Образ контейнера
Образ контейнера представляє бінарні дані, які інкапсулюють застосунок та всі його програмні залежності. Образи контейнерів — це виконувані пакунки програмного забезпечення, які можуть працювати окремо і роблять дуже чітко визначені припущення щодо свого середовища виконання.
Зазвичай ви створюєте образ контейнера свого застосунку та розміщуєте його в реєстрі перш ніж посилатися на нього у Pod.
Ця сторінка надає огляд концепції образів контейнерів.
Примітка:
Якщо ви шукаєте образи контейнерів для випуску Kubernetes (наприклад, v1.32, остання мінорна версія), відвідайте розділ Завантаження Kubernetes.Назви образів
Образам контейнерів зазвичай дається назва, така як pause
, example/mycontainer
або kube-apiserver
. Образ також може містити імʼя хосту реєстру; наприклад: fictional.registry.example/imagename
, а також, можливо, номер порту; наприклад: fictional.registry.example:10443/imagename
.
Якщо ви не вказуєте імʼя хосту реєстру, Kubernetes вважає, що ви маєте на увазі публічний реєстр образів Docker. Ви можете змінити цю поведінку, вказавши стандартний реєстр образів у налаштуваннях середовища виконання контейнерів.
Після частини назви образу ви можете додати теґ або даджест (так само, якщо ви використовуєте команди типу docker
чи podman
). Теґи дозволяють ідентифікувати різні версії одного ряду образів. Даджест — унікальний ідентифікатор конкретної версії образу. Даджести є хешами, які визначаються вмістом образу, і вони не змінюються. Теґи можна змініювати, так щоб вони вказували на різні версії образу, даджйести залишаються незмінними.
Теґи образів складаються з малих і великих літер, цифр, підкреслень (_
), крапок (.
) та тире (-
). Довжина теґу може бути до 128 символів. Теґ має відповідати наступному шаблону: [a-zA-Z0-9_][a-zA-Z0-9._-]{0,127}
. Дізнатись більше та знайти інші регулярні вирази для перевірки можна в OCI Distribution Specification. Якщо ви не вказуєте теґ, Kubernetes вважає, що ви маєте на увазі теґ latest
.
Хеш-сума образу складається з назви алгоритму хешу (наприклад, sha256
) і значення хешу. Наприклад: sha256:1ff6c18fbef2045af6b9c16bf034cc421a29027b800e4f9b68ae9b1cb3e9ae07
Додаткову інформацію про формат хешів можна знайти в OCI Image Specification.
Деякі приклади імен образів, які може використовувати Kubernetes:
busybox
— Тільки назва образу, без теґу або хеша. Kubernetes використовує загальний реєстр Docker і теґ latest. (Те саме, що іdocker.io/library/busybox:latest
)busybox:1.32.0
— назва образу з теґом. Kubernetes використовує загальний реєстр Docker. (Те саме, що іdocker.io/library/busybox:1.32.0
)registry.k8s.io/pause:latest
— назва образу з власного реєстру і теґом latest.registry.k8s.io/pause:3.5
— назва образу з власного реєстру і теґом, який не є останнім.registry.k8s.io/pause@sha256:1ff6c18fbef2045af6b9c16bf034cc421a29027b800e4f9b68ae9b1cb3e9ae07
— назва образу з хешем.registry.k8s.io/pause:3.5@sha256:1ff6c18fbef2045af6b9c16bf034cc421a29027b800e4f9b68ae9b1cb3e9ae07
— назва образу з теґом і хешем. Тільки хеш буде використаний для завантаження.
Оновлення образів
При першому створенні Deployment, StatefulSet, Pod чи іншого обʼєкта, що включає шаблон Pod, стандартна політика завантаження всіх
контейнерів у цьому Pod буде встановлена в IfNotPresent
, якщо вона не вказана явно. Ця політика призводить до того, що kubelet пропускає завантаження образів, якщо вони вже існують.
Політика завантаження образів
imagePullPolicy
для контейнера та теґ образу впливають на те, коли kubelet намагається завантажити (стягнути) вказаний образ.
Ось список значень, які можна встановити для imagePullPolicy
та їхні ефекти:
IfNotPresent
- образ завантажується лише тоді, коли він ще не присутній локально.
Always
- кожен раз, коли kubelet запускає контейнер, kubelet зверетається до реєстру образів для пошуку відповідності між назвою та образом (digest). Якщо у kubelet є образ контейнера з цим точним хешем в кеші локально, kubelet використовує свій кеш образів; в іншому випадку kubelet завантажує образ зі знайденим хешем та використовує його для запуску контейнера.
Never
- kubelet не намагається отримати образ. Якщо образ вже присутній локально, kubelet намагається запустити контейнер; в іншому випадку запуск закінчується невдачею. Див. попередньо завантажені образи для отримання деталей.
Семантика кешування базового постачальника образів робить навіть imagePullPolicy: Always
ефективним, якщо реєстр доступний. Ваше середовище виконання контейнерів може помітити, що шари образів вже існують на вузлі, так що їх не потрібно знову завантажувати.
Примітка:
Ви повинні уникати використання теґу :latest
при розгортанні контейнерів в промисловому оточені, оскільки важко відстежити, яка версія образів запущена, і складніше виконати відкат.
Замість цього використовуйте інший значущий теґ, такий як v1.42.0
і/або хеш.
Щоб переконатися, що Pod завжди використовує ту саму версію образів контейнерів, ви можете вказати хеш образів; замініть <image-name>:<tag>
на <image-name>@<digest>
(наприклад, image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2
).
При використанні теґів образів, якщо реєстр образів змінив код, який представляє теґ вашого образу, ви могли б отримати суміш Podʼів, що запускають старий і новий код. Дайджест образу унікально ідентифікує конкретну версію образу, тому Kubernetes запускає один і той же код кожного разу, коли він запускає контейнер із вказаним імʼям образу та дайджестом. зазначення образу за допомогою дайджесту виправляє код, який ви запускаєте, так що зміна в реєстрі не може призвести до такого змішаного використання версій.
Є сторонні контролери допуску що змінюють Pod (і шаблони pod), коли вони створюються, так що робоче навантаження визначається на основі хешу образу, а не теґу. Це може бути корисно, якщо ви хочете переконатися, що всі ваші робочі навантаження запускають один і той самий код, незалежно від того, які зміни теґів відбуваються в реєстрі.
Стандартні політики завантаження образів
Коли ви (чи контролер) подаєте новий Pod серверу API, ваш кластер встановлює поле imagePullPolicy
при виконанні певних умов:
- якщо ви опускаєте поле
imagePullPolicy
та вказуєте хеш для образів контейнерів,imagePullPolicy
автоматично встановлюється вIfNotPresent
. - якщо ви опускаєте поле
imagePullPolicy
та теґ для образів контейнерів є:latest
,imagePullPolicy
автоматично встановлюється вAlways
; - якщо ви опускаєте поле
imagePullPolicy
та не вказуєте теґ для образів контейнерів,imagePullPolicy
автоматично встановлюється вAlways
; - якщо ви опускаєте поле
imagePullPolicy
та вказуєте теґ для образів контейнерів, який не є:latest
,imagePullPolicy
автоматично встановлюється вIfNotPresent
.
Примітка:
Значення imagePullPolicy
контейнера завжди встановлюється при першому створенні обʼєкта і не оновлюється, якщо теґ чи хеш образів пізніше зміниться.
Наприклад, якщо ви створите Deployment з образом, теґ якого не є :latest
, і пізніше оновите образ цього Deployment до теґу :latest
, поле imagePullPolicy
не зміниться на Always
. Вам слід вручну змінити політику завантаження для будь-якого обʼєкта після його початкового створення.
Обовʼязкове завантаження образів
Якщо ви хочете завжди виконувати завантаження, ви можете зробити одне з наступного:
- Встановіть
imagePullPolicy
контейнера вAlways
. - Опустіть
imagePullPolicy
і використовуйте:latest
як теґ для образів; Kubernetes встановить політику вAlways
при подачі Pod. - Опустіть
imagePullPolicy
та теґ для використання образів; Kubernetes встановить політику вAlways
при подачі Pod. - Увімкніть контролер допуску AlwaysPullImages.
ImagePullBackOff
Коли kubelet починає створювати контейнери для Pod за допомогою середовища виконання контейнерів, можливо, контейнер перебуває у стані Waiting з причини ImagePullBackOff
.
Статус ImagePullBackOff
означає, що контейнер не може запуститися через те, що Kubernetes не може завантажити образ контейнера (з причин, таких як невірне імʼя образу або спроба завантаження з приватного реєстру без imagePullSecret
). Частина BackOff
вказує на те, що Kubernetes буде продовжувати пробувати завантажити образ зі збільшенням інтервалів між спробами.
Kubernetes збільшує інтервал між кожною спробою до тих пір, поки не досягне вбудованого обмеження, яке становить 300 секунд (5 хвилин).
Завантаження образу відповідно до класу середовища виконання
Kubernetes v1.29 [alpha]
(стандартно увімкнено: false)Якщо ви увімкнете функціональну можливість RuntimeClassInImageCriApi
, kubelet вказує образи контейнерів кортежем (назва образу, обробник), а не лише назва чи хешем образу. Ваше середовище виконання контейнерів може адаптувати свою поведінку залежно від обраного обробника. Завантаження образів на основі класу середовища виконання буде корисним для контейнерів, що використовують віртуальні машини, таких як контейнери Windows Hyper-V.
Послідовне та паралельне завантаження образів
Типово kubelet завантажує образи послідовно. Іншими словами, kubelet надсилає лише один запит на завантаження образу до служби образів одночасно. Інші запити на завантаження образів мають чекати, поки завершиться обробка того, який знаходиться в процесі.
Вузли приймають рішення про завантаження образу незалежно один від одного. Навіть коли ви використовуєте послідовні запити на завантаження образів, два різні вузли можуть завантажувати один і той самий образ паралельно.
Якщо ви хочете увімкнути паралельне завантаження образів, ви можете встановити поле serializeImagePulls
у значення false у конфігурації kubelet. Зі значенням serializeImagePulls
встановленим у false, запити на завантаження образів будуть надсилатись до служби образів негайно, і кілька образів буде завантажено одночасно.
При увімкненні паралельного завантаження образів, будь ласка, переконайтеся, що служба образів вашого середовища виконання контейнерів може обробляти паралельне завантаження образів.
Kubelet ніколи не завантажує кілька образів паралельно від імені одного Pod. Наприклад, якщо у вас є Pod із контейнером ініціалізації та контейнером застосунку, завантаження образів для цих двох контейнерів не буде виконуватись паралельно. Однак якщо у вас є два Podʼи, які використовують різні образи, kubelet завантажує образи паралельно для цих двох різних Podʼів, коли увімкнено паралельне завантаження образів.
Максимальна кількість паралельних завантажень образів
Kubernetes v1.32 [beta]
Коли serializeImagePulls
встановлено в значення false, kubelet стандартно не обмежує максимальну кількість образів, які завантажуються одночасно. Якщо ви хочете обмежити кількість паралельних завантажень образів, ви можете встановити поле maxParallelImagePulls
у конфігурації kubelet. Зі значенням maxParallelImagePulls
в n, тільки n образів можуть завантажуватися одночасно, і будь-яке завантаження образу за межами n буде чекати, поки завершиться принаймні одне завантаження образу, яке вже триває.
Обмеження кількості паралельних завантажень образів допоможе уникнути зайвого використання пропускної здатності мережі або дискових операцій вводу/виводу, коли увімкнено паралельне завантаження образів.
Ви можете встановити maxParallelImagePulls
на позитивне число, яке більше або рівне 1. Якщо ви встановите maxParallelImagePulls
більше або рівне 2, ви повинні встановити serializeImagePulls
в значення false. Kubelet не буде запущено з недійсними налаштуваннями maxParallelImagePulls
.
Мультиархітектурні образи з індексами образів
Окрім надання бінарних образів, реєстр контейнерів також може обслуговувати індекс образу контейнера. Індекс образу може посилатися на кілька маніфестів образу для версій контейнера, специфічних для архітектури. Ідея полягає в тому, що ви можете мати імʼя для образу (наприклад: pause
, example/mycontainer
, kube-apiserver
) та дозволити різним системам отримувати правильний бінарний образ для використання на їхній архітектурі машини.
Сам Kubernetes зазвичай називає образи контейнерів із суфіксом -$(ARCH)
. З метою забезпечення сумісності з попередніми версіями, будь ласка, генеруйте старіші образи із суфіксами. Ідея полягає в тому, щоб створити, наприклад, образ pause
, який має маніфест для всіх архітектур, та скажімо pause-amd64
, який є сумісним з попередніми конфігураціями або файлами YAML, які можуть містити жорстко закодовані образи із суфіксами.
Використання приватних реєстрів
Приватні реєстри можуть вимагати ключі для читання образів з них. Облікові дані можна надати кількома способами:
- Налаштування вузлів для автентифікації в приватному реєстрі
- всі Podʼи можуть читати будь-які налаштовані приватні реєстри
- вимагає конфігурації вузла адміністратором кластера
- Постачальник облікових даних Kubelet для динамічного отримання облікових даних для приватних реєстрів
- kubelet може бути налаштований для використання втулка від постачальника облікових даних для відповідного приватного реєстру.
- Попередньо завантажені образи
- всі Podʼи можуть використовувати будь-які образи, кешовані на вузлі
- вимагає доступу до кореня на всіх вузлах для налаштування
- Вказання ImagePullSecrets на Pod
- лише Podʼи, які надають свої власні ключі, можуть отримувати доступ до приватного реєстру
- Постачальник специфічний для вендора або локальні розширення
- якщо ви використовуєте власну конфігурацію вузла, ви (або ваш постачальник хмари) можете реалізувати власний механізм автентифікації вузла в реєстрі контейнерів.
Ці варіанти пояснюються докладніше нижче.
Налаштування вузлів для автентифікації в приватному реєстрі
Конкретні інструкції щодо встановлення облікових даних залежать від середовища виконання контейнерів та реєстру, який ви вибрали для використання. Вам слід звертатися до документації щодо вашого рішення для отримання найточнішої інформації.
Для прикладу конфігурування приватного реєстру образів контейнерів дивіться завдання Завантаження образу з приватного реєстру. У цьому прикладі використовується приватний реєстр в Docker Hub.
Постачальник облікових даних Kubelet для витягування автентифікованих образів
Примітка:
Цей підхід добре підходить, коли kubelet повинен динамічно отримувати облікові дані реєстру. Зазвичай використовується для реєстрів, наданих хмарними провайдерами, де токени автентифікації мають обмежений термін дії.Ви можете налаштувати kubelet для виклику бінарного втулка, щоб динамічно отримувати облікові дані реєстру для образу контейнера. Це найнадійніший та універсальний спосіб отримання облікових даних для приватних реєстрів, але також вимагає конфігурації kubelet для його увімкнення.
Докладніше дивіться Налаштування постачальника облікових даних образу kubelet.
Тлумачення файлу config.json
Тлумачення config.json
відрізняється між оригінальною реалізацією Docker та тлумаченням Kubernetes. У Docker ключі auths
можуть вказувати тільки кореневі URL-адреси, тоді як Kubernetes дозволяє використовувати глобальні URL-адреси, а також шляхи, які відповідають префіксу. Єдиним обмеженням є те, що глобальні шаблони (*
) повинні включати крапку (.
) для кожного піддомену. Кількість піддоменів, що мають збіг, повинна дорівнювати кількості глобальних шаблонів (*.
), наприклад:
*.kubernetes.io
не збігатиметься зkubernetes.io
, але збігатиметься зabc.kubernetes.io
*.*.kubernetes.io
не збігатиметься зabc.kubernetes.io
, але збігатиметься зabc.def.kubernetes.io
prefix.*.io
збігатиметься зprefix.kubernetes.io
*-good.kubernetes.io
збігатиметься зprefix-good.kubernetes.io
Це означає, що файл config.json
, подібний до цього, є дійсним:
{
"auths": {
"my-registry.io/images": { "auth": "…" },
"*.my-registry.io/images": { "auth": "…" }
}
}
Операції отримання образів тепер будуть передавати облікові дані CRI контейнеру для кожного дійсного шаблону. Наприклад, образи контейнера, вказані нижче, успішно збігатимуться:
my-registry.io/images
my-registry.io/images/my-image
my-registry.io/images/another-image
sub.my-registry.io/images/my-image
Але не:
a.sub.my-registry.io/images/my-image
a.b.sub.my-registry.io/images/my-image
Kubelet виконує операції отримання образів послідовно для кожного знайденого облікового запису. Це означає, що можливі кілька записів у config.json
для різних шляхів:
{
"auths": {
"my-registry.io/images": {
"auth": "…"
},
"my-registry.io/images/subpath": {
"auth": "…"
}
}
}
Тепер, якщо контейнер вказує образ my-registry.io/images/subpath/my-image
,
то kubelet спробує завантажити його з обох джерел автентифікації, якщо завантеження з одного з них виявиться невдалим.
Попередньо завантажені образи
Примітка:
Цей підхід підходить, якщо ви можете контролювати конфігурацію вузла. Він не буде надійно працювати, якщо ваш постачальник хмари управляє вузлами та автоматично їх замінює.Типово kubelet намагається отримати кожен образ з вказаного реєстру. Однак якщо властивість imagePullPolicy
контейнера встановлена на IfNotPresent
або Never
,
то використовується локальний образ (переважно або виключно, відповідно).
Якщо ви хочете покладатися на попередньо завантажені образи як заміну автентифікації в реєстрі, вам слід переконатися, що всі вузли кластера мають однакові попередньо завантажені образи.
Це може бути використано для попереднього завантаження певних образів для швидкості або як альтернатива автентифікації в приватному реєстрі.
Всі Podʼи матимуть доступ на читання до будь-яких попередньо завантажених образів.
Вказання ImagePullSecrets для Pod
Примітка:
Це рекомендований підхід для запуску контейнерів на основі образів з приватних реєстрів.Kubernetes підтримує вказання ключів реєстру образів контейнерів для Pod. imagePullSecrets
повинні бути всі в тому ж просторі імен, що й Pod. Зазначені Secrets повинні бути типу kubernetes.io/dockercfg
або kubernetes.io/dockerconfigjson
.
Створення Secret з Docker-конфігом
Вам потрібно знати імʼя користувача, пароль реєстру та адресу електронної пошти клієнта для автентифікації в реєстрі, а також його імʼя хосту. Виконайте наступну команду, підставивши відповідні значення замість написів у верхньому регістрі:
kubectl create secret docker-registry <name> \
--docker-server=DOCKER_REGISTRY_SERVER \
--docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD \
--docker-email=DOCKER_EMAIL
Якщо у вас вже є файл облікових даних Docker, ніж використовувати вищезазначену команду, ви можете імпортувати файл облікових даних як Secrets Kubernetes. Створення Secret на основі наявних облікових даних Docker пояснює, як це зробити.
Це особливо корисно, якщо ви використовуєте кілька приватних реєстрів контейнерів, оскільки kubectl create secret docker-registry
створює Secret, який працює лише з одним приватним реєстром.
Примітка:
Podʼи можуть посилатися лише на ключі реєстру образів у своєму власному просторі імен, так що цей процес слід виконати один раз для кожного простору імен.Посилання на imagePullSecrets для Pod
Тепер ви можете створювати Podʼи, які посилаються на цей secret, додавши розділ imagePullSecrets
до визначення Pod. Кожен елемент у масиві imagePullSecrets
може посилатися тільки на Secret у тому ж просторі імен.
Наприклад:
cat <<EOF > pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: awesomeapps
spec:
containers:
- name: foo
image: janedoe/awesomeapp:v1
imagePullSecrets:
- name: myregistrykey
EOF
cat <<EOF >> ./kustomization.yaml
resources:
- pod.yaml
EOF
Це слід робити для кожного Podʼа, який використовує приватний реєстр.
Однак налаштування цього поля можна автоматизувати, встановивши imagePullSecrets в ресурс ServiceAccount.
Перевірте Додавання ImagePullSecrets до облікового запису служби для докладних інструкцій.
Ви можете використовувати це разом із .docker/config.json
на рівні вузла. Облікові дані обʼєднанні.
Сценарії використання
Існує кілька рішень для конфігурації приватних реєстрів. Ось деякі типові сценарії використання та рекомендовані рішення.
- Кластер, в якому використовуються лише непроприєтарні (наприклад, відкриті) образи. Немає потреби приховувати образи.
- Використовуйте відкриті образи з відкритого реєстру.
- Конфігурація не потрібна.
- Деякі постачальники хмари автоматично кешують або дзеркалюють відкриті образи, що підвищує доступність та скорочує час їх отримання.
- Використовуйте відкриті образи з відкритого реєстру.
- Кластер, в якому використовуються деякі проприєтарні образи, які повинні бути невидимими для інших компаній, але доступними для всіх користувачів кластера.
- Використовуйте приватний реєстр.
- Можлива ручна конфігурація на вузлах, які повинні мати доступ до приватного реєстру.
- Або запустіть внутрішній приватний реєстр за вашим фаєрволом з відкритим доступом на читання.
- Не потрібна конфігурація Kubernetes.
- Використовуйте сервіс реєстрації образів контейнерів, який контролює доступ до образів.
- Він працюватиме краще з автомасштабуванням кластера, ніж ручна конфігурація вузла.
- Або на кластері, де зміна конфігурації вузла незручна, використовуйте
imagePullSecrets
.
- Використовуйте приватний реєстр.
- Кластер із проприєтарними образами, кілька з яких вимагають строгого контролю доступу.
- Переконайтеся, що контролер доступу AlwaysPullImages активний. У противному випадку всі Podʼи потенційно мають доступ до всіх образів.
- Перемістіть конфіденційні дані в ресурс "Secret", а не додавайте їх в образ.
- Багатокористувацький кластер, де кожен орендар потребує власного приватного реєстру.
- Переконайтеся, що контролер доступу AlwaysPullImages активний. У противному випадку всі Podʼи всіх орендарів потенційно мають доступ до всіх образів.
- Запустіть приватний реєстр з обовʼязковою авторизацією.
- Створіть обліковий запис реєстру для кожного орендара, розмістіть його в Secret та внесіть Secret в кожний простір імен орендаря.
- Орендар додає цей Secret до imagePullSecrets кожного простору імен.
Якщо вам потрібен доступ до декількох реєстрів, ви можете створити Secret для кожного реєстру.
Застарілий вбудований постачальник облікових даних kubelet
У старших версіях Kubernetes kubelet мав пряму інтеграцію з обліковими даними хмарного постачальника. Це давало йому можливість динамічно отримувати облікові дані для реєстрів образів.
Існувало три вбудовані реалізації інтеграції облікових записів kubelet: ACR (Azure Container Registry), ECR (Elastic Container Registry) та GCR (Google Container Registry).
Докладніше про застарілий механізм можна прочитати в документації версії Kubernetes, яку ви використовуєте. У версіях Kubernetes від v1.26 до v1.32 він відсутній, тому вам потрібно або:
- налаштувати постачальника облікових записів kubelet на кожному вузлі
- вказати облікові дані для отримання образів, використовуючи
imagePullSecrets
та принаймні один Secret
Що далі
- Прочитайте Специфікацію маніфеста образу OCI.
- Дізнайтеся про збирання сміття образів контейнерів.
- Дізнайтеся більше про отримання образу з приватного реєстру.