Розповсюдження облікових даних з використанням 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-secret
test-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