K8s Q A Images

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску


Images

Перед тем, как описывать в манифесте какого-либо объекта Kubernetes образ контейнера, его необходимо создать и разместить в реестре образов.

Поле image в описании контейнера поддерживает тот же синтаксис, что и команда docker, включая частные реестры (private registries) и тэги.
По умолчанию для скачивания docker-образов установлена политика IfNotPresent, которая заставляет Kubelet пропускать скачивание образа, если он уже существует локально.
Если необходимо всегда скачивать docker-образы перед запуском контейнеров, изменить данную политику можно следующими вариантами:

  • установить для поля imagePullPolicy контейнера значение Always;
  • использовать тэг :latest при описании образа (????)
  • включить контроллер AlwaysPullImages. admission-controllers
AlwaysPullImages

Type: Mutating and Validating.

This admission controller modifies every new Pod to force the image pull policy to Always. This is useful in a multitenant cluster so that users can be assured that their private images can only be used by those who have the credentials to pull them. Without this admission controller, once an image has been pulled to a node, any pod from any user can use it by knowing the image's name (assuming the Pod is scheduled onto the right node), without any authorization check against the image. When this admission controller is enabled, images are always pulled prior to starting containers, which means valid credentials are required.

Если не задать в явном виде тэг docker-образа, то он будет автоматически установлен в :latest, а политика скачивания образа будет иметь вид imagePullPolicy=Always.
Примечание. Следует избегать использования тэга :latest
При использовании частных реестров образов (private registries) могут потребоваться учетные данные для скачивания образов. Такие данные (ключи) можно предоставлять несколькими способами, в зависимости от типа реестра:

  • средствами GCR (Google Container Registry)
  • средствами AWS EC2 Container Registry (ECR);
  • средствами ACR (Azure Container Registry);
  • настраивая узлы кластера для аутентификации в частных реестрах;
  • скачивая образы до запуска подов;
  • указывая ImagePullSecrets в описании пода.

Рассмотрим каждый вариант более детально.

GCR Kubernetes

GCR Kubernetes имеет встроенную поддержку Google Container Registry (GCR) при работе c GCE/GKE. Если используется кластер в Google Compute Engine или Google Kubernetes Engine, достаточно указать полное имя образа, например, gcr.io/my_project/image:tag.

Все поды кластера будут иметь доступ к данному реестру образов. Kubelet получит доступ к GCR с помощью служебной учетной записи (instance’s Google service account) с правами read_only.

ECR Kubernetes

ECR Kubernetes имеет встроенную поддержку реестра контейнеров AWS EC2, если узлы кластера являются экземплярами AWS EC2. В таком случае достаточно использовать полное имя образа - например, ACCOUNT.dkr.ecr.REGION.amazonaws.com/imagename:tag в описании пода. Все пользователи кластера с правами запуска подов получают также права на скачивание docker-образов из ECR.

Kubelet (начиная с версии v1.2.0) будет проверять и периодически обновлять учетные данные ECR. Для этого ему необходимы следующие разрешения:

ecr:GetAuthorizationToken
ecr:BatchCheckLayerAvailability
ecr:GetDownloadUrlForLayer
ecr:GetRepositoryPolicy
ecr:DescribeRepositories
ecr:ListImages
ecr:BatchGetImage

Azure Container Registry

ACR При работе с Azure Container Registry можно получить доступ к реестру образов либо с учетными данными администратора, либо с помощью стандартной аутентификации Docker. Второй вариант предполагает использование инструмента командной строки azure-cli. Создать реестр и сгенерировать учетные данные можно следуя документации, после чего можно использовать учетные данные для входа в систему:

DOCKER_USER: главный администратор или администратор службы DOCKER_PASSWORD: пароль главного администратора или администратора службы DOCKER_REGISTRY_SERVER: $ {some-registry-name} .azurecr.io DOCKER_EMAIL: $ {some-email-address}

Настройка узлов кластера для аутентификации в частных реестрах Docker хранит ключи для частных реестров образов в файле $HOME/.dockercfg или $HOME/.docker/config.json. Необходимо разместить этот файл в домашнем каталоге пользователя root на всех узлах кластера с запущенным kubelet. Для этого:

На рабочем компьютере нужно выполнить docker login [server] для всех наборов учетных записей / реестров, которые вы планируете использовать. Эти команды актуализируют конфигурационный файл $HOME/.docker/config.json. Проверьте данный файл ($HOME/.docker/config.json) в текстовом редакторе и убедитесь, что в нем есть все необходимые данные. Получите все имена или ip-адреса узлов кластера Kubernetes: nodes=$(kubectl get nodes -o jsonpath='{range.items[*].metadata}{.name} {end}') или

nodes=$(kubectl get nodes -o jsonpath='{range .items[*].status.addresses[?(@.type=="ExternalIP")]}{.address} {end}') Скопируйте конфигурационный файл $HOME/.docker/config.json на все узлы кластера, например так: for n in $nodes; do scp ~/.docker/config.json root@$n:/root/.docker/config.json; done Проверьте доступ в частному реестру - например, создайте манифест для пода, использующий образ из реестра. Скачивая образы до запуска подов Не самый оптимальный вариант, но все же - если вы хотите использовать локально размещенные docker-образы (например, если хотите сэкономить время на скачивании образов из реестра или нет учетных данных для доступа к реестру), то убедитесь, что эти образы есть на всех узлах кластера.

ImagePullSecrets

Указывая ImagePullSecrets в описании пода С помощью следующей команды (с заменой соответствующих значений на ваши) генерируем секретную переменную (Добавить ссылку на описание секретов!!!!)

kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL secret "myregistrykey" created.
Примечание. Если необходим доступ к нескольким частным реестрам образов, для каждого из них генерируем отдельный secret.

Альтернативный вариант описания секретной переменной - создаем манифест для объекта Secret следующего вида:

apiVersion: v1
kind: Secret
metadata:
  name: myregistrykey
  namespace: awesomeapps
data:
  .dockerconfigjson: ewogICJhdXRocyIgOiB7CiAgICAiaHR0cHM6Ly9yZWdpc3RyeS5naXRsYWIubGM6NTAwMCIgOiB7CgogICAgfSwKICAgICJyZWdpc3RyeS5naXRsYWIubGM6NTAwMCIgOiB7CgogICAgfQogIH0sCiAgIkh0dHBIZWFkZXJzIiA6IHsKICAgICJVc2VyLUFnZW50IiA6ICJEb2NrZXItQ2xpZW50LzE4LjAyLjAtY2UtcmMyIChkYXJ3aW4pIgogIH0sCiAgImV4cGVyaW1lbnRhbCIgOiAiZW5hYmxlZCIsCiAgImNyZWRzU3RvcmUiIDogIm9zeGtleWNoYWluIiwKICAib3JjaGVzdHJhdG9yIiA6ICJzd2FybSIKfQ==
type: kubernetes.io/dockerconfigjson

Убедитесь, что:

имя элемента данных в поле data установлено в .dockerconfigjson; значением для параметра .dockerconfigjson установлена строка, полученная как результат кодирования файла $HOME/.docker/config.json (см. выше) в base64; тип (type) объекта установлен в kubernetes.io/dockerconfigjson.
Команда для кодирования строки выглядит так: cat ~/.docker/config.json | base64.

Теперь, при описании манифеста для каждого пода, использующего частный реестр образов, не забудьте добавить поле imagePullSecrets:

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: myregistrykey