【问题标题】:Use Kubernetes secrets as environment variables inside a config map在配置映射中使用 Kubernetes 机密作为环境变量
【发布时间】:2020-03-23 17:51:42
【问题描述】:

我在容器中有一个应用程序,它从 configMap 读取某些数据,如下所示

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.yaml: |
        server:
          port: 8080
          host: 0.0.0.0

        ##
        ## UCP configuration.
        ## If skipped, it will default to looking inside of the connections.xml file.
        database:
            ApplicationDB:
                username: username
                password: hello123

现在我为密码创建了一个秘密,并在启动容器时安装为 env 变量。

apiVersion: v1
kind: Secret
metadata:
  name: appdbpassword
type: Opaque
stringData:
  password: hello123

我的 pod 看起来像:

apiVersion: v1
kind: Pod
metadata:
  name: {{ .Values.pod.name }}
spec:
  containers:
    - name: {{ .Values.container.name }}
      image: {{ .Values.image }}
      command: [ "/bin/sh", "-c", "--" ]
      args: [ "while true; do sleep 30; done;"]
      env:
      - name: password
        valueFrom:
          secretKeyRef:
            name: appdbpassword
            key: password
      volumeMounts:
      - name: config-volume
        mountPath: /app/app-config/application.yaml
        subPath: application.yaml
  volumes:
    - name: config-volume
      configMap:
        name: app-config

我尝试在 configMap 中使用这个环境变量:

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application.yaml: |
        server:
          port: 8080
          host: 0.0.0.0

        ##
        ## UCP configuration.
        ## If skipped, it will default to looking inside of the connections.xml file.
        database:
            ApplicationDB:
                username: username
                **password: ${password}**

但我的应用程序无法读取此密码。我在这里错过了什么吗?

编辑:

我无法将 application.yaml 更改为任何其他形式,因为我的服务器在源路径中查找 application.yaml。我们有什么方法可以在 values.yaml(helm) 文件中使用该环境变量并在 configmap 中使用它吗?

【问题讨论】:

  • 你不能在 in 配置映射中使用秘密
  • @Jonas 我的用例有什么替代方案吗?
  • 这是一个 Spring Boot 应用程序吗?
  • 您的 k8s 密钥中的密钥 password 的值必须通过 Base64 编码。 configmap 只是生成一个文件,它不支持环境变量。

标签: kubernetes kubernetes-helm kubernetes-pod kubernetes-secrets


【解决方案1】:

您的 ${password} 变量不会被其值替换,因为 application.yaml 是一个静态文件。如果您在某些配置中使用此 yaml 文件,则它可能会被其值替换。

考虑一个场景,而不是 application.yaml 传递这个文件

application.sh: |
       echo "${password}"

现在进入 /app/app-config 你会看到 application.sh 文件。现在做sh application.sh 你会看到环境变量的值。

我希望这可以澄清你的观点。

【讨论】:

  • 我无法将 application.yaml 更改为任何其他形式,因为我的服务器在源路径中查找 application.yaml。我们有没有办法在 values.yaml 文件中使用该变量并在 configmap 中使用它?
  • 你可以从 application.yaml 文件中创建一个 secret。然后将这个 secret 挂载到 /app/app-config/application.yaml 文件中
  • 或使用sed,envsubst 之类的工具将 env var 替换为各自的值。在容器的 postStart 中添加这些命令。
  • 你所做的很奇怪,很麻烦。将密码从秘密传递到 configmap 与将其直接放入 configMap 相同。如果您的服务器正在查找该格式的 yaml 文件,那么您的服务器已经配置错误。重新开始,把事情做好。这将花费您更少的时间。
【解决方案2】:

您不能在 ConfigMap 中使用机密,因为它们旨在用于非敏感数据 (See here)。

另外,您不应该使用env's 传递Secrets,因为它会产生潜在风险(阅读更多here 为什么env 不应该 用过的)。 应用程序通常会在错误报告中转储 env 变量,甚至将 启动时的应用程序日志,这可能导致暴露Secrets

最好的方法是将Secret 挂载为文件。 这是一个简单的示例,如何将其挂载为文件:

spec:
  template:
    spec:
      containers:
      - image: "my-image:latest"
        name: my-app
        ...
        volumeMounts:
          - mountPath: "/var/my-app"
            name: ssh-key
            readOnly: true
      volumes:
        - name: ssh-key
          secret:
            secretName: ssh-key

Kubernetes documentation 很好地解释了如何使用和挂载 Secret。

【讨论】:

    猜你喜欢
    • 2019-07-04
    • 2020-10-05
    • 1970-01-01
    • 2021-08-24
    • 1970-01-01
    • 1970-01-01
    • 2023-01-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多