使用 CSI 驱动程序将 AKV 与 AKS 集成后,从 /mnt/secrets-store/ 中读取值

Reading in values from /mnt/secrets-store/ after integration AKV with AKS using CSI Driver

我使用 CSI 驱动程序 (documentation) 将 AKV 与 AKS 集成。

我可以通过执行以下操作在 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

我会很高兴,但事实并非如此。

在 Pods 中,它以字符串形式读取值,这让我对两件事感到困惑:

  1. 为什么这适用于 PostgreSQL 部署而不适用于我的 Django API,例如?
  2. 有没有一种方法可以将它们添加到 env: 中,而不用将它们保密并使用 secretKeyRef

CSI 驱动程序通过将机密作为文件放置在文件系统上,将机密注入 pod。每个秘密将有一个文件,其中

  • 文件名是秘密的名称(或秘密提供者中指定的别名class)
  • 文件的内容就是秘密的值。

CSI 不创建机密的环境变量。将 secret 添加为环境变量的推荐方法是让 CSI 创建一个 Kubernetes secret,然后使用本机 secretKeyRef 构造

为什么这适用于 PostgreSQL 部署而不适用于我的 Django API,例如?

在你的 Django API 应用程序中你设置了一个环境变量 POSTGRES_PASSWORD 到值 /mnt/secrets-store/PG-PASSWORD。也就是说,您只是说某个变量应该包含某个值,仅此而已。因此变量将包含 pat,而不是秘密值本身。

对于 Postgres 部署也是如此,它只是环境变量中的一个路径。不同之处在于 Postgres 部署如何解释该值。当使用以 _FILE 结尾的环境变量时,Postgres 不希望环境变量本身包含秘密,而是希望文件路径包含秘密。来自 the docs of the Postgres image:

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? 不,不是开箱即用的。你可以做的是在你的图像中有一个入口点脚本,它在启动主应用程序之前读取你的秘密文件夹中的所有文件并将它们设置为环境变量(变量的名称是文件名和文件内容的值) .这样应用程序就可以将机密作为环境变量访问。