0

我正在研究一个完全独立的问题,然后遇到了这个问题,这引起了一些担忧:

https://stackoverflow.com/a/50510753/3123109

我正在做一些非常相似的事情。我正在使用 Azure 的CSI 驱动程序将 Azure Kubernetes 服务与 Azure Key Vault 集成。我的集成清单类似于:

apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentity
metadata:
  name: aks-akv-identity
  namespace: prod
spec:
  type: 0                                 
  resourceID: $identityResourceId
  clientID: $identityClientId
---
apiVersion: aadpodidentity.k8s.io/v1
kind: AzureIdentityBinding
metadata:
  name: aks-akv-identity-binding
  namespace: prod
spec:
  azureIdentity: aks-akv-identity
  selector: aks-akv-identity-binding-selector
apiVersion: secrets-store.csi.x-k8s.io/v1alpha1
kind: SecretProviderClass
metadata:
  name: aks-akv-secret-provider
  namespace: prod
spec:
  provider: azure
  secretObjects:
  - secretName: ${resourcePrefix}-prod-secrets
    type: Opaque
    data:
    - objectName: PROD-PGDATABASE
      key: PGDATABASE
    - objectName: PROD-PGHOST
      key: PGHOST
    - objectName: PROD-PGPORT
      key: PGPORT
    - objectName: PROD-PGUSER
      key: PGUSER
    - objectName: PROD-PGPASSWORD
      key: PGPASSWORD
  parameters:
    usePodIdentity: "true"                                        
    keyvaultName: ${resourceGroupName}akv
    cloudName: ""                               
    objects: |
      array:
            objectName: PROD-PGDATABASE             
            objectType: secret                 
            objectVersion: ""
        - |
            objectName: PROD-PGHOST             
            objectType: secret                 
            objectVersion: ""
        - |
            objectName: PROD-PGPORT             
            objectType: secret                 
            objectVersion: ""
        - |
            objectName: PROD-PGUSER             
            objectType: secret                 
            objectVersion: ""
        - |
            objectName: PROD-PGPASSWORD             
            objectType: secret                 
            objectVersion: ""
    tenantId: $tenantId

然后在微服务清单中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-deployment-prod
  namespace: prod
spec:
  replicas: 3
  selector:
    matchLabels:
      component: api
  template:
    metadata:
      labels:
        component: api
        aadpodidbinding: aks-akv-identity-binding-selector
    spec:
      containers:
        - name: api
          image: appacr.azurecr.io/app-api
          ports:
            - containerPort: 5000
          env:
            - name: PGDATABASE
              valueFrom:
                secretKeyRef:
                  name: app-prod-secrets
                  key: PGDATABASE
            - name: PGHOST
              value: postgres-cluster-ip-service-prod
            - name: PGPORT
              valueFrom:
                secretKeyRef:
                  name: app-prod-secrets
                  key: PGPORT
            - name: PGUSER
              valueFrom:
                secretKeyRef:
                  name: app-prod-secrets
                  key: PGUSER
            - name: PGPASSWORD
              valueFrom:
                secretKeyRef:
                  name: app-prod-secrets
                  key: PGPASSWORD
          volumeMounts:
            - name: secrets-store01-inline
              mountPath: /mnt/secrets-store
              readOnly: true
      volumes:
        - 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: api-cluster-ip-service-prod
  namespace: prod
spec:
  type: ClusterIP
  selector:
    component: api
  ports:
    - port: 5000
      targetPort: 5000

然后在我的应用程序中settings.py

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': os.environ['PGDATABASE'],
        'USER': os.environ['PGUSER'],
        'PASSWORD': os.environ['PGPASSWORD'],
        'HOST': os.environ['PGHOST'],
        'PORT': os.environ['PGPORT'],
    }
}

在我的文章中没有Dockerfile提到任何这些变量,只是 Django 微服务代码。

根据链接,其中一条评论是:

当前的最佳实践建议不要完全这样做。通过 docker 中的环境变量管理的机密很容易查看,不应被视为安全。

所以我第二次猜测这种方法。

我需要考虑修改我在这里的内容吗?

链接中的建议是os.environ[]调用从密钥库中提取凭据的方法...但是甚至访问密钥库的凭据也需要存储在机密中...所以我不是看看有什么不同。


注意:我注意到的一件事是使用env:和安装秘密到卷是多余的。后者是根据有关集成的文档完成的,但它使秘密可用,/mnt/secrets-store因此您可以执行类似cat /mnt/secrets-store/PROD-PGUSER. os.environ[]不是真的有必要,env:我不认为因为你可以从 Pod 中的那个位置提取秘密。

至少执行以下操作会打印出秘密值:

kubectl exec -it $(kubectl get pods -l component=api -o custom-columns=:metadata.name -n prod) -n prod -- cat /mnt/secrets-store/PROD-PGUSER
4

1 回答 1

2

对您链接的答案的评论不正确。我留下了一张便条来解释这种混乱。你所拥有的一切都很好,如果可能过度构建:) 与直接使用 Kubernetes Secrets 相比,你实际上并没有获得任何安全性,但如果你更喜欢围绕 AKV 的工作流程,那么这看起来很好。你可能想看看外部秘密而不是 CSI 东西的这个奇怪的侧面特征?CSI 驱动程序更多地用于将内容公开为文件而不是 external->Secret->envvar。

于 2021-07-29T21:55:36.103 回答