Знакомство с Kubernetes. Часть 14: Секреты (Secrets)
Aug 27, 2018 06:06 · 624 words · 3 minute read
В кластере Kubernetes
объекты типа секрет (secret
) предназначены для хранения конфиденциальной информации, такой как пароли, OAuth-токены или ssh-ключи. Давайте разберемся!
Представление конфиденциальной информации в виде секрета является более безопасным и гибким, чем добавление такой информации в открытом виде при описании контейнера или сборке docker-образа.
Объекты типа секрет могут быть созданы как пользователем, так и системой. Для использования секрета, под (pod
) должен на него ссылаться - чаще всего как на файл, находящийся на примонтированном томе. Кроме того, kubelet
может использовать секреты при скачивании docker-образов из реджистри.
Kubernetes
автоматически создает необходимые ему секреты, которые содержат учетные данные для доступа к API, и автоматически модифицирует созданные поды для использования этого секрета.
Объекты типа секрет могут быть созданы с помощью команды kubectl create secret
. Рассмотрим пример - допустим, для подключения к БД из пода необходимы логин и пароль, которые находятся в отдельных файлах:
echo -n 'admin' > ./username.txt
echo -n 'B7wItYlHeRR1' > ./password.txt
C помощью данной команды можно преобразовать эти два файла в объект типа секрет:
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
Убедиться, что секрет успешно создан можно так:
kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 51s
kubectl describe secrets/db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: 12 bytes
username.txt: 5 bytes
Стоит отметить, что ни get
, ни describe
не отобразят содержимое данного секрета на экране пользователя - это сделано из соображений безопасности.
Еще один вариант создания секрета - сначала описать его в формате yaml (или json), и только после этого создать секрет. Для этого, каждое используемое значение должно быть закодировано в base64:
echo -n 'admin' | base64
YWRtaW4=
echo -n 'B7wItYlHeRR1' | base64
Qjd3SXRZbEhlUlIx
Создаем yaml-файл со следующим содержимым:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: Qjd3SXRZbEhlUlIx
Здесь поле data
это map, ключи которого могут содержать буквенно-цифровые последовательности и символы -
, _
и .
, а значения - необходимые данные, закодированные в base64.
Теперь можно создать секрет с использованием команды kubectl create
:
kubectl create -f ./secret.yaml
secret "mysecret" created
Получим информацию о только что созданном секрете с помощью kubectl get secret
(вывод сокращен):
kubectl get secret mysecret -o yaml
apiVersion: v1
data:
username: YWRtaW4=
password: Qjd3SXRZbEhlUlIx
kind: Secret
metadata:
...
type: Opaque
Раскодировать значение из секрета можно, например, так:
echo 'Qjd3SXRZbEhlUlIx' | base64 --decode
B7wItYlHeRR1
Секреты могут быть смонтированы как тома данных или определены в качестве переменных окружения для использования в подах. Пример:
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
Если в поде существует несколько контейнеров, которые должны использовать данный секрет, то секцию volumeMounts:
следует добавить в описание каждого из них. Есть возможность указания конкретного пути монтирования внутрь контейнера значения отдельного ключа из секрета:
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
В этом примере значение username
будет доступно по пути /etc/foo/my-group/my-username
вместо /etc/foo/username
, а password
доступен не будет.
Примечание. Можно задавать права доступа к объектам типа секрет (и даже к отдельным ключам).
Использование секретов как переменных окружения в описании подов выглядит так:
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
restartPolicy: Never
После запуска пода в контейнере с именем mycontainer
проверим переменные окружения:
echo $SECRET_USERNAME
admin
echo $SECRET_PASSWORD
B7wItYlHeRR1
Еще один частный случай использования секретов - параметр imagePullSecrets
, который содержит пароль для доступа к docker-реджистри. Подробнее о нем можно почитать здесь или здесь.
Больше информации о работе с секретами можно найти в официальной документации.