kubernetes 部署将 secret 挂载为文件夹而不是文件

kubernetes deployment mounts secret as a folder instead of a file

我在 kubernetes 中有一个配置文件作为秘密,我想将它安装到容器内的特定位置。问题是在容器内创建的卷是一个文件夹,而不是一个包含机密内容的文件。有什么办法可以解决吗? 我的部署如下所示:

kind: Deployment
apiVersion: apps/v1
metadata:
  name: jetty
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: jetty
  template:
    metadata:
      labels:
        app: jetty
    spec:
      containers:
        - name: jetty
          image: quay.io/user/jetty
          ports:
            - containerPort: 8080
          volumeMounts:
          - name: config-properties
            mountPath: "/opt/jetty/config.properties"
            subPath: config.properties
          - name: secrets-properties
            mountPath: "/opt/jetty/secrets.properties"
          - name: doc-path
            mountPath: /mnt/storage/
          resources:
            limits:
              cpu: '1000m'
              memory: '3000Mi'
            requests:
              cpu: '750m'
              memory: '2500Mi'
      volumes:
      - name: config-properties
        configMap:
          name: jetty-config-properties
      - name: secrets-properties
        secret: 
          secretName: jetty-secrets
      - name: doc-path
        persistentVolumeClaim:
          claimName: jetty-docs-pvc
      imagePullSecrets:
      - name: rcc-quay

Secrets 与 ConfigMaps

Secrets 让您存储和管理敏感信息(例如密码、私钥),ConfigMaps 用于非敏感配置数据。
正如您在 Secrets and ConfigMaps 文档中所见:

A Secret is an object that contains a small amount of sensitive data such as a password, a token, or a key.

A ConfigMap allows you to decouple environment-specific configuration from your container images, so that your applications are easily portable.

将 Secret 安装为文件

可以创建 Secret 并将其作为 文件 或多个 文件 传递给 Pods .
我已经为您创建了一个简单的示例来说明它是如何工作的。 您可以在下面看到示例 Secret 清单文件和使用此 Secret 的 Deployment
注意: 我将 subPathSecrets 一起使用,它按预期工作。

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
data:
  secret.file1: |
    c2VjcmV0RmlsZTEK
  secret.file2: |
    c2VjcmV0RmlsZTIK
---
apiVersion: apps/v1
kind: Deployment
metadata:
...
    spec:
      containers:
      - image: nginx
        name: nginx
        volumeMounts:
        - name: secrets-files
          mountPath: "/mnt/secret.file1"  # "secret.file1" file will be created in "/mnt" directory
          subPath: secret.file1
        - name: secrets-files
          mountPath: "/mnt/secret.file2"  # "secret.file2" file will be created in "/mnt" directory
          subPath: secret.file2
      volumes:
        - name: secrets-files
          secret:
            secretName: my-secret # name of the Secret
            

注意: Secret应该在Deployment之前创建。

创建SecretDeployment后,我们可以看看它是如何工作的:

$ kubectl get secret,deploy,pod
NAME                         TYPE                                  DATA   AGE
secret/my-secret             Opaque                                2      76s

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   1/1     1            1           76s

NAME                         READY   STATUS    RESTARTS   AGE
pod/nginx-7c67965687-ph7b8   1/1     Running   0          76s

$ kubectl exec nginx-7c67965687-ph7b8 -- ls /mnt
secret.file1
secret.file2
$ kubectl exec nginx-7c67965687-ph7b8 -- cat /mnt/secret.file1
secretFile1
$ kubectl exec nginx-7c67965687-ph7b8 -- cat /mnt/secret.file2
secretFile2

预计成交量

我认为实现目标的更好方法是使用 projected volume

A projected volume maps several existing volume sources into the same directory.

Projected Volume documentation 中,您可以找到详细的解释,但我另外创建了一个示例,可以帮助您了解其工作原理。 使用投影卷,我将 secret.file1Secretsecret.file2ConfigMapconfig.file1 作为文件安装到 Pod.

---
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
data:
  secret.file1: |
    c2VjcmV0RmlsZTEK
  secret.file2: |
    c2VjcmV0RmlsZTIK
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
data:
  config.file1: |
    configFile1  
---
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: all-in-one
      mountPath: "/config-volume"
      readOnly: true
  volumes:
  - name: all-in-one
    projected:
      sources:
      - secret:
          name: my-secret
          items:
            - key: secret.file1
              path: secret-dir1/secret.file1
            - key: secret.file2
              path: secret-dir2/secret.file2
      - configMap:
          name: my-config
          items:
            - key: config.file1
              path: config-dir1/config.file1

我们可以检查它是如何工作的:

$ kubectl exec nginx -- ls /config-volume
config-dir1
secret-dir1
secret-dir2    
$ kubectl exec nginx -- cat /config-volume/config-dir1/config.file1
configFile1
$ kubectl exec nginx -- cat /config-volume/secret-dir1/secret.file1
secretFile1
$ kubectl exec nginx -- cat /config-volume/secret-dir2/secret.file2
secretFile2

如果此回复没有回答您的问题,请提供更多关于您的 Secret 以及您想要实现的目标的详细信息。