Как подключить приватный registry

Для использования образов из приватного registry необходимо настроить аутентификацию. Доступно три варианта:

  1. Через конфигурацию узлов (NCI) — рекомендуемый способ для кластера: один объект NodeConfigItem (NCI) с разделом Container Runtime задаёт реестры контейнеров (и при необходимости учётные данные) для выбранных узлов. Оператор shturval-node-config применяет настройки на узлы без ручного входа по SSH. Подробнее о NCI — Конфигурация узлов (NCI).
  2. Ручное изменение конфигурации ContainerD на каждом узле — подходит при разовой настройке или когда NCI недоступен.
  3. ImagePullSecrets в неймспейсе — удобно с точки зрения безопасности и для разграничения по неймспейсам.

Сравнение способов аутентификации

КритерийЧерез NCI (Конфигурация узлов)Ручная правка ContainerDImagePullSecrets
Кто настраиваетАдминистратор кластера (один NCI)Администратор (на каждом узле по SSH)Администратор неймспейса или кластера
Область действияВсе поды на выбранных узлах (по селектору NCI)Все поды на узлеТолько поды, использующие секрет
СложностьОдин NCI на все узлы, применение операторомПравка конфига и перезапуск containerd на каждом узлеСекрет в каждом неймспейсе
БезопасностьУчётные данные в NCI (в кластере)Учётные данные в открытом виде в конфиге на узлеСекрет хранится в Kubernetes (Secret)
ИзмененияПравка NCI, оператор обновит узлыПравка конфига и перезапуск на всех узлахОбновление Secret в нужных неймспейсах

Настройка через конфигурацию узлов (NCI)

Этот способ не требует входа на каждый узел: оператор конфигурации узлов (shturval-node-config) применит настройки Container Runtime к узлам по селектору из NCI.

  1. Откройте Администрирование → Конфигурация узлов → Добавить NCI (или импортируйте манифест через Импорт манифестов).
  2. Задайте название, приоритет и селектор узлов (например, kubernetes.io/os: linux для всех Linux-узлов или node-role.kubernetes.io/control-plane для Control Plane). Подробнее о селекторах — Конфигурация узлов (NCI).
  3. В списке разделов выберите Container Runtime.
  4. В блоке Конфигурация реестров контейнеров нажмите + и заполните окно Добавить конфигурацию реестров образов:
Скриншот: окно добавления конфигурации реестров образов

Добавить конфигурацию реестров образов

Если вы используете зеркалирование r.shturval.tech:

  • Исходный реестр — имя реестра, которое нужно зеркалировать, например, r.shturval.tech.
  • Адрес зеркала реестра — адрес корпоративного зеркала, откуда будут загружаться образы, например, mirror-registry.corp.domain.
  • Возможности репозитория — выберите resolve и pull.
  • при необходимости укажите Авторизация в зеркало в формате Basic и строки base64.
Пример подключения реестра образов с зеркалированием r.shturval.tech с помощью NCI
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: private-registry
spec:
  nodeconfigselector:
    kubernetes.io/os: linux
  priority: 100
  runtimecfg:
    registries:
    - capabilities:
      - resolve
      - pull
      license: Basic YWRtaW46c2VjcmV0MTIz
      host: https://my-registry.corp:443
      name: r.shturval.tech

Если вы используете ваш реестр образов, в который требуется basic-авторизация:

Пример подключения реестра образов с basic-авторизацией с помощью NCI
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: private-registry
spec:
  nodeconfigselector:
    kubernetes.io/os: linux
  priority: 100
  runtimecfg:
    registries:
    - capabilities:
      - resolve
      - pull
      license: Basic YWRtaW46c2VjcmV0MTIz
      name: myprivateregistry.domain.ltd

Если вы используете ваш реестр образов, в который требуется авторизация с именем и паролем:

  • Исходный реестр — имя реестра, например, myprivateregistry.domain.ltd.
  • Логин и Пароль — учётные данные приватного реестра.
  • при необходимости укажите зеркало и Авторизация в зеркало.
Пример подключения вашего реестра образов с помощью NCI
apiVersion: node.shturval.tech/v1beta2
kind: NodeConfigItem
metadata:
  name: private-registry
spec:
  nodeconfigselector:
    kubernetes.io/os: linux
  priority: 100
  runtimecfg:
    registries:
    - capabilities:
      - resolve
      - pull
      name: myprivateregistry.domain.ltd
    configSections:
      - exist: true
        path: plugins."io.containerd.grpc.v1.cri".registry.configs."myprivateregistry.domain.ltd".auth
        params:
          - exist: true
            key: username
            value: myLogin
          - exist: true
            key: password
            value: myPassword

Если вы используете ваш реестр образов, в который авторизация не требуется, достаточно указать его хост в манифесте нагрузки, добавление в NCI не требуется.

  1. Нажмите Добавить, заполните остальные шаги и Завершить.

NCI будет применён к выбранным узлам оператором. Перезапуск containerd на узлах выполняется автоматически при применении конфигурации.

