Использование OCI Connector для развертывания рабочих нагрузок без секретов

В кластере Kubernetes для загрузки образов из приватных реестров обычно требуется распространять учетные данные реестра по пространствам имен, что увеличивает риск утечки этих данных.

OCI Connector предоставляет безсекретное решение, выступая в роли прокси для реестра. Это позволяет пользователям получать доступ к приватным реестрам без хранения долгосрочных паролей или токенов робота в каждом пространстве имен, тем самым максимально повышая безопасность учетных данных.

В этом руководстве показано, как использовать OCI Connector для развертывания рабочих нагрузок, которым необходимо загружать образы из приватных OCI реестров. OCI Connector функционирует как обратный прокси между вашим Kubernetes кластером и OCI реестром, обрабатывая аутентификацию и получение образов.

Содержание

Обзор возможностей

При развертывании рабочих нагрузок с OCI Connector учитывайте следующие ключевые моменты:

  • Чтобы включить загрузку образов через прокси OCI Connector в Kubernetes runtime, необходимо настроить ConnectorOCI так, чтобы его сервис был доступен через NodePort или Ingress. Подробные инструкции по установке см. в Installation Guide.
  • Адрес образа, указанный в вашей рабочей нагрузке, будет автоматически переписан на адрес прокси OCI Connector. Поскольку прокси использует HTTP, необходимо настроить runtime на разрешение небезопасных реестров.
  • OCI Connector выступает в роли обратного прокси для OCI реестра, обрабатывая аутентификацию и загрузку образов от имени ваших рабочих нагрузок.
  • Прокси OCI Connector аутентифицирует клиентов с помощью токенов их ServiceAccount, гарантируя, что только авторизованные рабочие нагрузки могут получить доступ к указанному коннектору.

Требования

  • ConnectorsCore установлен и запущен в кластере: Убедитесь, что ConnectorsCore развернут в вашем кластере.
  • ConnectorOCI установлен и доступен извне (NodePort или Ingress): Разверните ConnectorOCI и обеспечьте его внешний доступ. Подробности см. в Installation Guide.
  • Доступ к приватному OCI реестру: У вас должны быть действительные учетные данные и доступ к целевому реестру.
  • Настроенный kubectl: Убедитесь, что kubectl установлен и настроен для доступа к вашему кластеру.

С помощью OCI Connector вы можете безопасно загружать образы из приватных реестров в вашем Kubernetes кластере без хранения учетных данных на стороне клиента. Такой подход обеспечивает централизованное управление чувствительными данными и исключает их раскрытие отдельным рабочим нагрузкам или пользователям.

OCI Connector обеспечивает беспрепятственную загрузку образов для подов без необходимости передачи учетных данных, проксируя аутентификацию и запросы образов через безопасный централизованный сервис.

Обзор процесса

Процесс включает несколько ключевых шагов:

  1. Создание ресурса Connector, определяющего подключение к вашему OCI реестру.
  2. Настройка секретов для аутентификации.
  3. Создание токена ServiceAccount для внутренней аутентификации.
  4. Конфигурация секретов для загрузки образов.
  5. Развертывание рабочей нагрузки с соответствующими аннотациями.

Пошаговые действия

Шаг 1: Создание Connector

Сначала создайте пространство имен для демонстрации:

kubectl create namespace oci-connector-demo

Далее создайте ресурс Connector, который определит подключение к вашему OCI реестру. Этот ресурс будет управлять аутентификацией и операциями проксирования.

kubectl apply -n oci-connector-demo -f - <<'EOF'
apiVersion: connectors.alauda.io/v1alpha1
kind: Connector
metadata:
  name: harbor
spec:
  address: https://harbor.example.com # Замените на адрес вашего OCI реестра
  auth:
    name: tokenAuth
    secretRef:
      name: harbor-secret
  connectorClassName: oci
---
apiVersion: v1
stringData: # Замените на актуальную информацию для аутентификации
  password: robotsecret
  username: robot$demo
kind: Secret
metadata:
  name: harbor-secret
type: cpaas.io/distribution-registry-token
EOF

Рекомендация: Используйте robot account для доступа к реестру вместо admin аккаунта, если ваш OCI реестр это поддерживает.

Пояснение:

  • Ресурс Connector задает параметры подключения, включая адрес реестра и метод аутентификации.
  • Ресурс Secret безопасно хранит учетные данные реестра.
  • connectorClassName: oci указывает, что это коннектор типа OCI.
  • Метод аутентификации tokenAuth используется для аутентификации на основе токена.

Теперь мы создали коннектор в пространстве имен oci-connector-demo, и статус коннектора — Ready.

$ kubectl get connector.connectors -n oci-connector-demo
NAME     CLASS   ADDRESS                      READY   REASON   AGE
harbor   oci     https://harbor.example.com   True             30s

Шаг 2: Создание токена ServiceAccount

Сгенерируйте токен для ServiceAccount по умолчанию в вашем пространстве имен:

$ kubectl create token default -n oci-connector-demo
eyJhbGciOiJSUzI1NiIsImtpZCI6xxxximJ0VNVV_GblYvYy3dg...

Этот токен будет использоваться для загрузки образов через прокси коннектора. Любой ServiceAccount с правами доступа к коннектору может использоваться как pull secret для пода. Подробнее о правах доступа к ресурсу Connector см. в Connector Scope Permissions.

