Це багатосторінкова версія цього розділу для друку. Натисніть тут, щоб надрукувати.
Введення даних у застосунки
- 1: Визначення команд та аргументів для контейнера
- 2: Визначення залежних змінних середовища
- 3: Визначення змінних середовища для контейнера
- 4: Визначення значень змінних середовища за допомогою контейнера ініціалізації
- 5: Використання змінних середовища для передачі контейнерам інформації про Pod
- 6: Передача інформації про Pod контейнерам через файли
- 7: Розповсюдження облікових даних з використанням Secret
1 - Визначення команд та аргументів для контейнера
Ця сторінка показує, як визначати команди та аргументи при запуску контейнера в Pod.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Для перевірки версії введіть kubectl version.
Визначення команди та аргументів при створенні Podʼа
При створенні Podʼа ви можете визначити команду та аргументи для контейнерів, які працюють в Podʼі. Щоб визначити команду, включіть поле command у файл конфігурації. Щоб визначити аргументи для команди, включіть поле args у файл конфігурації. Команду та аргументи, які
ви визначаєте, не можна змінити після створення Podʼа.
Команда та аргументи, які ви визначаєте у файлі конфігурації, перевизначають станадртну команду та аргументи, надані образом контейнера. Якщо ви визначаєте аргументи, але не визначаєте команду, використовується стандартна команда з вашими новими аргументами.
Примітка:
Полеcommand відповідає ENTRYPOINT, а поле args відповідає CMD у деяких реалізаціях середовища виконання контейнерів.У цьому завданні ви створюєте Pod, який запускає один контейнер. Файл конфігурації для Podʼа визначає команду та два аргументи:
apiVersion: v1
kind: Pod
metadata:
name: command-demo
labels:
purpose: demonstrate-command
spec:
containers:
- name: command-demo-container
image: debian
command: ["printenv"]
args: ["HOSTNAME", "KUBERNETES_PORT"]
restartPolicy: OnFailure
Створіть Podʼ на основі файлу конфігурації YAML:
kubectl apply -f https://k8s.io/examples/pods/commands.yamlПерегляньте список запущених Podʼів:
kubectl get podsВивід показує, що контейнер, який працював у Podʼі command-demo, завершився.
Щоб побачити вивід команди, яка запустилася в контейнері, перегляньте логи з Podʼа:
kubectl logs command-demoВивід показує значення змінних середовища HOSTNAME та KUBERNETES_PORT:
command-demo tcp://10.3.240.1:443
Використання змінних середовища для визначення аргументів
У попередньому прикладі ви визначили аргументи безпосередньо, надавши їх. Як альтернативу наданню рядків безпосередньо, ви можете визначати аргументи, використовуючи змінні середовища:
env:
- name: MESSAGE
value: "hello world"
command: ["/bin/echo"]
args: ["$(MESSAGE)"]
Це означає, що ви можете визначити аргумент для Podʼа, використовуючи будь-які з технік доступних для визначення змінних середовища, включаючи ConfigMap та Secret.
Примітка:
Змінна середовища зʼявляється у дужках,"$(VAR)". Це необхідно для того, щоб змінна була розгорнута у полі command або args.Виконання команди в оболонці
У деяких випадках вам потрібно, щоб ваша команда запускалася в оболонці. Наприклад, ваша команда може складатися з кількох команд, обʼєднаних в конвеєр, або це може бути сценарій оболонки. Щоб запустити вашу команду в оболонці, оберніть її так:
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 10;done"]
Що далі
- Дізнайтеся більше про налаштування Podʼів та контейнерів.
- Дізнайтеся більше про виконання команд у контейнері.
- Дивіться Контейнер.
2 - Визначення залежних змінних середовища
Ця сторінка показує, як визначати залежні змінні середовища для контейнера у Podʼі Kubernetes.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Визначення змінної залежної від середовища для контейнера
При створенні Podʼа ви можете встановлювати залежні змінні середовища для контейнерів, які працюють в Podʼі. Для встановлення залежних змінних середовища ви можете використовувати $(VAR_NAME) у value env у файлі конфігурації.
У цьому завданні ви створюєте Pod, який запускає один контейнер. Файл конфігурації для Podʼа визначає залежну змінну середовища з визначеним загальним використанням. Ось маніфест конфігурації для Podʼа:
apiVersion: v1
kind: Pod
metadata:
name: dependent-envars-demo
spec:
containers:
- name: dependent-envars-demo
args:
- while true; do echo -en '\n'; printf UNCHANGED_REFERENCE=$UNCHANGED_REFERENCE'\n'; printf SERVICE_ADDRESS=$SERVICE_ADDRESS'\n';printf ESCAPED_REFERENCE=$ESCAPED_REFERENCE'\n'; sleep 30; done;
command:
- sh
- -c
image: busybox:1.28
env:
- name: SERVICE_PORT
value: "80"
- name: SERVICE_IP
value: "172.17.0.1"
- name: UNCHANGED_REFERENCE
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: PROTOCOL
value: "https"
- name: SERVICE_ADDRESS
value: "$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
- name: ESCAPED_REFERENCE
value: "$$(PROTOCOL)://$(SERVICE_IP):$(SERVICE_PORT)"
Створіть Podʼ на основі цього маніфесту:
kubectl apply -f https://k8s.io/examples/pods/inject/dependent-envars.yamlpod/dependent-envars-demo createdПерегляньте список запущених Podʼів:
kubectl get pods dependent-envars-demoNAME READY STATUS RESTARTS AGE dependent-envars-demo 1/1 Running 0 9sПеревірте лог контейнера, що працює у вашому Podʼі:
kubectl logs pod/dependent-envars-demoUNCHANGED_REFERENCE=$(PROTOCOL)://172.17.0.1:80 SERVICE_ADDRESS=https://172.17.0.1:80 ESCAPED_REFERENCE=$(PROTOCOL)://172.17.0.1:80
Як показано вище, ви визначили правильне посилання на залежність SERVICE_ADDRESS, неправильне посилання на залежність UNCHANGED_REFERENCE і пропустили залежні посилання на залежність ESCAPED_REFERENCE.
Коли змінна середовища вже визначена при посиланні, посилання може бути правильно розгорнуте, як у випадку з SERVICE_ADDRESS.
Зверніть увагу, що порядок має значення у списку env. Змінна середовища не вважається "визначеною", якщо вона вказана далі в списку. Тому UNCHANGED_REFERENCE не вдається розгорнути $(PROTOCOL) у прикладі вище.
Коли змінна середовища невизначена або містить лише деякі змінні, невизначена змінна середовища трактується як звичайний рядок, як у випадку з UNCHANGED_REFERENCE. Зверніть увагу, що неправильно опрацьовані змінні середовища, як правило, не блокують запуск контейнера.
Синтаксис $(VAR_NAME) може бути екранований подвійним $, тобто: $$(VAR_NAME). Екрановані посилання ніколи не розгортаються, незалежно від того, чи визначена посилана змінна, чи ні. Це можна побачити у випадку з ESCAPED_REFERENCE вище.
Що далі
- Дізнайтеся більше про змінні середовища.
- Перегляньте EnvVarSource.
3 - Визначення змінних середовища для контейнера
Ця сторінка показує, як визначити змінні середовища для контейнера у Kubernetes Pod.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Визначення змінної середовища для контейнера
При створенні Pod ви можете задати змінні середовища для контейнерів, які запускаються в Pod. Щоб задати змінні середовища, включіть поле env або envFrom у файлі конфігурації.
Поля env та envFrom мають різний ефект.
env- дозволяє вам задати змінні середовища для контейнера, вказуючи значення безпосередньо для кожної змінної, яку ви називаєте.
envFrom- дозволяє вам задати змінні середовища для контейнера, посилаючись на ConfigMap або Secret. Коли ви використовуєте
envFrom, всі пари ключ-значення у зазначеному ConfigMap або Secret встановлюються як змінні середовища для контейнера. Ви також можете вказати спільний префіксовий рядок.
Докладніше про ConfigMap та Secret.
Ця сторінка пояснює, як використовувати env.
У цьому завданні ви створюєте Pod, який запускає один контейнер. Конфігураційний файл для Pod визначає змінну середовища з імʼям DEMO_GREETING та значенням "Привіт із середовища". Ось маніфест конфігурації для Pod:
apiVersion: v1
kind: Pod
metadata:
name: envar-demo
labels:
purpose: demonstrate-envars
spec:
containers:
- name: envar-demo-container
image: gcr.io/google-samples/hello-app:2.0
env:
- name: DEMO_GREETING
value: "Hello from the environment"
- name: DEMO_FAREWELL
value: "Such a sweet sorrow"
Створіть Pod на основі цього маніфесту:
kubectl apply -f https://k8s.io/examples/pods/inject/envars.yamlПерегляньте перелік запущених Podʼів:
kubectl get pods -l purpose=demonstrate-envarsВивід буде подібний до:
NAME READY STATUS RESTARTS AGE envar-demo 1/1 Running 0 9sПерегляньте змінні середовища контейнера Pod:
kubectl exec envar-demo -- printenvВивід буде подібний до такого:
NODE_VERSION=4.4.2 EXAMPLE_SERVICE_PORT_8080_TCP_ADDR=10.3.245.237 HOSTNAME=envar-demo ... DEMO_GREETING=Привіт із середовища DEMO_FAREWELL=Такий солодкий прощальний слова
Примітка:
Змінні середовища, встановлені за допомогою полівenv або envFrom, перевизначають будь-які змінні середовища, вказані в образі контейнера.Примітка:
Змінні середовища можуть посилатися одна на одну, проте важливий порядок. Змінні, які використовують інші, визначені в тому ж контексті, повинні йти пізніше у списку. Також уникайте циклічних посилань.Використання змінних середовища у вашій конфігурації
Змінні середовища, які ви визначаєте у конфігурації Pod у .spec.containers[*].env[*], можна використовувати в інших частинах конфігурації, наприклад, у командах та аргументах, які ви задаєте для контейнерів Pod. У наступній конфігурації прикладу, змінні середовища GREETING, HONORIFIC та NAME встановлені на Warm greetings to, The Most Honorable та Kubernetes відповідно. Змінна середовища MESSAGE комбінує набір усіх цих змінних середовища, а потім використовує їх як аргумент командного рядка, переданий контейнеру env-print-demo.
Імена змінних середовища можуть складатися з будь-яких друкованих символів ASCII, окрім "=".
apiVersion: v1
kind: Pod
metadata:
name: print-greeting
spec:
containers:
- name: env-print-demo
image: bash
env:
- name: GREETING
value: "Warm greetings to"
- name: HONORIFIC
value: "The Most Honorable"
- name: NAME
value: "Kubernetes"
- name: MESSAGE
value: "$(GREETING) $(HONORIFIC) $(NAME)"
command: ["echo"]
args: ["$(MESSAGE)"]
Після створення команда echo Warm greetings to The Most Honorable Kubernetes виконується в контейнері.
Що далі
- Дізнайтеся більше про змінні середовища.
- Дізнайтеся про використання secret як змінних середовища.
- Дивіться EnvVarSource.
4 - Визначення значень змінних середовища за допомогою контейнера ініціалізації
Kubernetes v1.35 [beta](стандартно увімкнено)Ця сторінка показує, як налаштувати змінні середовища для контейнерів у Pod за допомогою файлу.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Версія вашого Kubernetes сервера має бути не старішою ніж v1.34.
Для перевірки версії введіть kubectl version.
Як працює дизайн
В цьому завданні ви створите Pod, який отримує змінні середовища з файлів, проєцюючи ці значення в запущений контейнер.
apiVersion: v1
kind: Pod
metadata:
name: envfile-test-pod
spec:
initContainers:
- name: setup-envfile
image: nginx
command: ['sh', '-c', "echo \"DB_ADDRESS=\'address\'\nREST_ENDPOINT=\'endpoint\'\" > /data/config.env"]
volumeMounts:
- name: config
mountPath: /data
containers:
- name: use-envfile
image: nginx
command: [ "/bin/sh", "-c", "env" ]
env:
- name: DB_ADDRESS
valueFrom:
fileKeyRef:
path: config.env
volumeName: config
key: DB_ADDRESS
optional: false
restartPolicy: Never
volumes:
- name: config
emptyDir: {}
В маніфесті ви можете побачити, що initContainer монтує том emptyDir і записує змінні середовища у файл всередині нього, а звичайні контейнери посилаються на нього як на файл, так і на ключ змінної середовища через поле fileKeyRef, не потребуючи монтування тому. Коли поле optional встановлено в false, вказаний key у fileKeyRef повинен існувати у файлі змінних середовища.
Том буде змонтовано лише в контейнер, який записує у файл
(initContainer), тоді як контейнер-споживач, який споживає змінну середовища, не матиме змонтованого тому.
Формат файлу env відповідає стандарту файлів env kubernetes.
Під час ініціалізації контейнера kubelet отримує змінні середовища
з вказаних файлів у томі emptyDir і надає їх контейнеру.
Примітка:
Всі типи контейнерів (initContainers, звичайні контейнери, sidecars контейнери та епhemeral контейнери) підтримують завантаження змінних середовища з файлів.
Хоча ці змінні середовища можуть зберігати конфіденційну інформацію, томи emptyDir не забезпечують тих самих механізмів захисту, що й спеціалізовані об'єкти Secret. Тому вважається, що відкриття конфіденційних змінних середовища для контейнерів за допомогою цієї функції не є кращою практикою з точки зору безпеки.
Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/envars-file-container.yaml
Перевірте, чи контейнер у Pod працює:
kubectl get pods
```shell
# Якщо новий Pod ще не справний, повторіть цю команду кілька разів.
kubectl get pods
Перевірте журнали контейнера на наявність змінних середовища:
kubectl logs dapi-test-pod -c use-envfile | grep DB_ADDRESS
Вивід показує значення вибраних змінних середовища:
DB_ADDRESS=address
Синтаксис файлів env
Формат файлу env, який використовує Kubernetes, є чітко визначеним підмножиною семантики змінних середовища для POSIX-сумісного bash. Будь-який файл env, який підтримує Kubernetes, створюватиме ті самі змінні середовища, що й POSIX-сумісний bash. Однак POSIX-сумісний bash підтримує деякі додаткові формати, які Kubernetes не приймає.
Приклад:
MY_VAR='my-literal-value'
Правила
- Оголошення змінної: використовуйте форму
VAR='value'. Пробіли навколо=ігноруються; пробіли на початку рядка ігноруються; порожні рядки ігноруються. - Значення в лапках: значення повинні бути укладені в одинарні лапки (
').- Вміст всередині одинарних лапок зберігається буквально. Не застосовується обробка екрануючих послідовностей, згортання пробілів або інтерпретація символів.
- Нові рядки всередині одинарних лапок зберігаються (підтримуються багаторядкові значення).
- Коментарі: рядки, що починаються з
#, розглядаються як коментарі та ігноруються. Символ#всередині значення в одинарних лапках не є коментарем.
Приклади:
# comment
DB_ADDRESS='address'
MULTI='line1
line2'
Непідтримувані форми
- Значення без лапок заборонені:
VAR=value— не підтримується.
- Значення в подвійних лапках заборонені:
VAR="value"— не підтримується.
- Кілька сусідніх рядків у лапках не підтримуються:
VAR='val1''val2'— не підтримується.
- Будь-яка форма інтерполяції, розширення або конкатенації не підтримується:
VAR='a'$OTHERабоVAR=${OTHER}— не підтримується.
Сувора вимога щодо використання одинарних лапок гарантує, що kubelet сприймає значення буквально під час завантаження змінних середовища з файлів.
Що далі
- Дізнайтеся більше про змінні середовища.
- Ознайомтесь з Оголошенням змінних середовища для контейнера
- Дізнайтеся про Експонування інформації про Pod для контейнерів через змінні середовища
5 - Використання змінних середовища для передачі контейнерам інформації про Pod
Ця сторінка показує, як Pod може використовувати змінні середовища для передачі інформації про себе контейнерам, які працюють в Pod, використовуючи downward API. Ви можете використовувати змінні середовища для експозиції полів Pod, полів контейнера або обох.
У Kubernetes є два способи експозиції полів Pod та контейнера для запущеного контейнера:
- Змінні середовища, як пояснено в цьому завданні
- Файли томів
Разом ці два способи експозиції полів Pod та контейнера називаються downward API.
Оскільки Service є основним засобом взаємодії між контейнеризованими застосунками, якими керує Kubernetes, корисно мати можливість виявляти їх під час виконання.
Дізнайтеся більше про доступ до Сервісів тут.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Використання полів Pod як значень для змінних середовища
У цій частині завдання ви створюєте Pod з одним контейнером, і ви спроєцюєте поля рівня Pod у працюючий контейнер у вигляді змінних середовища.
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-fieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox:1.27.2
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
sleep 10;
done;
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: MY_POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: MY_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: MY_POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
restartPolicy: Never
У цьому маніфесті ви бачите пʼять змінних середовища. Поле env є масивом визначень змінних середовища. Перший елемент у масиві вказує, що змінна середовища MY_NODE_NAME отримує своє значення з поля spec.nodeName Pod. Аналогічно, інші змінні середовища отримують свої назви з полів Pod.
Примітка:
Поля в цьому прикладі є полями Pod. Вони не є полями контейнера в Pod.Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-pod.yaml
Перевірте, що контейнер в Pod працює:
# Якщо новий Pod ще не став доступним, кілька разів перезапустіть цю команду.
kubectl get pods
Перегляньте лог контейнера:
kubectl logs dapi-envars-fieldref
Вивід показує значення вибраних змінних середовища:
minikube
dapi-envars-fieldref
default
172.17.0.4
default
Щоб побачити, чому ці значення є в лозі, подивіться на поля command та args у файлі конфігурації. При запуску контейнера він записує значення пʼяти змінних середовища у stdout. Він повторює це кожні десять секунд.
Далі, отримайте оболонку в контейнер, який працює в вашому Pod:
kubectl exec -it dapi-envars-fieldref -- sh
У вашій оболонці перегляньте змінні середовища:
# Виконайте це в оболонці всередині контейнера
printenv
Вивід показує, що деякі змінні середовища мають призначені значення полів Pod:
MY_POD_SERVICE_ACCOUNT=default
...
MY_POD_NAMESPACE=default
MY_POD_IP=172.17.0.4
...
MY_NODE_NAME=minikube
...
MY_POD_NAME=dapi-envars-fieldref
Використання полів контейнера як значень для змінних середовища
У попередньому завданні ви використовували інформацію з полів рівня Pod як значення для змінних середовища. У наступному завданні ви плануєте передати поля, які є частиною визначення Pod, але взяті з конкретного контейнера замість всього Pod загалом.
Ось маніфест для іншого Pod, який знову має лише один контейнер:
apiVersion: v1
kind: Pod
metadata:
name: dapi-envars-resourcefieldref
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox:1.27.2
command: [ "sh", "-c"]
args:
- while true; do
echo -en '\n';
printenv MY_CPU_REQUEST MY_CPU_LIMIT;
printenv MY_MEM_REQUEST MY_MEM_LIMIT;
sleep 10;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
env:
- name: MY_CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.cpu
- name: MY_CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- name: MY_MEM_REQUEST
valueFrom:
resourceFieldRef:
containerName: test-container
resource: requests.memory
- name: MY_MEM_LIMIT
valueFrom:
resourceFieldRef:
containerName: test-container
resource: limits.memory
restartPolicy: Never
У цьому маніфесті ви бачите чотири змінні середовища. Поле env є масивом визначень змінних середовища. Перший елемент у масиві вказує, що змінна середовища MY_CPU_REQUEST отримує своє значення з поля requests.cpu контейнера з іменем test-container. Аналогічно, інші змінні середовища отримують свої значення з полів, що є специфічними для цього контейнера.
Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-envars-container.yaml
Перевірте, що контейнер в Pod працює:
# Якщо новий Pod ще не став доступним, кілька разів перезапустіть цю команду.
kubectl get pods
Перегляньте лог контейнера:
kubectl logs dapi-envars-resourcefieldref
Вивід показує значення вибраних змінних середовища:
1
1
33554432
67108864
Що далі
- Прочитайте Визначення змінних середовища для контейнера
- Прочитайте API-визначення
specдля Pod. Специфікація включає визначення Контейнера (частина Pod). - Ознайомтесь зі списком доступних полів, які можна викрити за допомогою downward API.
Дізнайтеся про Pod, контейнери та змінні середовища в легасі довідці API:
6 - Передача інформації про Pod контейнерам через файли
Ця сторінка показує, як Pod може використовувати volumeDownwardAPI, щоб передати інформацію про себе контейнерам, які працюють в Pod. volumeDownwardAPI може викривати поля Pod та контейнера.
У Kubernetes є два способи експозиції полів Pod та контейнера для запущеного контейнера:
- Змінні середовища
- Файли томів, як пояснено в цьому завданні
Разом ці два способи експозиції полів Pod та контейнера називаються downward API.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Зберігання полів Pod
У цій частині завдання ви створюєте Pod з одним контейнером, і ви проєцюєте поля рівня Pod у працюючий контейнер як файли. Ось маніфест для Pod:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example
labels:
zone: us-est-coast
cluster: test-cluster1
rack: rack-22
annotations:
build: two
builder: john-doe
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.27.2
command: ["sh", "-c"]
args:
- while true; do
if [[ -e /etc/podinfo/labels ]]; then
echo -en '\n\n'; cat /etc/podinfo/labels; fi;
if [[ -e /etc/podinfo/annotations ]]; then
echo -en '\n\n'; cat /etc/podinfo/annotations; fi;
sleep 5;
done;
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "annotations"
fieldRef:
fieldPath: metadata.annotations
У маніфесті ви бачите, що у Pod є volumeDownwardAPI, і контейнер монтує том за шляхом /etc/podinfo.
Подивіться на масив items під downwardAPI. Кожен елемент масиву визначає volumeDownwardAPI. Перший елемент вказує, що значення поля metadata.labels Pod має бути збережене в файлі з назвою labels. Другий елемент вказує, що значення поля annotations Pod має бути збережене в файлі з назвою annotations.
Примітка:
Поля в цьому прикладі є полями Pod. Вони не є полями контейнера в Pod.Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume.yaml
Перевірте, що контейнер в Pod працює:
kubectl get pods
Перегляньте логи контейнера:
kubectl logs kubernetes-downwardapi-volume-example
Вивід показує вміст файлів labels та annotations:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
build="two"
builder="john-doe"
Отримайте доступ до оболонки в контейнері, який працює в вашому Pod:
kubectl exec -it kubernetes-downwardapi-volume-example -- sh
У вашій оболонці перегляньте файл labels:
/# cat /etc/podinfo/labels
Вивід показує, що всі мітки Pod були записані у файл labels:
cluster="test-cluster1"
rack="rack-22"
zone="us-est-coast"
Аналогічно, перегляньте файл annotations:
/# cat /etc/podinfo/annotations
Перегляньте файли у теці /etc/podinfo:
/# ls -laR /etc/podinfo
У виводі ви побачите, що файли labels та annotations знаходяться в тимчасовій підтеці: у цьому прикладі, ..2982_06_02_21_47_53.299460680. У теці /etc/podinfo, ..data є символічним посиланням на тимчасову підтеку. Також у теці /etc/podinfo, labels та annotations є символічними посиланнями.
drwxr-xr-x ... Feb 6 21:47 ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 ..data -> ..2982_06_02_21_47_53.299460680
lrwxrwxrwx ... Feb 6 21:47 annotations -> ..data/annotations
lrwxrwxrwx ... Feb 6 21:47 labels -> ..data/labels
/etc/..2982_06_02_21_47_53.299460680:
total 8
-rw-r--r-- ... Feb 6 21:47 annotations
-rw-r--r-- ... Feb 6 21:47 labels
Використання символічних посилань дозволяє динамічне атомарне оновлення метаданих; оновлення записуються у новий тимчасову теку, а символічне посилання ..data оновлюється атомарно за допомогою rename(2).
Примітка:
Контейнер, який використовує Downward API як том з subPath монтуванням, не отримає оновлень від Downward API.Вийдіть з оболонки:
/# exit
Зберігання полів контейнера
У попередньому завданні ви зробили поля Pod доступними за допомогою Downward API. У наступній вправі ви передаєте поля, які є частиною визначення Pod, але беруться з конкретного контейнера скоріше, ніж з Pod загалом. Ось маніфест для Pod, що має лише один контейнер:
apiVersion: v1
kind: Pod
metadata:
name: kubernetes-downwardapi-volume-example-2
spec:
containers:
- name: client-container
image: registry.k8s.io/busybox:1.27.2
command: ["sh", "-c"]
args:
- while true; do
echo -en '\n';
if [[ -e /etc/podinfo/cpu_limit ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_limit; fi;
if [[ -e /etc/podinfo/cpu_request ]]; then
echo -en '\n'; cat /etc/podinfo/cpu_request; fi;
if [[ -e /etc/podinfo/mem_limit ]]; then
echo -en '\n'; cat /etc/podinfo/mem_limit; fi;
if [[ -e /etc/podinfo/mem_request ]]; then
echo -en '\n'; cat /etc/podinfo/mem_request; fi;
sleep 5;
done;
resources:
requests:
memory: "32Mi"
cpu: "125m"
limits:
memory: "64Mi"
cpu: "250m"
volumeMounts:
- name: podinfo
mountPath: /etc/podinfo
volumes:
- name: podinfo
downwardAPI:
items:
- path: "cpu_limit"
resourceFieldRef:
containerName: client-container
resource: limits.cpu
divisor: 1m
- path: "cpu_request"
resourceFieldRef:
containerName: client-container
resource: requests.cpu
divisor: 1m
- path: "mem_limit"
resourceFieldRef:
containerName: client-container
resource: limits.memory
divisor: 1Mi
- path: "mem_request"
resourceFieldRef:
containerName: client-container
resource: requests.memory
divisor: 1Mi
У маніфесті ви бачите, що у Pod є volumeDownwardAPI, і що контейнер у цьому Pod монтує том за шляхом /etc/podinfo.
Подивіться на масив items під downwardAPI. Кожен елемент масиву визначає файл у томі downward API.
Перший елемент вказує, що в контейнері з назвою client-container, значення поля limits.cpu у форматі, вказаному як 1m, має бути опубліковане як файл з назвою cpu_limit. Поле divisor є необовʼязковим і має стандартне значення 1. Дільник 1 означає ядра для ресурсів cpu, або байти для ресурсів memory.
Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/dapi-volume-resources.yaml
Отримайте доступ до оболонки в контейнері, який працює в вашому Pod:
kubectl exec -it kubernetes-downwardapi-volume-example-2 -- sh
У вашій оболонці перегляньте файл cpu_limit:
# Виконайте це в оболонці всередині контейнера
cat /etc/podinfo/cpu_limit
Ви можете використовувати подібні команди, щоб переглянути файли cpu_request, mem_limit та mem_request.
Проєцювання ключів на конкретні шляхи та дозволи на файли
Ви можете проєціювати ключі на конкретні шляхи та конкретні дозволи на файл на основі файлу. Для отримання додаткової інформації дивіться Secret.
Що далі
- Прочитайте
specAPI-визначення для Pod. Специфікація включає визначення Контейнера (частина Pod). - Прочитайте список доступних полів, які ви можете викрити за допомогою downward API.
Дізнайтеся про томи в легасі довідці API:
- Перегляньте
VolumeAPI-визначення, яке визначає загальний том у Pod для доступу контейнерів. - Перегляньте
DownwardAPIVolumeSourceAPI-визначення, яке визначає том, який містить інформацію Downward API. - Перегляньте
DownwardAPIVolumeFileAPI-визначення, яке містить посилання на обʼєкт або поля ресурсу для заповнення файлу у томі Downward API. - Перегляньте
ResourceFieldSelectorAPI-визначення, яке вказує ресурси контейнера та їх формат виведення.
7 - Розповсюдження облікових даних з використанням Secret
Ця сторінка показує, як безпечно передати чутливі дані, такі як паролі та ключі шифрування, у Podʼи.
Перш ніж ви розпочнете
Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:
Перетворення ваших секретних даних у base64
Припустимо, ви хочете мати дві частини секретних даних: імʼя користувача my-app та пароль 39528$vdg7Jb. Спочатку використайте інструмент кодування base64, щоб перетворити ваше імʼя користувача та пароль на base64. Ось приклад використання загальнодоступної програми base64:
echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64
Вивід показує, що base64 варіант вашого імені користувача — bXktYXBw, а base64 вашого пароля — Mzk1MjgkdmRnN0pi.
Увага:
Використовуйте локальний інструмент, якому довіряє ваша ОС, щоб зменшити ризики безпеки зовнішніх інструментів.Створіть Secret
Ось файл конфігурації, який ви можете використати для створення Secret, що містить ваше імʼя користувача та пароль:
apiVersion: v1
kind: Secret
metadata:
name: test-secret
data:
username: bXktYXBw
password: Mzk1MjgkdmRnN0pi
Створіть Secret
kubectl apply -f https://k8s.io/examples/pods/inject/secret.yamlПерегляньте інформацію про Secret:
kubectl get secret test-secretВивід:
NAME TYPE DATA AGE test-secret Opaque 2 1mПерегляньте більш детальну інформацію про Secret:
kubectl describe secret test-secretВивід:
Name: test-secret Namespace: default Labels: <none> Annotations: <none> Type: Opaque Data ==== password: 13 bytes username: 7 bytes
Створіть Secret безпосередньо за допомогою kubectl
Якщо ви хочете пропустити крок кодування Base64, ви можете створити такий самий Secret, використовуючи команду kubectl create secret. Наприклад:
kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'
Це зручніше. Детальний підхід, показаний раніше, розглядає кожен крок явно, щоб продемонструвати, що відбувається.
Створіть Pod, який має доступ до секретних даних через Том
Ось файл конфігурації, який ви можете використати для створення Podʼа:
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: nginx
volumeMounts:
# ім'я повинно відповідати імені тома нижче
- name: secret-volume
mountPath: /etc/secret-volume
readOnly: true
# Дані секрету доступні контейнерам у Podʼі через том.
volumes:
- name: secret-volume
secret:
secretName: test-secret
Створіть Pod:
kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yamlПеревірте, що ваш Pod працює:
kubectl get pod secret-test-podВивід:
NAME READY STATUS RESTARTS AGE secret-test-pod 1/1 Running 0 42mОтримайте доступ до оболонки в контейнері, що працює у вашому Podʼі:
kubectl exec -i -t secret-test-pod -- /bin/bashСекретні дані доступні контейнеру через Том, змонтований у
/etc/secret-volume.У вашій оболонці перегляньте файли у теці
/etc/secret-volume:# Виконайте це в оболонці всередині контейнера ls /etc/secret-volumeВивід показує два файли, один для кожної частини секретних даних:
password usernameУ вашій оболонці gthtukzymnt вміст файлів
usernameтаpassword:# Виконайте це в оболонці всередині контейнера echo "$( cat /etc/secret-volume/username )" echo "$( cat /etc/secret-volume/password )"Вивід — ваше імʼя користувача та пароль:
my-app 39528$vdg7Jb
Змініть ваш образ або командний рядок так, щоб програма шукала файли у теці mountPath. Кожен ключ у масиві data Secretʼу стає імʼям файлу у цій теці.
Спроєцюйте ключі Secret на конкретні шляхи файлів
Ви також можете контролювати шляхи в томі, куди проєцюються ключі Secret. Використовуйте поле .spec.volumes[].secret.items, щоб змінити шлях для кожного ключа:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
При розгортанні цього Podʼа відбувається наступне:
- Ключ
usernameзmysecretдоступний контейнеру за шляхом/etc/foo/my-group/my-usernameзамість/etc/foo/username. - Ключ
passwordз цього Secret не проєцюється.
Якщо ви отримуєте перелік ключів явно за допомогою .spec.volumes[].secret.items, розгляньте наступне:
- Проєцюються тільки ключі, вказані у
items. - Щоб використовувати всі ключі з Secret, всі вони повинні бути перераховані у полі
items. - Усі перераховані ключі повинні існувати у відповідному Secret. Інакше Том не створюється.
Встановіть POSIX-права доступу до ключів Secret
Ви можете встановити POSIX права доступу до файлів для окремого ключа Secret. Якщо ви не вказали жодних дозволів, стандартно використовується 0644. Ви також можете встановити стандартно режим файлу POSIX для всього тому Secret, і ви можете перевизначити його за потреби для кожного ключа.
Наприклад, ви можете вказати режим стандартно так:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 0400
Секрет Secret у /etc/foo; всі файли, створені томом секрету, мають дозволи 0400.
Примітка:
Якщо ви визначаєте Pod або шаблон Podʼа за допомогою JSON, зверніть увагу, що специфікація JSON не підтримує вісімкові літерали для чисел, оскільки JSON розглядає0400 як десяткове значення 400. У JSON використовуйте десяткові значення для defaultMode. Якщо ви пишете YAML, ви можете написати defaultMode в вісімковій системі числення.Визначте змінні середовища контейнера, використовуючи дані з Secret
Ви можете використовувати дані у Secret як змінні середовища у ваших контейнерах.
Якщо контейнер вже використовує Secret у змінній середовища, оновлення Secret не буде видно контейнеру, якщо він не буде перезапущений. Існують сторонні рішення для виклику перезавантажень, коли змінюються Secret.
Визначення змінної середовища контейнера з даними з одного Secret
Визначте змінну середовища як пару ключ-значення в Secret:
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'Призначте значення
backend-username, визначене у Secret, змінній середовищаSECRET_USERNAMEу специфікації Podʼа.apiVersion: v1 kind: Pod metadata: name: env-single-secret spec: containers: - name: envars-test-container image: nginx env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: backend-user key: backend-usernameСтворіть Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yamlУ вашій оболонці покажіть вміст змінної середовища контейнера
SECRET_USERNAME.kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'Вивід схожий на:
backend-admin
Визначення змінних середовища контейнера з даними з декількох Secret
Як і у попередньому прикладі, спочатку створіть Secretʼи.
kubectl create secret generic backend-user --from-literal=backend-username='backend-admin' kubectl create secret generic db-user --from-literal=db-username='db-admin'Визначте змінні середовища у специфікації Podʼа.
apiVersion: v1 kind: Pod metadata: name: envvars-multiple-secrets spec: containers: - name: envars-test-container image: nginx env: - name: BACKEND_USERNAME valueFrom: secretKeyRef: name: backend-user key: backend-username - name: DB_USERNAME valueFrom: secretKeyRef: name: db-user key: db-usernameСтворіть Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yamlУ вашій оболонці покажіть змінні середовища контейнера.
kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'Вивід схожий на:
DB_USERNAME=db-admin BACKEND_USERNAME=backend-admin
налаштування всіх пар ключ-значення в Secret як змінних середовища контейнера
Примітка:
Ця функціональність доступна у Kubernetes v1.6 та пізніше.Створіть Secret, що містить декілька пар ключ-значення
kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'Використовуйте
envFrom, щоб визначити всі дані Secret як змінні середовища контейнера. Ключ з Secret стає імʼям змінної середовища у Pod.apiVersion: v1 kind: Pod metadata: name: envfrom-secret spec: containers: - name: envars-test-container image: nginx envFrom: - secretRef: name: test-secretСтворіть Pod:
kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yamlУ вашій оболонці покажіть змінні середовища контейнера
usernameтаpassword.kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'Вивід схожий на:
username: my-app password: 39528$vdg7Jb
Приклад: Надавання операційних/тестових облікових даних Podʼам за допомогою Secret
У цьому прикладі показано Pod, який використовує Secret, що містить облікові дані операційного середовища, і ще один Pod, який використовує Secret з обліковими даними тестового середовища.
Створіть Secret для облікових даних операційного середовища:
kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11Вивід схожий на:
secret "prod-db-secret" createdСтворіть Secret для облікових даних тестового середовища.
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtestsВивід схожий на:
secret "test-db-secret" createdПримітка:
Спеціальні символи, такі як
$,\,*,=, та!, будуть інтерпретовані вашою оболонкою і вимагатимуть екранування.У більшості оболонок найпростіший спосіб екранування пароля полягає в обрамленні його одинарними лапками (
'). Наприклад, якщо ваш фактичний пароль —S!B\*d$zDsb=, ви повинні виконати команду наступним чином:kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='Вам не потрібно екранувати спеціальні символи у паролях з файлів (
--from-file).Створіть маніфести Podʼів:
cat <<EOF > pod.yaml apiVersion: v1 kind: List items: - kind: Pod apiVersion: v1 metadata: name: prod-db-pod spec: containers: - name: prod-db-container image: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: prod-db-secret key: password - name: MYSQL_DATABASE value: mydatabase - name: MYSQL_USER valueFrom: secretKeyRef: name: prod-db-secret key: username - kind: Pod apiVersion: v1 metadata: name: test-db-pod spec: containers: - name: test-db-container image: mysql env: - name: MYSQL_ROOT_PASSWORD valueFrom: secretKeyRef: name: test-db-secret key: password - name: MYSQL_DATABASE value: mydatabase - name: MYSQL_USER valueFrom: secretKeyRef: name: test-db-secret key: username EOFПримітка:
Специфікації для двох Podʼів відрізняються лише в одному полі; це сприяє створенню Podʼів з різними можливостями на основі загального шаблону Podʼа.Застосуйте всі ці обʼєкти на сервер API, виконавши:
kubectl create -f pod.yaml
Обидва контейнери матимуть у своїх файлових системах наступні файли зі значеннями для кожного середовища контейнера:
/etc/secret-volume/username
/etc/secret-volume/password
Ви також можете подальшим спрощенням базової специфікації Podʼа використовуючи два службові облікові записи:
prod-userзprod-db-secrettest-userзtest-db-secret
Специфікація Podʼа скорочується до:
apiVersion: v1
kind: Pod
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
serviceAccount: prod-db-client
containers:
- name: db-client-container
image: myClientImage