K8s Q A Images: различия между версиями
Sirmax (обсуждение | вклад) (Новая страница: «Категория:K8s Категория:K8s_Вопросы_И_Ответы =Images=») |
Sirmax (обсуждение | вклад) (→Images) |
||
Строка 3: | Строка 3: | ||
=Images= |
=Images= |
||
+ | Перед тем, как описывать в манифесте какого-либо объекта Kubernetes образ контейнера, его необходимо создать и разместить в реестре образов. Давайте разберемся! |
||
+ | |||
+ | Примечание. В данной статье будем говорить прежде всего о docker-образах и docker-registry. |
||
+ | |||
+ | Поле image в описании контейнера поддерживает тот же синтаксис, что и команда docker, включая частные реестры (private registries) и тэги. |
||
+ | |||
+ | По умолчанию для скачивания docker-образов установлена политика IfNotPresent, которая заставляет Kubelet пропускать скачивание образа, если он уже существует локально. Если необходимо всегда скачивать docker-образы перед запуском контейнеров, изменить данную политику можно следующими вариантами: |
||
+ | |||
+ | установить для поля imagePullPolicy контейнера значение Always; |
||
+ | использовать тэг :latest при описании образа; |
||
+ | включить контроллер AlwaysPullImages. |
||
+ | Если не задать в явном виде тэг docker-образа, то он будет автоматически установлен в :latest, а политика скачивания образа будет иметь вид imagePullPolicy=Always. |
||
+ | |||
+ | Примечание. Следует избегать использования тэга :latest - подробнее здесь. |
||
+ | |||
+ | При использовании частных реестров образов (private registries) могут потребоваться учетные данные для скачивания образов. Такие данные (ключи) можно предоставлять несколькими способами, в зависимости от типа реестра: |
||
+ | |||
+ | средствами GCR (Google Container Registry); |
||
+ | средствами AWS EC2 Container Registry (ECR); |
||
+ | средствами ACR (Azure Container Registry); |
||
+ | настраивая узлы кластера для аутентификации в частных реестрах; |
||
+ | скачивая образы до запуска подов; |
||
+ | указывая ImagePullSecrets в описании пода. |
||
+ | Рассмотрим каждый вариант более детально. |
||
+ | |||
+ | 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 имеет встроенную поддержку реестра контейнеров 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 |
||
+ | 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 в описании пода С помощью следующей команды (с заменой соответствующих значений на ваши) генерируем секретную переменную (создание секретов рассмотрим в одной из следующих статей): |
||
+ | |||
+ | 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: |
||
+ | |||
+ | <PRE> |
||
+ | apiVersion: v1 |
||
+ | kind: Pod |
||
+ | metadata: |
||
+ | name: foo |
||
+ | namespace: awesomeapps |
||
+ | spec: |
||
+ | containers: |
||
+ | - name: foo |
||
+ | image: janedoe/awesomeapp:v1 |
||
+ | imagePullSecrets: |
||
+ | - name: myregistrykey |
||
+ | </PRE> |
Версия 15:27, 8 января 2024
Images
Перед тем, как описывать в манифесте какого-либо объекта Kubernetes образ контейнера, его необходимо создать и разместить в реестре образов. Давайте разберемся!
Примечание. В данной статье будем говорить прежде всего о docker-образах и docker-registry.
Поле image в описании контейнера поддерживает тот же синтаксис, что и команда docker, включая частные реестры (private registries) и тэги.
По умолчанию для скачивания docker-образов установлена политика IfNotPresent, которая заставляет Kubelet пропускать скачивание образа, если он уже существует локально. Если необходимо всегда скачивать docker-образы перед запуском контейнеров, изменить данную политику можно следующими вариантами:
установить для поля imagePullPolicy контейнера значение Always; использовать тэг :latest при описании образа; включить контроллер AlwaysPullImages. Если не задать в явном виде тэг docker-образа, то он будет автоматически установлен в :latest, а политика скачивания образа будет иметь вид imagePullPolicy=Always.
Примечание. Следует избегать использования тэга :latest - подробнее здесь.
При использовании частных реестров образов (private registries) могут потребоваться учетные данные для скачивания образов. Такие данные (ключи) можно предоставлять несколькими способами, в зависимости от типа реестра:
средствами GCR (Google Container Registry); средствами AWS EC2 Container Registry (ECR); средствами ACR (Azure Container Registry); настраивая узлы кластера для аутентификации в частных реестрах; скачивая образы до запуска подов; указывая ImagePullSecrets в описании пода. Рассмотрим каждый вариант более детально.
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 имеет встроенную поддержку реестра контейнеров 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 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 в описании пода С помощью следующей команды (с заменой соответствующих значений на ваши) генерируем секретную переменную (создание секретов рассмотрим в одной из следующих статей):
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