У меня AKV интегрирован с AKS с помощью драйвера CSI (документация).
Я могу получить к ним доступ в Pod, выполнив что-то вроде:
## show secrets held in secrets-store
kubectl exec busybox-secrets-store-inline -- ls /mnt/secrets-store/
## print a test secret 'ExampleSecret' held in secrets-store
kubectl exec busybox-secrets-store-inline -- cat /mnt/secrets-store/ExampleSecret
У меня он работает с моим развертыванием PostgreSQL, делая следующее:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment-prod
namespace: prod
spec:
replicas: 1
selector:
matchLabels:
component: postgres
template:
metadata:
labels:
component: postgres
aadpodidbinding: aks-akv-identity
spec:
containers:
- name: postgres
image: postgres:13-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB_FILE
value: /mnt/secrets-store/PG-DATABASE
- name: POSTGRES_USER_FILE
value: /mnt/secrets-store/PG-USER
- name: POSTGRES_PASSWORD_FILE
value: /mnt/secrets-store/PG-PASSWORD
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
- name: PGDATA
value: /var/postgresql/data
volumeMounts:
- name: postgres-storage-prod
mountPath: /var/postgresql
- name: secrets-store01-inline
mountPath: /mnt/secrets-store
readOnly: true
volumes:
- name: postgres-storage-prod
persistentVolumeClaim:
claimName: postgres-storage-prod
- name: file-storage-prod
persistentVolumeClaim:
claimName: file-storage-prod
- name: secrets-store01-inline
csi:
driver: secrets-store.csi.k8s.io
readOnly: true
volumeAttributes:
secretProviderClass: aks-akv-secret-provider
---
apiVersion: v1
kind: Service
metadata:
name: postgres-cluster-ip-service-prod
namespace: prod
spec:
type: ClusterIP
selector:
component: postgres
ports:
- port: 5432
targetPort: 5432
Который отлично работает.
Я понял, что все, что мне нужно сделать, это поменять местами такие вещи, как следующие:
- name: PGPASSWORD
valueFrom:
secretKeyRef:
name: app-prod-secrets
key: PGPASSWORD
За:
- name: POSTGRES_PASSWORD
value: /mnt/secrets-store/PG-PASSWORD
# or
- name: POSTGRES_PASSWORD_FILE
value: /mnt/secrets-store/PG-PASSWORD
И я был бы золотым, но это не так.
В модулях он считывает значение как строку, что смущает меня в двух вещах:
env:
, не превращая в секреты и не используя secretKeyRef
?Драйвер CSI внедряет секреты в модуль, помещая их в виде файлов в файловую систему. Будет один файл на секрет, где
CSI не создает переменные среды секретов. Рекомендуемый способ добавления секретов в качестве переменных среды — позволить CSI создать секрет Kubernetes, а затем использовать нативную конструкцию secretKeyRef
.
Почему это работает, например, для развертывания PostgreSQL, но не для моего API Django?
В приложении Django API вы устанавливаете переменную среды POSTGRES_PASSWORD
к значению /mnt/secrets-store/PG-PASSWORD
. то есть вы просто говорите, что некая переменная должна содержать определенное значение, не более того. Таким образом, переменная может содержать шаблон, а не само секретное значение.
То же самое верно и для развертывания Postgres, это просто путь в переменной среды. Разница заключается в том, как развертывание Postgres интерпретирует значение. Когда используются переменные среды, оканчивающиеся на _FILE
, Postgres не ожидает, что сама переменная среды будет содержать секрет, а скорее путь к файлу, который содержит. Из документы образа Postgres:
As an alternative to passing sensitive information via environment variables, _FILE may be appended to some of the previously listed environment variables, causing the initialization script to load the values for those variables from files present in the container. In particular, this can be used to load passwords from Docker secrets stored in /run/secrets/<secret_name> files. For example:
$ docker run --name some-postgres -e POSTGRES_PASSWORD_FILE=/run/secrets/postgres-passwd -d postgres
Currently, this is only supported for POSTGRES_INITDB_ARGS, POSTGRES_PASSWORD, POSTGRES_USER, and POSTGRES_DB.
Есть ли способ добавить их в env: не превращая их в секреты и используя secretKeyRef? Нет, не из коробки. Что вы могли бы сделать, так это иметь сценарий точки входа в вашем изображении, который читает все файлы в вашей секретной папке и устанавливает их как переменные среды (имена переменных являются именами файлов, а значение - содержимым файла) перед запуском основного приложения . Таким образом, приложение может получить доступ к секретам как к переменным среды.