Ответ
Система находит образ контейнера по его полному имени (FQDN), которое включает адрес реестра (registry), имя репозитория и тег или диджест. Механизм поиска зависит от контекста.
В Docker команда docker pull сначала проверяет локальный кеш. Если образа нет, Docker обращается к публичному Docker Hub (это registry по умолчанию) или к приватному registry, указанному в полном имени.
# Ищет в локальном кеше, затем качает с Docker Hub (registry-1.docker.io)
docker pull nginx:alpine
# Ищет и качает из приватного реестра GitLab
docker pull registry.gitlab.com/mygroup/myapp:latest
В Kubernetes путь к образу указывается в манифесте Pod или Deployment в поле spec.containers[].image. Kubelet на узле, используя Container Runtime Interface (CRI), выполняет аналогичную логику: проверяет локальный кеш и при необходимости обращается к удаленному registry.
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: nginx:1.25 # Скачается с Docker Hub
# image: myprivateregistry.local:5000/app:v2 # Скачается с кастомного registry
Ключевые нюансы:
- Аутентификация: Для приватных registry необходимо настроить секреты. В Kubernetes это
imagePullSecrets, в Docker — логин черезdocker login. - Теги vs Диджесты: Тег (
:latest) — это изменяемая метка. Диджест (nginx@sha256:a1b2c3...) — это криптографический хэш конкретного слоя образа, гарантирующий неизменность. - Локальные образы: Можно загрузить образ из tar-архива (
docker load -i image.tar) или собрать локально (docker build). В этом случае registry не используется.
Ответ 18+ 🔞
А, ну это же про то, как вся эта ваша оркестрация ищет картинки, чтобы запустить! Ёпта, история знакомая, как свои пять пальцев.
Смотри, тут всё просто, как три копейки. У каждого контейнера есть полное имя, этакая визитка — адрес реестра, имя проекта и версия (тег или диджест). И система, будь то тупой Docker или навороченный K8s, по этой визитке ищет, где скачать эту хрень.
Вот смотри на Docker. Ты пишешь docker pull nginx. А он что делает? Первым делом лезет в свой локальный кеш, как хомяк в кладовку: «А нет ли у меня уже такого nginx'а?». Если нет — тогда уже начинает дергать удаленный реестр. По умолчанию это Docker Hub, но если ты указал свой — пойдет туда.
# Полезет в кеш, потом потащит с дефолтного Docker Hub'а
docker pull nginx:alpine
# А тут уже полезет в твой кастомный реестр, например, на GitLab
docker pull registry.gitlab.com/mygroup/myapp:latest
А в Kubernetes — та же песня, только в профиль. Ты в манифесте для пода в поле image прописываешь этот самый адрес. А потом kubelet на рабочей ноде, через свой CRI (это такой универсальный адаптер для рантаймов), делает ровно то же самое: проверяет локально, нет ли? Нет? Ну тогда пошел скачивать с того реестра, который ты написал.
apiVersion: v1
kind: Pod
metadata:
name: myapp
spec:
containers:
- name: app
image: nginx:1.25 # Потянет с Docker Hub
# image: myprivateregistry.local:5000/app:v2 # Полезет на твой внутренний реестр
Но тут, бля, есть нюансы, на которых все обжигаются! Запоминай, ёперный театр:
- Доступ к приватному реестру. Это не просто так, «ой, дай-ка я скачаю». Для приватных штук нужны ключи! В Docker — это
docker login, а в K8s — специальные секреты типаimagePullSecrets. Без них тебе просто покажут фигу, доверия ебать ноль. - Теги против диджестов. Вот это важно! Тег (
:latest) — это просто бумажка на коробке, которую можно переклеить. Сегодня:latest— это одна версия, завтра — другая. А диджест (nginx@sha256:a1b2c3...) — это как отпечаток пальца, криптографическая подпись конкретного билда. Гарантия, что скачаешь именно то, что было. Хуй с горы его не изменит. - Локальные образы. А бывает и так, что registry вообще не нужен. Собрал образ сам (
docker build) или загрузил из архива (docker load -i image.tar) — и всё, он уже у тебя на машине. Система его найдет и запустит, не дергая никакую сеть.