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