Пояснение:

  • Этот токен используется для аутентификации запросов к прокси коннектора.
  • Токен ограничен конкретным пространством имен (oci-connector-demo).
  • Храните этот токен в безопасности, он понадобится на следующем шаге.

Примечание: Токены ServiceAccount имеют время жизни (по умолчанию: 1 час). Вы можете использовать флаг --duration для продления срока действия. Подробнее см. в документации Kubernetes.

Шаг 3: Создание секрета для загрузки образов

Создайте секрет Docker registry, используя токен ServiceAccount:

kubectl create secret docker-registry oci-connector-secret \
  --docker-server="192.168.x.x:31567" \
  --docker-username="u" \
  --docker-password="eyJhbGciOiJSUzI1NiIsImtpZCI6xxxximJ0VNVV_GblYvYy3dg" \
  --docker-email=xxx@xxxx \
  --namespace=oci-connector-demo

Пояснение:

Адрес docker-server указывает на сервис прокси коннектора в кластере, его можно получить из статуса коннектора:

$ kubectl get connectors.connector harbor -n oci-connector-demo -o jsonpath='{.status.proxy.httpAddress.url}'
http://192.168.x.x:31567/namespaces/oci-connector-demo/connectors/harbor
  • docker-username установлен в "u" (заглушка для имени пользователя).
  • docker-password использует токен ServiceAccount с предыдущего шага.
  • docker-email может быть любым валидным email (требование совместимости с Docker registry).

Шаг 4: Добавление секрета загрузки образов к ServiceAccount

Привяжите секрет загрузки образов к ServiceAccount, чтобы поды, использующие этот ServiceAccount, автоматически применяли секрет при загрузке образов.

kubectl patch serviceaccount default -n oci-connector-demo -p "{\"imagePullSecrets\": [{\"name\": \"oci-connector-secret\"}]}"

Пояснение:

  • Эта команда добавляет oci-connector-secret в список imagePullSecrets ServiceAccount по умолчанию.
  • Любой под, использующий этот ServiceAccount, автоматически применит этот секрет для загрузки образов.
  • Это избавляет от необходимости указывать секрет в каждом описании пода.

Таким образом, любой под с этим ServiceAccount будет автоматически использовать секрет для загрузки образов.

Шаг 5: Развертывание рабочей нагрузки

Создайте рабочую нагрузку (в данном примере Pod) с необходимыми аннотациями для использования OCI Connector.

kubectl apply -n oci-connector-demo -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: oci-connector-pod
  annotations:
    connectors.cpaas.io/connector: oci-connector-demo/harbor
  labels:
    connectors.cpaas.io/proxy-inject: "true"
spec:
  containers:
    - name: oci-connector-container
      image: harbor.example.com/oci-connector-demo:v1
  serviceAccountName: default
EOF
  • Аннотация connectors.cpaas.io/connector указывает, какой коннектор использовать (namespace/connector-name).
  • Метка connectors.cpaas.io/proxy-inject: "true" включает инъекцию прокси для этого пода.
  • Поле image должно содержать исходный адрес вашего образа.
  • serviceAccountName: default гарантирует, что под использует ServiceAccount с секретом для загрузки образов.

Шаг 6: Проверка статуса пода

После создания пода можно проверить, что адрес образа в поде переписан на адрес прокси коннектора:

$ kubectl get pod oci-connector-pod -n oci-connector-demo -o jsonpath='{.spec.containers[0].image}'
# Пример вывода:
# 192.168.x.x:31567/namespaces/oci-connector-demo/connectors/harbor/oci-connector-demo:v1

Затем убедитесь, что под запущен и успешно загрузил образ через прокси коннектора:

kubectl get pod oci-connector-pod -n oci-connector-demo

Ожидаемый вывод:

NAME                  READY   STATUS    RESTARTS   AGE
oci-connector-pod     1/1     Running   0          2m

Устранение неполадок

Распространенные проблемы

  1. Под зависает в состоянии ImagePullBackOff:

    • Убедитесь, что коннектор корректно настроен и запущен.
    • Проверьте, что токен ServiceAccount действителен и не истек.
    • Убедитесь, что секрет загрузки образов правильно привязан к ServiceAccount.
  2. Ошибки аутентификации:

    • Проверьте учетные данные реестра в harbor-secret.
    • Убедитесь, что адрес коннектора доступен.
    • Проверьте, что параметр репозитория соответствует вашему реальному репозиторию.
  3. Инъекция прокси не работает:

    • Убедитесь, что присутствует метка connectors.cpaas.io/proxy-inject: "true".
    • Проверьте правильность формата аннотации коннектора.
    • Убедитесь, что коннектор существует в указанном пространстве имен.

Команды для проверки

# Проверка статуса коннектора
kubectl get connector.connectors harbor -n oci-connector-demo

# Проверка наличия секрета
kubectl get secret oci-connector-secret -n oci-connector-demo

# Проверка конфигурации ServiceAccount
kubectl get serviceaccount default -n oci-connector-demo -o yaml

# Просмотр событий пода для диагностики
kubectl describe pod oci-connector-pod -n oci-connector-demo

Заключение

Вы успешно прошли процесс использования OCI Connector для развертывания рабочих нагрузок без секретов. Такой подход повышает безопасность за счет централизованного управления учетными данными и исключает необходимость распространять чувствительную информацию по отдельным рабочим нагрузкам.