Знакомство с Kubernetes. Часть 7: Образы (Images)
Jun 11, 2018 07:05 · 743 words · 4 minute read
Перед тем, как описывать в манифесте какого-либо объекта 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