Образ контейнера представляє бінарні дані, які інкапсулюють застосунок та всі його програмні залежності. Образи контейнерів — це виконувані пакунки програмного забезпечення, які можуть працювати окремо і роблять дуже чітко визначені припущення щодо свого середовища виконання.
Зазвичай ви створюєте образ контейнера свого застосунку та розміщуєте його в реєстрі, перш ніж посилатися на нього у Podʼі.
Ця сторінка надає огляд концепції образів контейнерів.
Образам контейнерів зазвичай дається назва, така як 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 — назва образу із власним реєстром і теґом, відмінним від latest.registry.k8s.io/pause@sha256:1ff6c18fbef2045af6b9c16bf034cc421a29027b800e4f9b68ae9b1cb3e9ae07 — назва образу з дайджестом.registry.k8s.io/pause:3.5@sha256:1ff6c18fbef2045af6b9c16bf034cc421a29027b800e4f9b68ae9b1cb3e9ae07 — назва образу з теґом і дайджестом. Для завантаження використовується лише дайджест.При першому створенні Deployment, StatefulSet, Podʼа чи іншого обʼєкта, що включає PodTemplate, а політику завантаження явно не вказано, стандартна політика завантаження всіх контейнерів у цьому Podʼі буде встановлена в IfNotPresent. Ця політика призводить до того, що kubelet пропускає завантаження образів, якщо вони вже існують.
imagePullPolicy для контейнера та теґ образу впливають на те, коли kubelet намагається завантажити (отримати) вказаний образ.
Ось список значень, які можна встановити для imagePullPolicy та їхній вплив:
IfNotPresentAlwaysNeverСемантика кешування середовища виконання контейнерів робить ефективним навіть imagePullPolicy: Always, якщо реєстр доступний. Середовище виконання контейнерів може помітити, що шари образів вже існують на вузлі, так що їх не потрібно знову завантажувати.
Ви повинні уникати використання теґу :latest при розгортанні контейнерів в промисловому середовищі, оскільки так важче відстежити, яка версія образу запущена, і складніше виконати відкат.
Замість цього використовуйте значущий теґ, такий як v1.42.0, і/або дайджест.
Щоб переконатися, що Pod завжди використовує ту саму версію образу контейнера, ви можете вказати дайджест образу; замініть <image-name>:<tag> на <image-name>@<digest> (наприклад, image@sha256:45b23dee08af5e43a7fea6c4cf9c25ccf269ee113168c19722f87876677c5cb2).
При використанні теґів образів, якщо реєстр образів змінив код, який представляє теґ вашого образу, ви могли б отримати суміш Podʼів, що запускають старий і новий код. Дайджест образу унікально ідентифікує конкретну версію образу, тому Kubernetes запускає той самий код кожного разу, коли він запускає контейнер із вказаними назвою образу та дайджестом. Зазначення образу за допомогою дайджесту фіксує код, який ви запускаєте, так що зміна в реєстрі не може призвести до такого змішаного використання версій.
Є сторонні контролери допуску, що змінюють Podʼи (і PodTemplates) під час створення, так що робоче навантаження визначається на основі дайджесту образу, а не теґу. Це може бути корисно, якщо ви хочете переконатися, що ваші робочі навантаження запускають один і той самий код, незалежно від того, які зміни теґів відбуваються в реєстрі.
Коли ви (чи контролер) подаєте новий 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ʼа.Коли kubelet починає створювати контейнери для Podʼа за допомогою середовища виконання контейнерів, можливо, контейнер перебуває у стані Waiting з причини ImagePullBackOff.
Статус ImagePullBackOff означає, що контейнер не може запуститися через те, що Kubernetes не може завантажити образ контейнера (з причин, таких як неправильна назва образу або спроба завантаження з приватного реєстру без imagePullSecret). Частина BackOff вказує на те, що Kubernetes буде продовжувати пробувати завантажити образ зі збільшенням інтервалів між спробами.
Kubernetes збільшує інтервал між кожною спробою до тих пір, поки не досягне вбудованого обмеження, яке становить 300 секунд (5 хвилин).
To use this feature, you (or a cluster administrator) will need to enable the RuntimeClassInImageCriApi feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
Якщо ви увімкнете функціональну можливість RuntimeClassInImageCriApi, kubelet вказує образи контейнерів кортежем із назви образу та обробника середовища виконання, а не лише назвою чи дайджестом образу. Ваше середовище виконання контейнерів може адаптувати свою поведінку залежно від обраного обробника. Завантаження образів на основі класу середовища виконання буде корисним для контейнерів, що використовують віртуальні машини, таких як контейнери Windows Hyper-V.
Типово kubelet завантажує образи послідовно. Іншими словами, kubelet надсилає лише один запит на завантаження образу до служби образів одночасно. Інші запити на завантаження образів мають чекати, поки завершиться обробка поточного запиту.
Вузли приймають рішення про завантаження образу незалежно один від одного. Навіть коли ви використовуєте послідовні запити на завантаження образів, два різні вузли можуть завантажувати один і той самий образ паралельно.
Якщо ви хочете увімкнути паралельне завантаження образів, ви можете встановити поле serializeImagePulls у значення false в конфігурації kubelet. Якщо serializeImagePulls встановлено в false, запити на завантаження образів будуть надсилатись до служби образів негайно, і кілька образів буде завантажено одночасно.
Вмикаючи паралельне завантаження образів, переконайтеся, що служба образів вашого середовища виконання контейнерів може обробляти паралельне завантаження образів.
Kubelet ніколи не завантажує кілька образів паралельно від імені одного Podʼа. Наприклад, якщо у вас є Pod із контейнером ініціалізації та контейнером застосунку, завантаження образів для цих двох контейнерів не буде виконуватись паралельно. Однак якщо у вас є два Podʼи, які використовують різні образи, kubelet завантажує образи паралельно для цих двох різних Podʼів, коли увімкнено паралельне завантаження образів.
Коли 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 із жорстко закодованими назвами образів із суфіксами.
Приватні реєстри можуть вимагати автентифікації для виявлення та/або завантаження образів з них. Облікові дані можна надати кількома способами:
Через зазначення imagePullSecrets у визначенні Podʼа
Доступ до приватного реєстру мають лише ті Podʼи, які надали власні ключі.
Налаштування вузлів для автентифікації в приватному реєстрі
Використання втулка kubelet credential provider для динамічного отримання облікових даних для приватних реєстрів
kubelet може бути налаштований для використання втулка exec постачальника облікових даних для відповідного приватного реєстру.
Розширення від постачальників або локальні розширення
Якщо ви використовуєте власну конфігурацію вузла, ви (або ваш хмарний провайдер) можете реалізувати власний механізм автентифікації вузла в реєстрі контейнерів.
Ці варіанти пояснюються докладніше нижче.
imagePullSecrets в PodʼіУ Kubernetes підтримується вказівка ключів реєстру образів контейнерів у Podʼі. Усі imagePullSecrets мають бути Secrets, які існують у тому самому Namespace, що й Pod. Ці Secrets мають бути типу kubernetes.io/dockercfg або kubernetes.io/dockerconfigjson.
Конкретні інструкції щодо встановлення облікових даних залежать від середовища виконання контейнерів та реєстру, який ви вибрали для використання. Вам слід звертатися до документації щодо вашого рішення для отримання найточнішої інформації.
Для прикладу конфігурування приватного реєстру образів контейнерів дивіться завдання Завантаження образу з приватного реєстру. У цьому прикладі використовується приватний реєстр в Docker Hub.
Ви можете налаштувати kubelet для виклику бінарного втулка, щоб динамічно отримувати облікові дані реєстру для образу контейнера. Це найнадійніший та універсальний спосіб отримання облікових даних для приватних реєстрів, але також вимагає конфігурації kubelet для його увімкнення.
Ця техніка може бути особливо корисною для запуску статичних Podʼів, які потребують образів контейнерів, розміщених у приватному реєстрі. Використання ServiceAccount або Secret для надання облікових даних приватного реєстру є неможливим у специфікації статичного Podʼа, оскільки він не може мати посилань на інші ресурси API у своїй специфікації.
Докладніше дивіться Налаштування постачальника облікових даних образу kubelet.
Тлумачення config.json відрізняється між оригінальною реалізацією Docker та тлумаченням Kubernetes. У Docker ключі auths можуть вказувати тільки кореневі URL-адреси, тоді як Kubernetes дозволяє використовувати URL-адреси із шаблонами glob, а також шляхи, які відповідають префіксу. Єдиним обмеженням є те, що шаблони glob (*) повинні включати крапку (.) для кожного піддомену. Кількість піддоменів, що мають збіг, повинна дорівнювати кількості шаблонів glob (*.), наприклад:
*.kubernetes.io не збігатиметься з kubernetes.io, але збігатиметься з abc.kubernetes.io*.*.kubernetes.io не збігатиметься з abc.kubernetes.io, але збігатиметься з abc.def.kubernetes.ioprefix.*.io збігатиметься з prefix.kubernetes.io*-good.kubernetes.io збігатиметься з prefix-good.kubernetes.ioЦе означає, що файл config.json, подібний до цього, є дійсним:
{
"auths": {
"my-registry.example/images": { "auth": "…" },
"*.my-registry.example/images": { "auth": "…" }
}
}
Операції завантаження образів передають облікові дані середовищу виконання контейнерів CRI для кожного дійсного шаблону. Наприклад, такі назви образів контейнерів матимуть збіг:
my-registry.example/imagesmy-registry.example/images/my-imagemy-registry.example/images/another-imagesub.my-registry.example/images/my-imageОднак ці назви образів контейнерів не матимуть збігу:
a.sub.my-registry.example/images/my-imagea.b.sub.my-registry.example/images/my-imageKubelet виконує операції завантаження образів послідовно для кожного знайденого набору облікових даних. Це означає, що можливі кілька записів у config.json для різних шляхів:
{
"auths": {
"my-registry.example/images": {
"auth": "…"
},
"my-registry.example/images/subpath": {
"auth": "…"
}
}
}
Тепер, якщо контейнер вказує образ my-registry.example/images/subpath/my-image, то kubelet спробує завантажити його з обох джерел автентифікації, якщо завантаження з одного з них виявиться невдалим.
Типово kubelet намагається отримати кожен образ з вказаного реєстру. Однак якщо властивість imagePullPolicy контейнера встановлена на IfNotPresent або Never, то використовується локальний образ (переважно або виключно, відповідно).
Якщо ви хочете покладатися на попередньо завантажені образи як заміну автентифікації в реєстрі, вам слід переконатися, що всі вузли кластера мають однакові попередньо завантажені образи.
Це може бути використано для попереднього завантаження певних образів для швидкості або як альтернатива автентифікації в приватному реєстрі.
Подібно до використання постачальника облікових даних kubelet, попередньо завантажені образи також підходять для запуску статичних Podʼів, які залежать від образів, розміщених у приватному реєстрі.
Доступ до попередньо завантажених образів може бути авторизований згідно з перевіркою облікових даних для завантаження образів.
Якщо увімкнено функціональну можливість KubeletEnsureSecretPulledImages, Kubernetes перевірятиме облікові дані для кожного образу, який потребує їх для завантаження, навіть якщо цей образ вже присутній на вузлі. Ця перевірка гарантує, що образи із запиту Podʼа, які не були успішно завантажені за допомогою наданих облікових даних, повинні бути повторно завантажені з реєстру. Крім того, при повторному завантаженні образів з тими самими обліковими даними, які раніше призвели до успішного завантаження образів, не потрібно повторно завантажувати їх з реєстру, а вони перевіряються локально без доступу до реєстру (за умови, що образ доступний локально). Це контролюється полем imagePullCredentialsVerificationPolicy у конфігурації Kubelet.
Ця конфігурація контролює, коли потрібно перевіряти облікові дані для завантаження образів, якщо образ вже присутній на вузлі:
NeverVerify: Імітує поведінку, коли цю функціональну можливість вимкнено. Якщо образ присутній локально, облікові дані для завантаження образу не перевірятимуться.NeverVerifyPreloadedImages: Образи, завантажені за межами kubelet, не перевірятимуться, але всі інші образи будуть перевірятися. Це стандартна поведінка.NeverVerifyAllowListedImages: Образи, завантажені поза kubelet і згадані у списку preloadedImagesVerificationAllowlist, вказаному у конфігурації kubelet, не перевірятимуться.AlwaysVerify: Всі образи будуть перевірятися перед тим, як їх буде використано.Ця перевірка застосовується до попередньо завантажених образів, образів, завантажених за допомогою Secrets рівня вузла, та образів, завантажених за допомогою Secrets рівня Podʼа.
KubeletEnsureSecretPulledImagesКоли функція KubeletEnsureSecretPulledImages вмикається вперше, чи то через оновлення kubelet, чи то явним увімкненням цієї функції, і якщо kubelet має доступ до будь-яких образів у цей момент, усі вони вважатимуться попередньо завантаженими. Це відбувається тому, що в цьому випадку kubelet не має записів про образи, що завантажуються. Kubelet зможе почати створювати записи про завантаження образів лише тоді, коли образ завантажується вперше.
Якщо це викликає занепокоєння, рекомендується очистити вузли від усіх образів, які не повинні вважатися попередньо завантаженими, перед увімкненням функції.
Зверніть увагу, що видалення теки, що містить записи про завантаження образів, матиме той самий ефект при перезапуску kubelet, зокрема всі образи, які зараз кешовані на вузлах середовищем виконання контейнерів, вважатимуться попередньо завантаженими.
Вам потрібно знати імʼя користувача, пароль реєстру та адресу електронної пошти клієнта для автентифікації в реєстрі, а також його імʼя хоста. Виконайте таку команду, підставивши відповідні значення замість заповнювачів:
kubectl create secret docker-registry <name> \
--docker-server=<docker-registry-server> \
--docker-username=<docker-user> \
--docker-password=<docker-password> \
--docker-email=<docker-email>
Якщо у вас вже є файл облікових даних Docker, то замість наведеної вище команди ви можете імпортувати файл облікових даних як Secret Kubernetes. Створення Secret на основі наявних облікових даних Docker пояснює, як це зробити.
Це особливо корисно, якщо ви використовуєте кілька приватних реєстрів контейнерів, оскільки kubectl create secret docker-registry створює Secret, який працює лише з одним приватним реєстром.
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 на рівні вузла. Облікові дані буде обʼєднано.
Існує кілька рішень для конфігурації приватних реєстрів. Ось деякі типові сценарії використання та рекомендовані рішення.
imagePullSecrets.imagePullSecrets кожного простору імен.Якщо вам потрібен доступ до декількох реєстрів, ви можете створити Secret для кожного реєстру окремо.
У старіших версіях Kubernetes kubelet мав пряму інтеграцію з обліковими даними хмарного провайдера. Це давало йому можливість динамічно отримувати облікові дані для реєстрів образів.
Існувало три вбудовані реалізації інтеграції постачальника облікових даних kubelet: ACR (Azure Container Registry), ECR (Elastic Container Registry) та GCR (Google Container Registry).
Починаючи з версії Kubernetes v1.26 застарілий механізм було видалено, тому вам потрібно або:
imagePullSecrets та принаймні один Secret.