Учётные данные (логин/пароль) при необходимости задаются в форме NCI в блоке Container Runtime — поле «Авторизация в зеркало». Для применения этого NCI создайте объект через интерфейс Конфигурация узлов или добавьте в манифест соответствующие поля по документации API NodeConfigItem.

После создания или изменения NCI проверьте применение на узлах: Узлы → выберите узел → вкладка Конфигурация узла (список применённых NCI и статус).

Настройка через конфигурацию ContainerD вручную

На каждом узле кластера нужно отредактировать конфиг ContainerD (обычно путь /etc/containerd/config.toml).

  1. Найдите в файле секцию:
    [plugins."io.containerd.grpc.v1.cri".registry.configs]
    
  2. Добавьте под ней блок с адресом вашего registry и учётными данными:
Пример — иллюстрация
[plugins."io.containerd.grpc.v1.cri".registry.configs."myprivateregistry.domain.ltd".auth]
username = "myLogin"
password = "myPassword"
  1. Сохраните файл и перезапустите ContainerD на узле:
    sudo systemctl restart containerd
    

При обновлении или смене registry потребуется снова отредактировать конфиг и перезапустить ContainerD на всех узлах.

Настройка через ImagePullSecrets

Создайте в нужном неймспейсе Secret типа kubernetes.io/dockerconfigjson с данными для входа в registry. Затем укажите этот секрет в подах (или в defaultServiceAccount неймспейса) как imagePullSecrets.

1. Подготовка данных для аутентификации

Создайте JSON-файл с полем auths, в котором указаны адрес registry и учётные данные. Поле auth — строка base64 от username:password.

Пример JSON
{
  "auths": {
    "my-registry.example:5000": {
      "username": "tiger",
      "password": "pass1234",
      "email": "tiger@acme.example",
      "auth": "dGlnZXI6cGFzczEyMzQ="
    }

2. Создание Secret в кластере

Через веб-интерфейс: выберите кластер → нужный неймспейс → Хранилище → Secrets → создайте Secret с типом dockerconfigjson. В блоке Ключи добавьте ключ (например, .dockerconfigjson) и загрузите или вставьте содержимое JSON-файла с данными аутентификации.

Через kubectl:

Команда — иллюстрация
kubectl create secret docker-registry <имя-секрета> \
  --docker-server=my-registry.example:5000 \
  --docker-username=Username \
  --docker-password=Pass1234 \
  --docker-email=user@example.com \
  -n <имя-неймспейса>

Подставьте свои значения вместо <имя-секрета>, <имя-неймспейса> и учётных данных registry.

Эквивалентный Secret можно описать манифестом:

Пример Secret
apiVersion: v1
kind: Secret
metadata:
  name: external-registry-secret
  namespace: my-namespace
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: <base64-encoded-docker-config>

3. Использование секрета в нагрузках

При создании нагрузки (Deployment, Pod и т.п.) в поле Секреты образов (ImagePullSecrets) укажите созданный секрет. Тогда все поды этой нагрузки будут использовать его для pull образов из приватного registry.

В манифесте Pod или контроллера укажите секрет в поле imagePullSecrets:

Пример фрагмента манифеста
spec:
  imagePullSecrets:
  - name: regcred
  containers:
  - name: app
    image: registry.example.shturval.link/my-app:v1.0.0

Чтобы образы из этого registry тянулись по умолчанию во всём неймспейсе, добавьте imagePullSecrets в ServiceAccount по умолчанию этого неймспейса.

Пример ServiceAccount
apiVersion: v1
kind: ServiceAccount
metadata:
  name: default
  namespace: my-namespace
imagePullSecrets:
- name: regcred

Обратите внимание! секрет действует только в том неймспейсе, где создан. Для использования того же registry в другом неймспейсе создайте там отдельный Secret (или настройте кластерный механизм распространения секретов, если он у вас есть).

Если под переходит в ImagePullBackOff или ErrImagePull, проверьте имя образа и тег, доступность registry из кластера, права на образ и корректность imagePullSecrets. Подробные действия см. в разделе Траблшутинг нагрузок.

Аутентификация при push образов из CI/CD

Для публикации образов из pipeline выполните вход в registry учётной записью CI/CD и отправьте образ в нужный репозиторий.

Для ручной публикации образов выполните вход в registry перед docker push:

docker login registry.example.shturval.link -u <username> -p <password>

Пример GitLab CI

build_and_push:
  stage: build
  script:
    - docker login $REGISTRY_URL -u $REGISTRY_USER -p $REGISTRY_PASSWORD
    - docker build -t $REGISTRY_URL/my-app:$CI_COMMIT_SHA .
    - docker push $REGISTRY_URL/my-app:$CI_COMMIT_SHA
  variables:
    REGISTRY_URL: "registry.example.shturval.link"
    REGISTRY_USER: "ci-user"
    REGISTRY_PASSWORD: "${CI_REGISTRY_PASSWORD}"

Пример GitHub Actions

- name: Build and push
  uses: docker/build-push-action@v2
  with:
    push: true
    tags: registry.example.shturval.link/my-app:${{ github.sha }}
    registry: registry.example.shturval.link
    username: ${{ secrets.REGISTRY_USERNAME }}
    password: ${{ secrets.REGISTRY_PASSWORD }}