Модуль 4.1: ConfigMaps
Складність:
[MEDIUM]— Кілька способів створення та використанняЧас на виконання: 40–50 хвилин
Передумови: Модуль 1.1 (Поди), розуміння змінних оточення
Що ви зможете робити
Розділ «Що ви зможете робити»Після завершення цього модуля ви зможете:
- Створити ConfigMaps з літералів, файлів та директорій, використовуючи імперативний та декларативний методи
- Налаштувати Піди для використання ConfigMaps як змінних оточення та монтування томів
- Діагностувати проблеми конфігурації застосунків, спричинені відсутніми або неправильно змонтованими ConfigMaps
- Пояснити коли використовувати змінні оточення та коли монтування томів для впровадження конфігурації
Чому цей модуль важливий
Розділ «Чому цей модуль важливий»ConfigMaps відокремлюють конфігурацію від образів контейнерів. Замість того, щоб вбудовувати налаштування в образ, ви впроваджуєте їх під час запуску. Це дозволяє використовувати той самий образ у різних середовищах (dev, staging, production) з різними конфігураціями.
На іспиті CKAD часто перевіряють знання ConfigMaps, оскільки вони є фундаментальною частиною методології twelve-factor app. Очікуйте запитання щодо:
- Створення ConfigMaps з літералів, файлів та директорій
- Використання як змінних оточення
- Монтування як томів
- Оновлення конфігурацій
Аналогія з меню ресторану
Уявіть ConfigMaps як дошку зі спецпропозиціями ресторану. Кухня (образ контейнера) залишається незмінною, але спецпропозиції (конфігурація) змінюються щодня. Шеф-кухар не перебудовує кухню, щоб змінити меню — він просто оновлює дошку. ConfigMaps працюють так само: змініть конфігурацію, перезапустіть під, отримайте нову поведінку.
Створення ConfigMaps
Розділ «Створення ConfigMaps»З літералів
Розділ «З літералів»# Одна пара ключ-значенняk create configmap app-config --from-literal=APP_ENV=production
# Кілька пар ключ-значенняk create configmap app-config \ --from-literal=APP_ENV=production \ --from-literal=LOG_LEVEL=info \ --from-literal=MAX_CONNECTIONS=100
# Переглянути результатk get configmap app-config -o yamlЗ файлів
Розділ «З файлів»# Створити файл конфігураціїecho "database.host=db.example.comdatabase.port=5432database.name=myapp" > app.properties
# Створити ConfigMap з файлуk create configmap app-config --from-file=app.properties
# Власна назва ключаk create configmap app-config --from-file=config.properties=app.properties
# Кілька файлівk create configmap app-config \ --from-file=app.properties \ --from-file=logging.propertiesЗ директорій
Розділ «З директорій»# Усі файли в директорії стають ключамиk create configmap app-config --from-file=./config-dir/З YAML
Розділ «З YAML»apiVersion: v1kind: ConfigMapmetadata: name: app-configdata: APP_ENV: production LOG_LEVEL: info app.properties: | database.host=db.example.com database.port=5432 database.name=myappВикористання ConfigMaps
Розділ «Використання ConfigMaps»Як змінні оточення
Розділ «Як змінні оточення»Одна змінна:
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx env: - name: APP_ENVIRONMENT valueFrom: configMapKeyRef: name: app-config key: APP_ENVУсі ключі як змінні:
apiVersion: v1kind: Podmetadata: name: appspec: containers: - name: app image: nginx envFrom: - configMapRef: name: app-configЯк файли тому
Розділ «Як файли тому»Змонтувати весь ConfigMap:
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Змонтувати конкретні ключі:
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Змонтувати в конкретний файл:
volumeMounts:- name: config-volume mountPath: /etc/config/app.conf subPath: app.propertiesПатерни ConfigMap
Розділ «Патерни ConfigMap»Конфігурація для конкретного середовища
Розділ «Конфігурація для конкретного середовища»# Розробкаk create configmap app-config \ --from-literal=APP_ENV=development \ --from-literal=DEBUG=true \ -n development
# Продакшенk create configmap app-config \ --from-literal=APP_ENV=production \ --from-literal=DEBUG=false \ -n productionФайли конфігурації
Розділ «Файли конфігурації»# nginx.confcat << 'EOF' > nginx.confserver { listen 80; server_name localhost; location / { root /usr/share/nginx/html; }}EOF
k create configmap nginx-config --from-file=nginx.conf
# Змонтувати в подіcat << 'EOF' | k 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Оновлення ConfigMap
Розділ «Оновлення ConfigMap»Поведінка залежно від способу використання
Розділ «Поведінка залежно від способу використання»| Метод | Поведінка при оновленні |
|---|---|
| Змінні оточення | НЕ оновлюються — потрібен перезапуск пода |
| Монтування томів | Оновлюються автоматично (період синхронізації kubelet ~1 хв) |
| Монтування з subPath | НЕ оновлюються — потрібен перезапуск пода |
Примусове оновлення
Розділ «Примусове оновлення»# Перезапустити поди для застосування змін змінних оточенняk rollout restart deployment/myapp
# Для конфігурацій, змонтованих як томи, зачекайте або примусово синхронізуйте# Поди автоматично оновлюються протягом періоду синхронізації kubeletВізуалізація
Розділ «Візуалізація»┌─────────────────────────────────────────────────────────────┐│ Використання ConfigMap │├─────────────────────────────────────────────────────────────┤│ ││ ConfigMap: app-config ││ ┌─────────────────────────────────────┐ ││ │ APP_ENV: production │ ││ │ LOG_LEVEL: info │ ││ │ app.properties: | │ ││ │ database.host=db.example.com │ ││ │ database.port=5432 │ ││ └─────────────────────────────────────┘ ││ │ │ ││ ▼ ▼ ││ ┌──────────────┐ ┌──────────────┐ ││ │ envFrom │ │ монтування │ ││ │ │ │ тому │ ││ │ $APP_ENV │ │ │ ││ │ $LOG_LEVEL │ │ /etc/config/ │ ││ └──────────────┘ │ app.properties│ ││ └──────────────┘ ││ │└─────────────────────────────────────────────────────────────┘Швидка довідка
Розділ «Швидка довідка»# Створитиk create configmap NAME --from-literal=KEY=VALUEk create configmap NAME --from-file=FILEk create configmap NAME --from-file=DIR/
# Переглянутиk get configmap NAME -o yamlk describe configmap NAME
# Редагуватиk edit configmap NAME
# Видалитиk delete configmap NAMEЧи знали ви?
Розділ «Чи знали ви?»-
ConfigMaps мають обмеження розміру 1 МБ. Для більших конфігурацій розгляньте монтування зовнішнього сховища або використання init-контейнерів.
-
Дані ConfigMap зберігаються в etcd без шифрування (на відміну від Secrets, які можна зашифрувати в стані спокою). Не зберігайте конфіденційні дані в ConfigMaps.
-
Поле
immutable: true(Kubernetes 1.21+) запобігає випадковим змінам та покращує продуктивність кластера, зменшуючи навантаження на watch.
Типові помилки
Розділ «Типові помилки»| Помилка | Чому це шкодить | Рішення |
|---|---|---|
| Очікування оновлення змінних оточення | Застосунок використовує застарілу конфігурацію | Перезапустіть під після змін ConfigMap |
| Використання subPath з очікуванням оновлень | subPath не оновлюється автоматично | Використовуйте повне монтування тому або перезапуск |
| Зберігання секретів у ConfigMaps | Дані видимі у відкритому тексті | Використовуйте Secrets для конфіденційних даних |
| Відсутність простору імен для ConfigMaps | Конфігурація витікає між середовищами | Створюйте ConfigMaps для кожного простору імен |
| Помилка в назві ключа | Під не запуститься або отримає неправильну конфігурацію | Використовуйте k describe cm для перевірки |
Тест
Розділ «Тест»-
Як створити ConfigMap з кількох пар ключ-значення?
Відповідь
`kubectl create configmap NAME --from-literal=KEY1=VAL1 --from-literal=KEY2=VAL2` -
Як впровадити всі ключі ConfigMap як змінні оточення?
Відповідь
Використовуйте `envFrom` з `configMapRef`: ```yaml envFrom: - configMapRef: name: configmap-name ``` -
Чи оновлюються змінні оточення з ConfigMaps автоматично?
Відповідь
Ні. Змінні оточення встановлюються при запуску пода і не оновлюються. Для застосування змін потрібно перезапустити під. -
Як змонтувати лише конкретні ключі з ConfigMap?
Відповідь
Використовуйте `items` у визначенні тому: ```yaml volumes: - name: config configMap: name: my-config items: - key: specific-key path: filename ```
Практична вправа
Розділ «Практична вправа»Завдання: Створити та використати ConfigMaps кількома способами.
Підготовка:
# Створити ConfigMap з літералівk create configmap web-config \ --from-literal=APP_COLOR=blue \ --from-literal=APP_MODE=production
# Перевіритиk get configmap web-config -o yamlЧастина 1: Змінні оточення
cat << 'EOF' | k 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
# Перевірити оточенняk logs env-podЧастина 2: Монтування тому
# Створити файл конфігураціїk create configmap nginx-index --from-literal=index.html='<h1>Hello from ConfigMap</h1>'
cat << 'EOF' | k 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
# Тестуванняk exec vol-pod -- cat /usr/share/nginx/html/index.htmlОчищення:
k delete pod env-pod vol-podk delete configmap web-config nginx-indexПрактичні вправи
Розділ «Практичні вправи»Вправа 1: Створення з літералів (Ціль: 1 хвилина)
Розділ «Вправа 1: Створення з літералів (Ціль: 1 хвилина)»k create configmap drill1 --from-literal=KEY1=value1 --from-literal=KEY2=value2k get cm drill1 -o yamlk delete cm drill1Вправа 2: Створення з файлу (Ціль: 2 хвилини)
Розділ «Вправа 2: Створення з файлу (Ціль: 2 хвилини)»echo "setting1=onsetting2=off" > /tmp/settings.conf
k create configmap drill2 --from-file=/tmp/settings.confk get cm drill2 -o yamlk delete cm drill2Вправа 3: Змінні оточення (Ціль: 3 хвилини)
Розділ «Вправа 3: Змінні оточення (Ціль: 3 хвилини)»k create configmap drill3 --from-literal=DB_HOST=localhost --from-literal=DB_PORT=5432
cat << 'EOF' | k apply -f -apiVersion: v1kind: Podmetadata: name: drill3spec: containers: - name: app image: busybox command: ['sh', '-c', 'env | grep DB && sleep 3600'] envFrom: - configMapRef: name: drill3EOF
k logs drill3k delete pod drill3 cm drill3Вправа 4: Монтування тому (Ціль: 3 хвилини)
Розділ «Вправа 4: Монтування тому (Ціль: 3 хвилини)»k create configmap drill4 --from-literal=config.json='{"debug": true}'
cat << 'EOF' | k 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
k logs drill4k delete pod drill4 cm drill4Вправа 5: Монтування конкретного ключа (Ціль: 3 хвилини)
Розділ «Вправа 5: Монтування конкретного ключа (Ціль: 3 хвилини)»k create configmap drill5 \ --from-literal=app.conf='main config' \ --from-literal=log.conf='log config'
cat << 'EOF' | k 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
k logs drill5k delete pod drill5 cm drill5Вправа 6: Повний сценарій (Ціль: 5 хвилин)
Розділ «Вправа 6: Повний сценарій (Ціль: 5 хвилин)»Сценарій: Розгорнути nginx з власною конфігурацією.
# Створити конфігурацію nginxcat << 'NGINX' > /tmp/nginx.confserver { listen 8080; location / { return 200 'Custom Config Works!\n'; add_header Content-Type text/plain; }}NGINX
k create configmap drill6-nginx --from-file=/tmp/nginx.conf
cat << 'EOF' | k 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
# Тестування (зачекайте на готовність пода)k wait --for=condition=Ready pod/drill6 --timeout=30sk exec drill6 -- curl -s localhost:8080
k delete pod drill6 cm drill6-nginxНаступний модуль
Розділ «Наступний модуль»Модуль 4.2: Secrets — Безпечне керування конфіденційними даними.