Модуль 4.1: ConfigMaps
Складність:
[MEDIUM]— кілька способів створення та споживанняЧас на проходження: 40-50 хвилин
Передумови: Модуль 1.1 (Поди), розуміння змінних середовища
Результати навчання
Розділ «Результати навчання»Після завершення цього модуля ви зможете:
- Створювати та перевіряти ConfigMaps із літералів, файлів, каталогів та декларативних маніфестів.
- Налаштовувати та порівнювати способи споживання ConfigMap через змінні середовища,
envFrom, проєктовані файли тому та монтуванняsubPath. - Діагностувати та налагоджувати застарілу, відсутню або приховану конфігурацію, спричинену семантикою оновлень, іменами ключів, межами просторів імен та шляхами монтування.
- Проєктувати стратегію ConfigMap, яка відокремлює неконфіденційну конфігурацію від Secrets, зберігає образи придатними для повторного використання та підтримує операції в Kubernetes 1.35.
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»Гіпотетичний сценарій: команда постачає невеликий вебзастосунок через той самий образ контейнера в розробці, стейджингу та продакшені. Образ справний, Под запускається, а розгортання Деплойменту завершується, але продакшен раптом починає вказувати на базу даних стейджингу, бо під час поспішного складання в образ було вшито неправильне значення часу виконання. Відкат образу виправляє продакшен, але ламає стейджинг, і кожне аварійне перескладання створює ще один шанс змішати зміни коду з налаштуваннями, специфічними для середовища. ConfigMaps існують саме для того, щоб тримати ці два аспекти окремо: образ несе застосунок, а кластер впроваджує неконфіденційну конфігурацію, яка змінюється від середовища до середовища.
Це розділення — не лише питання стилю. На іспиті CKAD ConfigMaps з’являються тому, що вони лежать на перетині дизайну Подів, вільного володіння командним рядком, редагування YAML та налагодження під тиском часу. Вам потрібно вміти швидко створювати їх із літералів, файлів і каталогів, але також треба розпізнавати, коли Под читає ConfigMap як змінні середовища, доступні лише на старті, а коли — як файли, що оновлюються наживо. Правильна відповідь часто залежить від однієї дрібної деталі: простору імен, де було створено ConfigMap, імені ключа всередині об’єкта, або того, чи приховує монтування тому файли, які вже були присутні в образі контейнера.
Аналогія з ресторанним меню досі корисна, якщо пам’ятати про її межі. Образ контейнера — це кухня: вона містить обладнання, рецепти та робочий процес персоналу, потрібні для приготування страви. ConfigMap — це дошка зі стравами дня: вона змінює щоденний вибір, не перебудовуючи кухню. Аналогія закінчується там, де починається безпека, бо дошка зі стравами дня видима для зали. Якщо значення — це пароль, приватний токен чи ключ сертифіката, воно належить до Secret або зовнішньої системи секретів, а не до ConfigMap.
У цьому модулі ви побудуєте той самий об’єкт конфігурації кількома способами, а потім підключите його до Подів через два основні шляхи споживання. Ви також відпрацюєте режими відмов, які мають значення в реальних кластерах: застарілі значення середовища, відсутні ключі, приховування каталогів, компроміси subPath та операційну вартість змінної конфігурації проти незмінної. Мета — не запам’ятати список команд. Мета — вміти ухвалити обґрунтоване рішення, коли іспит або інцидент дає вам лише симптоми та кілька хвилин.
Створення ConfigMaps як вхідних даних часу виконання
Розділ «Створення ConfigMaps як вхідних даних часу виконання»ConfigMap — це Kubernetes API об’єкт із прив’язкою до простору імен, який зберігає неконфіденційні дані «ключ-значення». Ключ завжди є рядком, а значенням може бути короткий скаляр на кшталт LOG_LEVEL=info або цілий файл конфігурації, збережений під ключем на кшталт app.properties. Це звучить незначно, але змінює модель випуску застосунку. Замість того, щоб виробляти один образ на кожне середовище, ви виробляєте один образ і додаєте контракт часу виконання середовища під час створення Пода.
Найпростіший шлях створення — імперативний, бо він швидкий і легкий для перевірки. Використовуйте літерали, коли значення короткі, коли ви відпрацьовуєте екзаменаційне завдання або коли конфігурація природно є набором імен у стилі змінних середовища. Команда нижче зберігає вихідні приклади з одним та кількома ключами, але використовує повну команду kubectl, щоб блок можна було виконати у скрипті чи неінтерактивній оболонці. Перш ніж запускати це, який вивід ви очікуєте від фінального перегляду YAML, і де кожен літерал з’явиться під об’єктом ConfigMap?
# Single key-valuekubectl create configmap app-config-single --from-literal=APP_ENV=production
# Multiple key-valueskubectl create configmap app-config-multi \ --from-literal=APP_ENV=production \ --from-literal=LOG_LEVEL=info \ --from-literal=MAX_CONNECTIONS=100
# View the resultkubectl get configmap app-config-multi -o yamlВивід розміщує літеральні значення під полем data, а не під spec, бо ConfigMap не є контролером, що узгоджує бажаний стан із дочірніми об’єктами. Це контейнер даних, на який посилаються інші специфікації Подів. Ця відмінність має значення під час налагодження. Якщо Под не підхоплює значення, ви не шукаєте подій ConfigMap, які перезапускають Под. Ви досліджуєте дані ConfigMap, специфікацію споживчого Пода та спосіб, у який kubelet спроєктував чи впровадив дані під час старту контейнера.
Файли стають корисними, коли застосунок уже очікує певний формат файлу конфігурації. Java-сервіс може читати application.properties, nginx може читати .conf-файл, а невеликий скрипт може читати JSON-документ. Коли ви створюєте ConfigMap із файлу, типовим ім’ям ключа є базове ім’я файлу. Ви можете залишити це типове ім’я, перепризначити ключ на інше ім’я або додати кілька файлів, щоб ConfigMap став невеликим набором іменованих документів конфігурації.
# Create config filesecho "database.host=db.example.comdatabase.port=5432database.name=myapp" > app.propertiesecho "log.level=debug" > logging.properties
# Create ConfigMap from filekubectl create configmap app-config-file --from-file=app.properties
# Custom key namekubectl create configmap app-config-custom --from-file=config.properties=app.properties
# Multiple fileskubectl create configmap app-config-multifile \ --from-file=app.properties \ --from-file=logging.propertiesФорму зі своїм ключем легко випустити з уваги, але це один із найчистіших способів пристосувати інфраструктуру до наявного застосунку. Якщо репозиторій зберігає файл із іменем settings-prod.properties, а застосунок наполягає на читанні application.properties, ви можете створити ключ ConfigMap з тим ім’ям, якого очікує застосунок. Це уникає перескладання образу чи додавання обгорткового скрипту, єдиним завданням якого є перейменування файлів під час старту. Це також робить очікуване ім’я файлу видимим у маніфесті Kubernetes, замість того щоб ховати його в логіці запуску контейнера.
Каталоги — це зручний шар над тією самою поведінкою файлів. Кожен звичайний файл у каталозі стає одним ключем ConfigMap, а вміст файлу — значенням. Введення каталогом корисне для локального відпрацювання та невеликих наборів, але воно може здивувати команди, коли в каталозі присутні резервні файли редактора, тимчасові файли чи сторонні нотатки. У продакшен-процесах згенеровані маніфести з Kustomize, Helm чи іншого інструмента пакування часто роблять обрані входи більш явними.
# Create directory and filesmkdir ./config-dircp app.properties logging.properties ./config-dir/
# All files in directory become keyskubectl create configmap app-config-dir --from-file=./config-dir/Декларативний YAML — це форма, якій варто надавати перевагу для змін, придатних для огляду, повторюваних середовищ та доставки на основі Git. Об’єкт нижче містить ту саму суміш налаштувань у стилі літералів та багаторядкового файлу властивостей. Блокові скаляри YAML корисні, бо вони зберігають переноси рядків усередині одного значення ConfigMap, що саме й потрібно застосункам, орієнтованим на файли, після того, як значення спроєктовано як файл у томі.
apiVersion: v1kind: ConfigMapmetadata: name: app-configdata: APP_ENV: production LOG_LEVEL: info app.properties: | database.host=db.example.com database.port=5432 database.name=myappConfigMaps також підтримують binaryData для значень, орієнтованих на байти, але більшість завдань CKAD з ConfigMap використовують data, бо прикладами є текстові файли та рядки у стилі змінних середовища. Ставтеся до binaryData як до спеціалізованого інструмента, а не приводу зберігати великі артефакти чи конфіденційні дані в ConfigMaps. Якщо застосунку потрібен приватний ключ сертифіката, використовуйте Secret. Якщо йому потрібен великий файл моделі, спрямуйте його через образ, сховище артефактів або том, спроєктований для такого навантаження.
Ще одна корисна межа — це власність. ConfigMap зазвичай повинен мати ту саму власність та ритм випусків, що й навантаження, яке його споживає. Якщо три не пов’язані між собою застосунки спільно використовують один ConfigMap, бо так було зручно під час лабораторної, пізніше редагування може створити заплутаний радіус ураження для всіх застосунків. Розділення конфігурації за навантаженням чи компонентом полегшує огляд, бо ім’я об’єкта, мітки та споживачі описують один операційний аспект, а не різношерсту шухляду налаштувань, і застарілі припущення швидко спливають на поверхню.
Імперативне та декларативне створення — це не конкурентні релігії; це інструменти для різних моментів. Під час іспиту CKAD імперативне створення з --dry-run=client -o yaml може швидко згенерувати початковий маніфест, хоча цей модуль тримає приклади прямими, щоб поведінка команди залишалася зрозумілою. Під час звичайної інженерної роботи переглянутий YAML-файл чи згенерований маніфест дає вам історію, код-рев’ю та чистіший шлях для відкату. Важлива звичка — перевіряти отримані ключі та значення, перш ніж підключати їх до Пода, бо Kubernetes не здогадається, що APP_ENV та APP_ENVIRONMENT мали бути одним і тим самим налаштуванням.
ConfigMaps прив’язані до простору імен, тож одне ім’я об’єкта може безпечно означати різні значення в різних середовищах. Саме тому команди часто створюють app-config у просторі імен development та інший app-config у просторі імен production. Посилання Пода не перетинає меж простору імен. Под у production, який посилається на app-config, бачить лише ConfigMap з іменем app-config у production, що є корисним запобіжником, коли імена середовищ керуються послідовно.
# Create namespaceskubectl create ns developmentkubectl create ns production
# Developmentkubectl create configmap app-config \ --from-literal=APP_ENV=development \ --from-literal=DEBUG=true \ -n development
# Productionkubectl create configmap app-config \ --from-literal=APP_ENV=production \ --from-literal=DEBUG=false \ -n productionПатерн просторів імен зменшує випадкове спільне використання, але не замінює огляду. Якщо обидва простори імен використовують те саме ім’я об’єкта, ваші команди налагодження мають містити простір імен або виконуватися в контексті, який уже налаштовано правильно. Поширена екзаменаційна пастка — створити ConfigMap у типовому просторі імен (default), а потім створити Под десь в іншому місці. Под не зможе розв’язати посилання, навіть якщо kubectl get configmap app-config начебто працює з вашого поточного простору імен.
Споживання ConfigMaps через середовище та файли
Розділ «Споживання ConfigMaps через середовище та файли»Створення ConfigMap лише робить дані доступними через Kubernetes API. Поду все ще потрібне явне посилання, яке вказує kubelet, як помістити ці дані в контейнер. Kubernetes підтримує дві основні моделі споживання: змінні середовища та проєктовані файли тому. Правильна модель залежить від того, як застосунок читає конфігурацію, як часто значення змінюються, і чи потрібна вам можливість перезавантаження наживо після того, як контейнер уже стартував.
Використовуйте одну змінну середовища, коли хочете відобразити один ключ ConfigMap на одне ім’я середовища контейнера. Ім’я змінної середовища може відрізнятися від ключа ConfigMap, що корисно, коли висхідний ConfigMap використовує одну угоду іменування, а застосунок очікує іншу. Якщо названого ключа немає, а посилання не позначене як необов’язкове, Под не зможе успішно запуститися, бо kubelet не може побудувати середовище контейнера.
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx env: - name: APP_ENVIRONMENT valueFrom: configMapKeyRef: name: app-config key: APP_ENVВикористовуйте envFrom, коли хочете, щоб кожен ключ у ConfigMap став змінною середовища з тим самим ім’ям. Це компактно й ефективно для налаштувань, які вже дотримуються правил іменування змінних середовища. Компроміс полягає в тому, що специфікація Пода більше не документує кожну окрему змінну, а недійсні імена середовища пропускаються, а не магічним чином переписуються на дійсні. Для екзаменаційної роботи envFrom швидкий, але для продакшен-маніфестів вам слід вирішити, чи варта зручність зниженої явності.
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx envFrom: - configMapRef: name: app-configЗупиніться та передбачте: ви оновлюєте ConfigMap, який Под споживає через envFrom. Чи підхопить запущений контейнер нові значення автоматично, і чи зміниться ваша відповідь, якби той самий ConfigMap було змонтовано як проєктований файл тому замість впровадження як змінних середовища?
Змінні середовища прості, бо більшість застосунків можуть їх читати, але це дані часу старту. Щойно процес контейнера починається, значення стають частиною середовища цього процесу. Kubernetes не переписує середовище вже запущеного процесу після зміни ConfigMap. Це робить змінні середовища хорошим вибором для стабільних налаштувань, таких як режим, перемикачі функцій, що читаються лише на старті, та значення, де перезапуск Деплойменту є прийнятною частиною процесу зміни.
Проєктовані файли тому краще підходять, коли застосунок уже читає файли, коли формат файлу має значення, або коли ви хочете, щоб Kubernetes оновлював змонтовані дані після зміни ConfigMap. У повному монтуванні тому нижче кожен ключ ConfigMap стає файлом під /etc/config, а вмістом файлу є відповідне значення. Образу контейнера не потрібно містити ці файли, і той самий образ може отримувати різний вміст файлів у різних просторах імен чи випусках.
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-configПовне монтування тому має одну важливу операційну особливість: монтування тому в шлях каталогу приховує будь-які файли, які вже були присутні в цьому шляху в образі контейнера. Kubernetes не зливає два каталоги. Він розміщує проєктований том у цій точці монтування, тож вихідний вміст каталогу образу більше не видимий через цей шлях. Зупиніться та поміркуйте: якби /etc/config уже містив типові сертифікати чи базову конфігурацію, поставлені в образі, що зробило б це монтування з тими файлами, і як ви могли б уникнути їхнього приховування?
Коли вам потрібні лише обрані ключі, поле items дає вам білий список та необов’язкове перепризначення імені файлу. Це корисно, коли ConfigMap містить кілька налаштувань, але певний контейнер має бачити лише один файл. Воно також розв’язує проблему невідповідності імен файлів: ключ ConfigMap може бути app.properties, тоді як файл усередині контейнера може мати ім’я application.properties. Цей вибір видимий у специфікації Пода, яку легше переглядати, ніж команду запуску, що копіює файли туди-сюди.
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-config items: - key: app.properties path: application.propertiesКоли вам потрібно помістити один файл до наявного каталогу, не приховуючи решти каталогу, використовуйте монтування subPath. Шлях монтування називає кінцеве розташування файлу, а subPath обирає ключ ConfigMap, який має з’явитися в цьому розташуванні. Це уникає проблеми приховування каталогу, але змінює поведінку оновлень. Монтування subPath не отримує автоматичних оновлень ConfigMap після старту контейнера, тож вам слід використовувати його, коли збереження наявних файлів образу важливіше за проєкцію наживо.
volumeMounts:- name: config-volume mountPath: /etc/config/app.conf subPath: app.propertiesДва шляхи споживання найлегше запам’ятати як діаграму потоку даних. Той самий ConfigMap може живити змінні середовища або файли, але контейнер бачить різні форми даних. Впровадження середовища перетворює ключі на записи середовища процесу на старті. Проєкція тому перетворює ключі на файли під змонтованим шляхом. Застосунок вирішує, чи читаються ці файли один раз, опитуються, відстежуються чи ігноруються після старту.
┌─────────────────────────────────────────────────────────────┐│ ConfigMap Usage │├─────────────────────────────────────────────────────────────┤│ ││ ConfigMap: app-config ││ ┌─────────────────────────────────────┐ ││ │ APP_ENV: production │ ││ │ LOG_LEVEL: info │ ││ │ app.properties: | │ ││ │ database.host=db.example.com │ ││ │ database.port=5432 │ ││ └─────────────────────────────────────┘ ││ │ │ ││ ▼ ▼ ││ ┌──────────────┐ ┌──────────────┐ ││ │ envFrom │ │ volume │ ││ │ │ │ mount │ ││ │ $APP_ENV │ │ │ ││ │ $LOG_LEVEL │ │ /etc/config/ │ ││ └──────────────┘ │ app.properties│ ││ └──────────────┘ ││ │└─────────────────────────────────────────────────────────────┘Ця діаграма також показує, чому ConfigMap не робить застосунок налаштовуваним у будь-який спосіб автоматично. Kubernetes може помістити дані в контейнер, але не може змусити застосунок перечитати дані в потрібний момент. Якщо застосунок читає /etc/config/app.properties один раз під час старту, оновлений наживо файл тому зміниться на диску, але процес може й далі використовувати старі налаштування з пам’яті. Хороший дизайн Kubernetes та хороший дизайн застосунку зустрічаються на цій межі.
Семантика оновлень та налагодження в Kubernetes 1.35
Розділ «Семантика оновлень та налагодження в Kubernetes 1.35»Поведінка оновлення ConfigMap залежить від методу споживання. Змінні середовища копіюються в середовище процесу контейнера на старті, тож вони потребують перезапуску Пода для зміни. Повні монтування тому ConfigMap оновлюються kubelet після зміни ConfigMap, з урахуванням часу синхронізації kubelet та поведінки кешу. Монтування subPath є особливим випадком, бо шлях змонтованого файлу прив’язується на старті контейнера й не отримує пізніших оновлень проєкції, які отримує звичайний том ConfigMap.
| Метод | Поведінка оновлення |
|---|---|
| Змінні середовища | НЕ оновлюються — потрібен перезапуск Пода |
| Монтування тому | Оновлюються автоматично (період синхронізації kubelet зазвичай близько 1 хв) |
| Монтування subPath | НЕ оновлюються — потрібен перезапуск Пода |
Таблиця коротка, але вона визначає багато рішень щодо налагодження. Якщо Деплоймент читає APP_ENV через envFrom, редагування ConfigMap та очікування не змінить середовище запущеного процесу. Правильна операційна дія — перезапустити чи розгорнути замінні Поди, щоб нові контейнери було створено з новим середовищем. Якщо Под читає змонтований файл, а застосунок правильно відстежує цей файл, очікування проєкції kubelet може бути достатнім. Якщо Под використовує subPath, розташування файлу може виглядати точним, але перезапуск залишається частиною плану оновлення.
# Restart pods to pick up env var changeskubectl rollout restart deployment/myapp
# For volume-mounted configs, wait or force sync# Pods auto-update within the kubelet sync periodНалагодження проблеми з ConfigMap починається з простого ланцюга доказів. По-перше, переконайтеся, що ConfigMap існує в тому самому просторі імен, що й Под. По-друге, дослідіть точні імена ключів та значення в об’єкті. По-третє, дослідіть специфікацію Пода, щоб побачити, чи використовує посилання env, envFrom, том, обрані items чи subPath. Нарешті, перевірте запущений контейнер у тій самій формі, яку бачить застосунок: виведіть середовище для впровадження середовища, перелічіть змонтований каталог для файлів або прочитайте конкретний шлях файлу, який відкриває застосунок.
Швидкий довідник нижче зберігає вихідне покриття команд, використовуючи повні виконувані команди. Спокусливо одразу перейти до edit, але на іспиті з обмеженим часом чи під час продакшен-інциденту вам слід дослідити, перш ніж змінювати. Друкарська помилка в ключі може виглядати як баг застосунку, невідповідність простору імен може виглядати як відсутній об’єкт, а змонтований каталог може виглядати як порожній каталог конфігурації, коли він насправді приховує вміст образу.
# Createkubectl create configmap NAME --from-literal=KEY=VALUEkubectl create configmap NAME --from-file=FILEkubectl create configmap NAME --from-file=DIR/
# Viewkubectl get configmap NAME -o yamlkubectl describe configmap NAME
# Editkubectl edit configmap NAME
# Deletekubectl delete configmap NAMEKubernetes 1.35 досі трактує ConfigMaps як звичайні API-об’єкти зі стандартною поведінкою простору імен та RBAC. Будь-хто, хто може читати ConfigMap, може читати його дані, і ці дані не є місцем для секретів. Secrets мають власний тип об’єкта, і навіть Secrets потребують ретельного шифрування кластера та контролю доступу. ConfigMaps призначені для неконфіденційної конфігурації, такої як рівні логування, перемикачі функцій, які безпечно розкривати, імена файлів, імена хостів, що не є обліковими даними, та режими застосунку.
Незмінні ConfigMaps — це ще один операційний вибір. Додавання immutable: true запобігає пізнішим змінам даних об’єкта, що може зменшити випадкові редагування та знизити навантаження від спостереження kubelet для стабільної конфігурації. Компроміс полягає в тому, що оновлення потребують створення нового імені ConfigMap та зміни посилання в шаблоні Пода, що часто є хорошим патерном випуску, але менш зручним для швидких експериментів. Використовуйте незмінність, коли конфігурація має рухатися разом із випуском, а не коли ви очікуєте, що оператор налаштовуватиме її на місці під час лабораторної.
Перевірка та усунення несправностей у посиланнях на ConfigMap
Розділ «Перевірка та усунення несправностей у посиланнях на ConfigMap»Усунення несправностей ConfigMap відбувається швидше, коли ви відокремлюєте проблеми об’єкта від проблем проєкції. Проблема об’єкта означає, що Kubernetes не може знайти чи прочитати ConfigMap або ключ, на який посилається Под. Проблема проєкції означає, що об’єкт існує, але контейнер не бачить очікуваної змінної середовища чи файлу. Ці дві категорії ведуть до різних доказів. Проблеми об’єкта проявляються в подіях Пода та повідомленнях kubelet, тоді як проблеми проєкції проявляються в середовищі контейнера, файловій системі чи логах застосунку.
Почніть із простору імен та імені об’єкта, бо такі відмови поширені й дешеві для усунення. Под не шукає по кластеру ConfigMap з відповідним іменем. Він розв’язує посилання всередині власного простору імен, використовуючи точне ім’я об’єкта, записане в специфікації Пода. Якщо ви створили app-config у default, а застосували Под у production, обидва ресурси можуть виглядати правильними, коли їх досліджувати окремо, але посилання все одно не спрацьовує. Саме тому надійні команди усунення несправностей містять -n, щойно простори імен потрапляють у сценарій.
Після того як об’єкт існує в правильному просторі імен, порівняйте ключі точно. Ключі ConfigMap не обізнані зі схемою, і Kubernetes не трактуватиме APP_ENV, APP_ENVIRONMENT та app_env як споріднені значення. Посилання env на один ключ відмовляє інакше, ніж envFrom: явне посилання вказує на один обов’язковий ключ, тоді як envFrom намагається перетворити всі дійсні ключі на змінні середовища. Якщо застосунок бачить порожню змінну, причиною може бути друкарська помилка в команді застосунку, відсутній ключ або ключ, який так і не став дійсною змінною середовища.
Прапорець optional змінює поведінку відмови, а не якість даних. Kubernetes дозволяє позначати деякі посилання ConfigMap як необов’язкові, що може бути корисним для типових значень чи точок розширення, але необов’язкові посилання також можуть приховувати помилки. Якщо застосунок справді має безпечні типові значення, необов’язкові посилання можуть бути доречними. Якщо налаштування потрібне для коректності, необов’язкове посилання перетворює зрозумілу відмову на старті на загадку часу виконання. В екзаменаційних завданнях уникайте optional, якщо завдання явно про це не просить або сценарій чітко не описує резервну поведінку.
Для файлових проєкцій дослідіть як змонтований шлях, так і відображення «ключ–шлях» ConfigMap. Повний том ConfigMap створює один файл на ключ у шляху монтування, якщо items не звужує вибір. Якщо items присутній, а названий ключ неправильний, проєктований файл не з’явиться як очікувалося. Якщо шлях монтування — це каталог, пам’ятайте, що вигляд каталогу походить від тому. Якщо шлях монтування — це файл із subPath, пам’ятайте, що оновлення потребують заміни Пода.
Дозволи файлів також можуть бути частиною діагностики, хоча вони рідше зустрічаються у вступних завданнях CKAD. Томи ConfigMap монтуються лише для читання, і застосункам слід трактувати їх як вхідні дані, а не як стан, доступний для запису. Якщо процес намагається відредагувати власний файл конфігурації на місці, відмова не є проблемою створення ConfigMap. Правильний дизайн — записувати стан часу виконання деінде, наприклад в emptyDir чи том даних застосунку, а ConfigMap тримати як джерело бажаної конфігурації.
Розгортання Деплойментів додає ще один шар. Редагування ConfigMap не змінює автоматично шаблон Пода Деплойменту, тож контролер Деплойменту не має причини створювати новий ReplicaSet лише через те, що змінився ConfigMap, на який є посилання. Якщо ваша операційна модель потребує, щоб кожне редагування ConfigMap створювало нові Поди, додайте навмисний крок розгортання або використайте патерн пакування, який змінює анотацію шаблона Пода, коли вміст конфігурації змінюється. Саме тому багато Helm-чартів додають анотації з контрольними сумами для ConfigMaps, тоді як простіші лабораторні часто використовують kubectl rollout restart.
Найкраще питання для налагодження — «де значення перестало рухатися?». Якщо об’єкт ConfigMap має правильний ключ та значення, дані потрапили в API-сервер. Якщо специфікація Пода посилається на правильний об’єкт та ключ, бажану проєкцію оголошено. Якщо середовище контейнера чи змонтований файл показує правильне значення, Kubernetes доставив його до межі процесу. Якщо застосунок усе одно поводиться некоректно, наступне дослідження — це поведінка перезавантаження застосунку, правила розбору або інше джерело конфігурації, яке перевизначає значення.
Перш ніж змінювати живу конфігурацію, передбачте радіус ураження. ConfigMap може спільно використовуватися багатьма Подами в одному просторі імен, тож редагування, яке виправляє один Деплоймент, може вплинути на іншого споживача. Зміна, змонтована як том, може дістатися до запущених Подів за розкладом проєкції kubelet, тоді як зміна змінної середовища чекає на заміну Пода. Ім’я ConfigMap з версією робить радіус ураження явним, бо лише Поди, які посилаються на нове ім’я, отримують його. Це додаткове ім’я об’єкта часто менш заплутане, ніж змінний спільний об’єкт із незрозумілими споживачами.
Гіпотетичний сценарій: застосунок має одночасно LOG_LEVEL зі змінної середовища та log.level усередині змонтованого файлу властивостей. Оператор змінює лише ключ ConfigMap, який використовує файл, а потім очікує, що рівень логування процесу зміниться негайно. Ретельна діагностика запитує, яке джерело застосунок насправді читає для рівня логування, чи перечитує він файл, і чи має середовище процесу інше значення, яке перемагає під час старту. ConfigMaps можуть доставляти дані в кількох формах, але пріоритет застосунку все одно вирішує поведінку.
Для екзаменаційної практики складіть короткий мисленнєвий контрольний список, перш ніж друкувати: простір імен, ім’я об’єкта, ім’я ключа, метод споживання, шлях монтування, поведінка оновлення та поведінка читання застосунку. Цей список швидший за спроби випадкових редагувань, бо кожен пункт виключає категорію відмови. Він також не дає вам застосувати неправильне виправлення. Перезапуск Пода допомагає зі змінними середовища та монтуваннями subPath, але не виправляє друкарську помилку в ключі ConfigMap. Редагування ConfigMap допомагає зі значеннями даних, але не виправляє шлях монтування, який приховує потрібні файли образу.
Розбір прикладу: конфігурація Nginx без перескладання образу
Розділ «Розбір прикладу: конфігурація Nginx без перескладання образу»Вихідний модуль використовував nginx, щоб показати, чому файлова конфігурація є природним випадком використання ConfigMap. Nginx уже читає файли конфігурації, тож ConfigMap може надати файл, не складаючи власний образ. Приклад нижче записує nginx.conf, створює з нього ConfigMap і монтує цей один файл поверх /etc/nginx/conf.d/default.conf з subPath. Сенс subPath тут навмисний: образи nginx уже містять корисну структуру каталогів, і заміна цілого каталогу була б іншим операційним вибором.
# nginx.confcat << 'EOF' > nginx.confserver { listen 80; server_name localhost; location / { root /usr/share/nginx/html; }}EOF
kubectl create configmap nginx-config --from-file=nginx.conf
# Mount in podcat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: nginx-customspec: containers: - name: nginx image: nginx volumeMounts: - name: config mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf volumes: - name: config configMap: name: nginx-configEOFПісля запуску цього Пода контейнер бачить файл за шляхом /etc/nginx/conf.d/default.conf, вміст якого походить із ключа ConfigMap nginx.conf. Інші файли в /etc/nginx/conf.d залишаються видимими, бо том не замінив увесь каталог. Ціна — це поведінка оновлення: зміна ConfigMap не оновить цей файл subPath у запущеному контейнері. Якщо вам потрібна нова конфігурація nginx, перезапустіть Под або розгорніть Деплоймент, щоб файл було змонтовано наново під час створення контейнера.
Сценарій вправи: контейнер агента логування постачається із сертифікатами та типовими значеннями під /etc/agent, але ваша власна конфігурація логування має з’явитися поруч із цими файлами. Якщо ви змонтуєте весь ConfigMap у /etc/agent, проєктований том приховає сертифікати та типові значення з образу. Безпечніший дизайн — створити ключ ConfigMap на кшталт custom.conf і змонтувати його в /etc/agent/custom.conf з subPath, а потім задокументувати, що оновлення файлу потребує заміни Пода. Це не драматична історія про реальний збій; це точна механіка монтування тому, застосована до поширеної структури агента.
Розбір прикладу також демонструє звичку огляду, яка масштабується далеко за межі nginx. Коли ви бачите mountPath, що закінчується каталогом, запитайте, чи мав образ важливий вміст там. Коли ви бачите mountPath, що закінчується файлом, та присутній subPath, запитайте, чи включає план випуску перезапуски для оновлень. Коли ви бачите envFrom, запитайте, чи кожен ключ є дійсним та задуманим ім’ям змінної середовища. Ці питання перетворюють роботу з ConfigMap із пригадування синтаксису на операційне міркування.
Патерни та антипатерни
Розділ «Патерни та антипатерни»Патерни та антипатерни для ConfigMaps здебільшого стосуються вибору правильної межі. ConfigMap має описувати неконфіденційні вибори часу виконання, яким дозволено варіюватися поза образом. Він не повинен ставати звалищем для облікових даних, великих блобів, згенерованого стану чи значень, які застосунок не може безпечно перезавантажити. Таблиця нижче зосереджується на конкретних виборах, які ви можете обґрунтувати під час проєктування, огляду чи налагодження.
| Патерн | Коли використовувати | Чому працює | Міркування щодо масштабування |
|---|---|---|---|
| Один образ, ConfigMap на простір імен | Той самий застосунок працює в розробці, стейджингу та продакшені | Образ залишається придатним для повторного використання, тоді як кожен простір імен володіє своїми значеннями часу виконання | Тримайте імена об’єктів послідовними, але завжди включайте простори імен в операційні команди |
| Файлова проєкція для застосунків, орієнтованих на файли | Застосунок уже читає файли .conf, .properties, JSON чи YAML | Kubernetes проєктує ключі як файли без перескладання образів | Вирішіть, чи застосунок відстежує файли, чи потребує перезапуску після змін |
Явний вибір ключів через items | ConfigMap має кілька ключів, але одному контейнеру потрібні лише обрані файли | Специфікація Пода документує, які ключі стають видимими та які імена файлів вони використовують | Відсутні обрані ключі можуть заблокувати старт, якщо не налаштовано необов’язкову поведінку |
| Незмінні ConfigMaps випуску | Зміни конфігурації мають рухатися разом із переглянутими випусками | Нові імена ConfigMap роблять відкати та аудиторські сліди чіткішими | Використовуйте згенеровані імена чи імена з версією, щоб шаблони Подів змінювалися під час оновлення |
| Антипатерн | Що йде не так | Краща альтернатива |
|---|---|---|
| Зберігання паролів у ConfigMaps | Значення у відкритому тексті легко прочитати через API та інструментарій | Використовуйте Secrets з відповідним RBAC та шифруванням у спокої там, де це потрібно |
| Монтування ConfigMap поверх заповненого каталогу | Файли з образу приховуються монтуванням тому | Монтуйте обрані ключі у шляхи файлів через subPath або монтуйте в порожній виділений каталог |
| Очікування оновлення змінних середовища наживо | Середовище процесу фіксується після старту контейнера | Перезапускайте Поди для змін середовища або переносьте перезавантажувані дані у файли |
| Використання одного гігантського ConfigMap для не пов’язаних аспектів | Дрібні зміни створюють широкий радіус ураження та заплутану власність | Розділяйте за компонентом застосунку, життєвим циклом чи межею власності |
Антипатерни — це не моральні провали; зазвичай це швидкі рішення, які спрацювали під час першого тесту, а потім стали дорогими під час змін. Монтування цілого каталогу швидше за точне монтування файлу, але воно змінює вигляд файлової системи. Гігантський ConfigMap легко створити, але він робить огляд та власність нечіткими. Змінні середовища звичні, але вони не перезавантажуються. Сеньйорський хід — обрати найменший механізм, який відповідає тому, як застосунок насправді читає конфігурацію.
Рамка ухвалення рішень
Розділ «Рамка ухвалення рішень»Використовуйте рамку ухвалення рішень, коли вибираєте між літералами, файловою проєкцією, повними монтуваннями тому, обраними ключами, subPath, Secrets та незмінними патернами випуску. Перше питання — чутливість. Якщо значення конфіденційне, ConfigMap є неправильним об’єктом, навіть якщо синтаксис зручний. Друге питання — форма. Якщо застосунок очікує файл, збережіть форму файлу замість того, щоб сплющувати його у змінні середовища. Третє питання — життєвий цикл. Якщо значення має змінюватися без заміни Подів, змінні середовища та монтування subPath самі по собі не відповідають цій вимозі.
| Питання для рішення | Оберіть це | Уникайте цього |
|---|---|---|
| Чи значення чутливе? | Secret або зовнішній менеджер секретів | ConfigMap |
| Чи застосунок читає змінні середовища на старті? | env або envFrom | Монтування файлу, якщо застосунок не очікує файлів |
| Чи застосунок читає іменований файл? | Том ConfigMap з відображенням шляху items | Перескладання образу лише заради зміни файлу |
| Чи мають змонтовані дані оновлюватися в запущеному Поді? | Повний том ConfigMap та підтримка перезавантаження на рівні застосунку | subPath без плану перезапуску |
| Чи мають наявні файли образу залишатися видимими? | Монтування файлу subPath або виділений порожній каталог | Повне монтування поверх заповненого каталогу образу |
| Чи має конфігурація змінюватися лише через випуски? | Незмінні ConfigMaps з версією в назві | Редагування на місці з незрозумілою історією розгортань |
Який підхід ви обрали б тут і чому: сервіс читає LOG_LEVEL лише на старті, тоді як sidecar-процес читає таблицю маршрутизації з /etc/routes/routes.yaml кожні кілька секунд? Обґрунтована відповідь — помістити LOG_LEVEL у змінну середовища, а таблицю маршрутизації — у проєктований том ConfigMap. Якщо sidecar справді перечитує файл, він може спостерігати оновлення проєкції kubelet. Якщо основному сервісу потрібен новий рівень логування, перезапустіть Под або розгорніть Деплоймент, щоб середовище процесу було відтворено.
Для роботи на CKAD рамка також допомагає зі швидкістю. Якщо завдання каже «створіть ConfigMap із цього файлу та змонтуйте його як /etc/app/app.conf», створіть із файлу й використайте або items, або subPath залежно від того, чи ціль є проєкцією каталогу, чи одним файлом усередині наявного каталогу. Якщо завдання каже «розкрийте всі ключі ConfigMap як змінні середовища», візьміть envFrom. Якщо симптом каже «ConfigMap змінився, але Под усе ще має старе значення», визначте метод споживання, перш ніж щось змінювати.
Чи знали ви?
Розділ «Чи знали ви?»- ConfigMaps мають обмеження розміру 1 MiB. API-сервер Kubernetes застосовує обмеження розміру об’єктів, тож великі навантаження конфігурації належать до іншого механізму зберігання чи специфічного для застосунку шляху доставки.
- ConfigMaps є об’єктами з прив’язкою до простору імен. Под може посилатися на ConfigMap лише у власному просторі імен, ось чому невідповідності просторів імен є такими поширеними відмовами в лабораторних та на іспитах.
- Значення змінних середовища з ConfigMaps фіксуються на старті контейнера. Пізніше редагування ConfigMap не переписує середовище вже запущеного процесу.
- Поле
immutable: trueстало стабільним у Kubernetes 1.21. Воно може захистити стабільну конфігурацію від випадкових редагувань та зменшити накладні витрати на спостереження для кластерів із багатьма змонтованими ConfigMaps.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому трапляється | Як виправити |
|---|---|---|
| Очікування оновлення змінних середовища | Змінні середовища копіюються в процес на старті контейнера | Перезапустіть Под або розгорніть Деплоймент після змін ConfigMap |
Використання subPath з очікуванням оновлень наживо | Монтування subPath прив’язує обраний файл на старті | Використовуйте повний том ConfigMap для оновлень проєкції або плануйте перезапуск |
| Зберігання секретів у ConfigMaps | Дані ConfigMap є відкритим текстом для звичайних читань API | Перенесіть чутливі значення до Secrets чи схваленої зовнішньої системи секретів |
| Створення ConfigMap у неправильному просторі імен | ConfigMaps прив’язані до простору імен, і посилання Подів не перетинають просторів імен | Перестворіть чи застосуйте ConfigMap у просторі імен Пода й перевірте через -n |
| Введення неправильного імені ключа | Kubernetes зіставляє точні рядки ключів і не здогадується про намір | Дослідіть kubectl get configmap NAME -o yaml і точно зіставте посилання Пода |
| Монтування поверх заповненого каталогу | Монтування тому приховує файли образу в шляху монтування | Монтуйте в порожній каталог або використовуйте subPath для одного файлу |
Використання envFrom для неохайних імен ключів | Не кожен ключ ConfigMap є дійсним ім’ям змінної середовища | Використовуйте явні відображення env або перейменуйте ключі ConfigMap |
Тест
Розділ «Тест»Питання 1. Сценарій вправи: Розробник оновлює ConfigMap новими налаштуваннями підключення до бази даних і підтверджує коректність об’єкта через kubectl get configmap app-config -o yaml. Под усе ще використовує старі налаштування, а його маніфест показує envFrom під контейнером. Що вам слід перевірити і яка зміна змусить нові значення з’явитися?
A. Зачекати, поки kubelet спроєктує нові дані в середовище процесу.
B. Перезапустити чи розгорнути Под, бо змінні середовища встановлюються на старті контейнера.
C. Додати items до тому ConfigMap, бо envFrom потребує відображення шляху файлу.
D. Перетворити ConfigMap на Secret, бо Secrets оновлюють змінні середовища наживо.
Відповідь та обґрунтування
B правильна, бо значення, які споживаються через env чи envFrom, копіюються в середовище контейнера, коли контейнер стартує. A неправильна, бо проєкція kubelet застосовується до змонтованих томів, а не до середовища запущеного процесу. C неправильна, бо items належить до проєкції тому ConfigMap, а не до впровадження середовища. D неправильна, бо Secrets мають ту саму поведінку старту, коли споживаються як змінні середовища.
Питання 2. Сценарій вправи: Ви монтуєте ConfigMap у /etc/nginx/conf.d/, і nginx відмовляє, бо типовий файл, що походив з образу, більше не видимий. Яка діагностика найкраще пояснює відмову, і яке виправлення зберігає інші файли образу?
A. ConfigMap у неправильному просторі імен; перестворіть його в kube-system.
B. Монтування тому приховує каталог образу; змонтуйте один ключ як файл із subPath.
C. ConfigMap занадто великий; розділіть його на кілька менших ConfigMaps.
D. Образ не може читати ConfigMaps; перескладіть nginx із включеним файлом.
Відповідь та обґрунтування
B правильна, бо том, змонтований у шлях каталогу, замінює вигляд цього каталогу для контейнера. A неправильна, бо невідповідність простору імен завадила б розв’язанню ще до появи цього симптому файлової системи, а kube-system не є загальним виправленням. C недоречна, якщо тільки API не відхилив ConfigMap. D відмовляється від основної переваги конфігурації часу виконання і не потрібна, щоб nginx прочитав змонтований файл.
Питання 3. Сценарій вправи: Под перебуває у просторі імен production і посилається на app-config, але kubectl get configmap app-config із вашої оболонки показує очікуваний об’єкт, а Под усе одно повідомляє, що ConfigMap не знайдено. Яке найімовірніше пояснення?
A. ConfigMap існує в іншому просторі імен, ніж Под.
B. На ConfigMaps не можуть посилатися Поди, створені з YAML.
C. ConfigMap має бути незмінним, перш ніж Под зможе його споживати.
D. Под може споживати ConfigMaps лише через subPath.
Відповідь та обґрунтування
A правильна, бо ConfigMaps прив’язані до простору імен, а посилання Пода розв’язується лише всередині простору імен Пода. Команда оболонки могла використати типовий простір імен або інший простір імен поточного контексту. B неправильна, бо YAML є звичайним декларативним способом посилатися на ConfigMaps. C неправильна, бо незмінність є необов’язковою, а D неправильна, бо Поди можуть споживати ConfigMaps через змінні середовища та томи.
Питання 4. Сценарій вправи: Застосунок очікує файл із іменем /etc/app/application.properties, але ваш ключ ConfigMap — app.properties. Ви хочете, щоб ім’я змонтованого файлу відповідало застосунку, не змінюючи образ. Який підхід найкращий?
A. Використати items, щоб відобразити ключ app.properties на шлях application.properties.
B. Зберегти значення під binaryData, щоб Kubernetes перейменував його автоматично.
C. Помістити ім’я файлу у змінну середовища та сподіватися, що застосунок його виявить.
D. Додати immutable: true, бо незмінні ConfigMaps перепризначають імена файлів.
Відповідь та обґрунтування
A правильна, бо items дозволяє тому Пода відобразити ключ ConfigMap на конкретний проєктований шлях файлу. B неправильна, бо binaryData призначений для байтів, закодованих у стилі base64, а не для перепризначення імен файлів. C ненадійна, якщо тільки застосунок уже не підтримує цю змінну середовища. D неправильна, бо незмінність контролює, чи можуть дані змінюватися, а не те, як ключі стають шляхами.
Питання 5. Сценарій вправи: Огляд виявляє пароль бази даних поруч із LOG_LEVEL та APP_ENV у ConfigMap. Команда каже, що це прийнятно, бо лише Под застосунку посилається на об’єкт. Яка правильна реакція?
A. Залишити, бо посилання Подів роблять ConfigMaps приватними.
B. Перенести пароль до Secret чи схваленого менеджера секретів і тримати в ConfigMap лише неконфіденційні налаштування.
C. Додати пароль через envFrom, бо змінні середовища приховані.
D. Позначити ConfigMap незмінним, бо незмінні дані зашифровані.
Відповідь та обґрунтування
B правильна, бо ConfigMaps призначені для неконфіденційних даних і можуть читатися як відкритий текст користувачами чи контролерами з доступом до об’єкта. A неправильна, бо посилання Пода не робить об’єкт приватним. C неправильна, бо змінні середовища можна дослідити кількома способами, і вони не змінюють чутливості джерела. D неправильна, бо незмінність запобігає редагуванням; вона не шифрує збережені дані.
Питання 6. Сценарій вправи: Sidecar відстежує файли під /etc/routes, і вам потрібно, щоб оновлення маршрутів з’являлися без перескладання образу. В образі немає важливих файлів під /etc/routes. Який метод споживання ConfigMap підходить найкраще?
A. Повний том ConfigMap, змонтований у /etc/routes, у парі з поведінкою перезавантаження застосунку.
B. envFrom, бо всі ключі автоматично стають файлами маршрутів.
C. Монтування subPath для кожного файлу маршруту, бо subPath — єдиний шлях, що оновлюється наживо.
D. Лише створення з літералів, бо файлові ConfigMaps не можуть оновлюватися.
Відповідь та обґрунтування
A правильна, бо повний том ConfigMap може отримувати оновлення проєкції kubelet, а поведінка відстеження файлів sidecar може реагувати на ці зміни. B неправильна, бо envFrom створює змінні середовища, а не файли. C неправильна, бо монтування subPath не отримують пізніших оновлень проєкції ConfigMap. D неправильна, бо ConfigMaps, створені з файлів чи літералів, обидва можуть проєктуватися як файли тому.
Питання 7. Сценарій вправи: Ви хочете, щоб зміни конфігурації переглядалися, версіонувалися та розгорталися зі зміною шаблона Деплойменту, а не редагувалися на місці. Який дизайн найкраще відповідає цій операційній моделі?
A. Використовувати один змінний ConfigMap з іменем app-config назавжди й редагувати його під час інцидентів.
B. Використовувати незмінні ConfigMaps з версією в назві та оновлювати посилання шаблона Пода під час випуску.
C. Помістити всю конфігурацію в мітки образу, щоб Подам ніколи не потрібні були ConfigMaps.
D. Зберігати не пов’язані застосунки в одному ConfigMap, щоб був лише один об’єкт для огляду.
Відповідь та обґрунтування
B правильна, бо незмінні ConfigMaps з версією в назві роблять конфігурацію частиною артефакту випуску й змушують змінити шаблон Пода для розгортання. A неправильна для цієї операційної моделі, бо редагування на місці важче аудитувати та відкочувати. C зловживає метаданими образу й не надає файлів часу виконання чи змінних середовища. D збільшує радіус ураження та робить власність незрозумілою.
Практична вправа
Розділ «Практична вправа»Сценарій вправи: створіть невеликий набір конфігурації, спожийте його як змінні середовища, спожийте інший ConfigMap як файли, а потім відпрацюйте кілька швидкісних дриллів CKAD. Команди припускають, що ви працюєте в одноразовому просторі імен чи локальному навчальному кластері. Якщо ви запускаєте їх у спільному кластері, додавайте -n YOUR_NAMESPACE послідовно й приберіть об’єкти наприкінці.
Критерії успіху
Розділ «Критерії успіху»- Створити та перевірити ConfigMaps із літералів, файлів, каталогів та YAML-маніфестів.
- Налаштувати та порівняти змінні середовища,
envFrom, файли тому та монтуванняsubPath. - Діагностувати та налагодити застарілу, відсутню чи приховану конфігурацію, перевіривши ключі, простори імен, поведінку оновлення та шляхи монтування.
- Спроєктувати стратегію ConfigMap, яка тримає неконфіденційну конфігурацію окремо від Secrets для навантажень Kubernetes 1.35.
- Прибрати кожен Под та ConfigMap, створені під час лабораторної.
Налаштування: створення ConfigMap із літералів
Розділ «Налаштування: створення ConfigMap із літералів»# Create ConfigMap from literalskubectl create configmap web-config \ --from-literal=APP_COLOR=blue \ --from-literal=APP_MODE=production
# Verifykubectl get configmap web-config -o yamlЦе налаштування створює короткий ConfigMap, природно сформований як змінні середовища. Крок перевірки має значення, бо він підтверджує точні імена ключів, перш ніж Под спробує їх спожити. Якщо ви бачите APP_COLOUR в об’єкті, але APP_COLOR у Поді, Kubernetes не вгадає написання, яке ви мали на увазі.
Налаштування: створення з каталогу
Розділ «Налаштування: створення з каталогу»Кожен звичайний файл у каталозі стає одним ключем ConfigMap. Це відповідає робочому процесу з каталогами, показаному раніше в теоретичній частині, і корисне, коли у вас уже є невелика тека файлів конфігурації на диску.
mkdir -p ./config-direcho "database.host=db.example.com" > ./config-dir/app.propertiesecho "log.level=debug" > ./config-dir/logging.properties
kubectl create configmap web-config-dir --from-file=./config-dir/kubectl get configmap web-config-dir -o yaml
kubectl delete cm web-config-dirrm -rf ./config-dirНотатки до розв'язання
Отриманий ConfigMap має містити два ключі, названі за іменами файлів: app.properties та logging.properties. Якщо з’являються зайві файли, перевірте каталог на наявність резервних копій редактора чи тимчасових файлів, перш ніж створювати об’єкт.
Налаштування: створення з декларативного YAML
Розділ «Налаштування: створення з декларативного YAML»Декларативний YAML — це форма, якій варто надавати перевагу для змін, придатних для огляду, та доставки на основі Git. Застосуйте маніфест нижче, дослідіть ключі під data, а потім видаліть об’єкт.
cat << 'EOF' > /tmp/app-config.yamlapiVersion: v1kind: ConfigMapmetadata: name: app-config-yamldata: APP_ENV: production LOG_LEVEL: info app.properties: | database.host=db.example.com database.port=5432 database.name=myappEOF
kubectl apply -f /tmp/app-config.yamlkubectl get configmap app-config-yaml -o yamlkubectl delete cm app-config-yamlНотатки до розв'язання
Ключі у стилі літералів, такі як APP_ENV, з’являються як звичайні рядки під data, тоді як app.properties зберігає переноси рядків через блоковий скаляр YAML. Це та сама форма, яку ви підключите до Подів через змінні середовища чи монтування томів у наступних частинах.
Частина 1: змінні середовища
Розділ «Частина 1: змінні середовища»cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: env-podspec: containers: - name: app image: busybox command: ['sh', '-c', 'echo Color: $APP_COLOR, Mode: $APP_MODE && sleep 3600'] envFrom: - configMapRef: name: web-configEOF
# Verify environmentkubectl wait --for=condition=Ready pod/env-pod --timeout=30skubectl logs env-podНотатки до розв'язання
Вивід логу має містити значення кольору та режиму з ConfigMap. Якщо Под не стає готовим, дослідіть kubectl describe pod env-pod і шукайте повідомлення про відсутні ConfigMaps чи недійсні посилання. Якщо значення порожні, порівняйте ключі ConfigMap з іменами змінних середовища, використаними в команді.
Частина 2: монтування тому
Розділ «Частина 2: монтування тому»# Create config filekubectl create configmap nginx-index --from-literal=index.html='<h1>Hello from ConfigMap</h1>'
cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: vol-podspec: containers: - name: nginx image: nginx volumeMounts: - name: html mountPath: /usr/share/nginx/html volumes: - name: html configMap: name: nginx-indexEOF
# Testkubectl wait --for=condition=Ready pod/vol-pod --timeout=30skubectl exec vol-pod -- cat /usr/share/nginx/html/index.htmlНотатки до розв'язання
Файл /usr/share/nginx/html/index.html має містити HTML-значення з ключа ConfigMap з іменем index.html. Це монтування цілого каталогу прийнятне для лабораторної, бо мета — замінити типову сторінку nginx. У продакшен-каталозі образу, який містив потрібні файли, ви перевірили б, чи безпечніше точніше монтування items або subPath.
Прибирання
Розділ «Прибирання»kubectl delete pod env-pod vol-podkubectl delete configmap web-config nginx-indexПрактичний дрилл 1: створення з літералів
Розділ «Практичний дрилл 1: створення з літералів»kubectl create configmap drill1 --from-literal=KEY1=value1 --from-literal=KEY2=value2kubectl get cm drill1 -o yamlkubectl delete cm drill1Нотатки до розв'язання
Переконайтеся, що обидва ключі з’являються під data. Коротке ім’я ресурсу cm прийнятне як абревіатура ресурсу Kubernetes, тоді як команда все одно використовує повний бінарник kubectl. Видаліть ConfigMap після дослідження, щоб пізніші дрилли починалися з чистого стану.
Практичний дрилл 2: створення з файлу
Розділ «Практичний дрилл 2: створення з файлу»echo "setting1=onsetting2=off" > /tmp/settings.conf
kubectl create configmap drill2 --from-file=/tmp/settings.confkubectl get cm drill2 -o yamlkubectl delete cm drill2Нотатки до розв'язання
Ключем має бути settings.conf, бо Kubernetes використовує базове ім’я файлу, коли не надано власного імені ключа. Якщо вам потрібен інший ключ, ви б використали --from-file=desired-name=/tmp/settings.conf. Цей дрилл готує вас до монтувань томів, де ключ стає ім’ям файлу.
Практичний дрилл 3: змінні середовища
Розділ «Практичний дрилл 3: змінні середовища»kubectl create configmap drill3 --from-literal=DB_HOST=localhost --from-literal=DB_PORT=5432
cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: drill3spec: containers: - name: app image: busybox command: ['sh', '-c', 'env | grep DB && sleep 3600'] envFrom: - configMapRef: name: drill3EOF
kubectl wait --for=condition=Ready pod/drill3 --timeout=30skubectl logs drill3kubectl delete pod/drill3 cm/drill3Нотатки до розв'язання
Лог має показати обидві змінні, пов’язані з базою даних. Якщо ви відредагуєте ConfigMap після старту Пода, лог не зміниться, бо середовище процесу фіксоване. Видаліть обидва ресурси, перш ніж повторювати дрилл, щоб не зіткнутися з наявними іменами об’єктів.
Практичний дрилл 4: монтування тому
Розділ «Практичний дрилл 4: монтування тому»kubectl create configmap drill4 --from-literal=config.json='{"debug": true}'
cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: drill4spec: containers: - name: app image: busybox command: ['sh', '-c', 'cat /config/config.json && sleep 3600'] volumeMounts: - name: cfg mountPath: /config volumes: - name: cfg configMap: name: drill4EOF
kubectl wait --for=condition=Ready pod/drill4 --timeout=30skubectl logs drill4kubectl delete pod/drill4 cm/drill4Нотатки до розв'язання
Ключ ConfigMap config.json має з’явитися як файл під /config. Оскільки це повний том ConfigMap, пізніші оновлення проєкції ConfigMap можуть змінити змонтований файл, хоча застосунок усе одно має перечитати файл, щоб використати новий вміст. BusyBox просто друкує файл один раз, тож цей дрилл демонструє проєкцію, а не перезавантаження наживо.
Практичний дрилл 5: монтування конкретного ключа
Розділ «Практичний дрилл 5: монтування конкретного ключа»kubectl create configmap drill5 \ --from-literal=app.conf='main config' \ --from-literal=log.conf='log config'
cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: drill5spec: containers: - name: app image: busybox command: ['sh', '-c', 'ls /config && cat /config/application.conf && sleep 3600'] volumeMounts: - name: cfg mountPath: /config volumes: - name: cfg configMap: name: drill5 items: - key: app.conf path: application.confEOF
kubectl wait --for=condition=Ready pod/drill5 --timeout=30skubectl logs drill5kubectl delete pod/drill5 cm/drill5Нотатки до розв'язання
Лише application.conf має бути видимим у /config, навіть попри те, що ConfigMap також має log.conf. Список items обрав один ключ і перепризначив його ім’я файлу. Це патерн, який слід використовувати, коли ConfigMap містить кілька ключів, але контейнер має отримати лише точну підмножину.
Практичний дрилл 6: повний сценарій
Розділ «Практичний дрилл 6: повний сценарій»# Create nginx configcat << 'NGINX' > /tmp/nginx.confserver { listen 8080; location / { return 200 'Custom Config Works!\n'; add_header Content-Type text/plain; }}NGINX
kubectl create configmap drill6-nginx --from-file=/tmp/nginx.conf
cat << 'EOF' | kubectl apply -f -apiVersion: v1kind: Podmetadata: name: drill6spec: containers: - name: nginx image: nginx ports: - containerPort: 8080 volumeMounts: - name: nginx-config mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf volumes: - name: nginx-config configMap: name: drill6-nginxEOF
# Verify nginx loaded the mounted ConfigMap-backed configkubectl wait --for=condition=Ready pod/drill6 --timeout=30skubectl exec drill6 -- nginx -T 2>&1 | grep -F "Custom Config Works!"
kubectl delete pod/drill6 cm/drill6-nginxНотатки до розв'язання
Команда nginx -T виводить ефективну конфігурацію nginx, а збіг grep має надрукувати правило відповіді Custom Config Works! зі змонтованого файлу. Монтування subPath розміщує один ключ ConfigMap за шляхом файлу, якого очікує nginx, зберігаючи решту каталогу. Якщо ви зміните /tmp/nginx.conf і перестворите ConfigMap, замініть також Под, бо файл subPath не оновлюється наживо.
Перевірка засвоєного
Розділ «Перевірка засвоєного»Коли ви видаляєте змішані типи ресурсів однією командою
kubectl delete, використовуйте слеш-нотацію на кшталтkubectl delete pod/drill3 cm/drill3, щоб кожен аргумент називав і тип ресурсу, і об’єкт.
Джерела
Розділ «Джерела»- https://kubernetes.io/docs/concepts/configuration/configmap/
- https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/
- https://kubernetes.io/docs/concepts/configuration/secret/
- https://kubernetes.io/docs/concepts/storage/volumes/#configmap
- https://kubernetes.io/docs/concepts/storage/volumes/#using-subpath
- https://kubernetes.io/docs/concepts/configuration/overview/
- https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.35/#configmap-v1-core
- https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-configmap-em-
- https://kubernetes.io/docs/concepts/workloads/pods/
- https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
- https://kubernetes.io/docs/tasks/administer-cluster/encrypt-data/
- https://12factor.net/config
Наступний модуль
Розділ «Наступний модуль»Модуль 4.2: Secrets - Безпечне керування конфіденційними даними.