从Kubernetes密钥导入数据到配置映射

31

我正在使用一个 Kubernetes ConfigMap,其中包含应用程序的数据库配置,并且有一个秘密,其中包含数据库密码。 我需要在 ConfigMap 中使用此秘密,以便在尝试添加环境变量到 ConfigMap 并从秘密中在 pod 部署中指定值时,我能够连接到密码为该变量的 MySQL 数据库,但是由于 ConfigMap 中的值将变量的确切字符串,因此无法连接到 mysql。

apiVersion: v1
kind: ConfigMap
metadata:
  name: config
data:
  APP_CONFIG: |
    port: 8080
    databases:
      default:
        connector: mysql
        host: "mysql"
        port: "3306"
        user: "root"
        password: "$DB_PASSWORD"

和 deployment.yaml 文件

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        ports:
          - name: "8080"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"

注意:密码存在,我能够获取"mysql-root-password"的值并用它登录到数据库


你在挂载到 Pod 的配置卷上是否将 readOnly 设置为 true 了呢? 将其设置为 False 并尝试一下。 - Sharat Chandra
@yara,您在github上的查询有一个未解决的问题。 - AATHITH RAJENDRAN
4个回答

17

Kubernetes无法为您进行这种替换,您应该在容器的entrypoint中使用shell来完成它。

这是一个可行的示例。我修改了默认的 entrypoint 来创建一个具备该替换的新变量。执行此命令后,您应该添加所需的 entrypoint。

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
  labels:
    app: backend
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: app
        image: simple-app-image
        command:
          - /bin/bash
          - -c
        args:
          - "NEW_APP_CONFIG=$(echo $APP_CONFIG | envsubst) && echo $NEW_APP_CONFIG && <INSERT IMAGE ENTRYPOINT HERE>"
        ports:
          - name: "app"
            containerPort: 8080
        env:
          - name: APP_CONFIG
            valueFrom:
              configMapKeyRef:
                name: config
                key: APP_CONFIG
          - name: DB_PASSWORD
            valueFrom:
              secretKeyRef:
                name: "mysql-secret"
                key: "mysql-root-password"

2
您可以在HELM中采用以下方式:

您可以像这样做:

{{- define "getValueFromSecret" }}
{{- $len := (default 16 .Length) | int -}}
{{- $obj := (lookup "v1" "Secret" .Namespace .Name).data -}}
{{- if $obj }}
{{- index $obj .Key | b64dec -}}
{{- else -}}
{{- randAlphaNum $len -}}
{{- end -}}
{{- end }}

那么您可以在configmap中执行以下操作:

{{- include "getValueFromSecret" (dict "Namespace" .Release.Namespace "Name" "<secret_name>" "Length" 10 "Key" "<key>")  -}}

在部署时应该已经存在密钥;或者您可以使用 https://github.com/vmware-tanzu/carvel-kapp-controller 控制部署顺序。


0
对我来说,像这样的东西有效(仅分享相关示例片段以简化):
example-configmap
data:
  example.yaml: |
    user: ${USER}

示例秘密

data:
  user: <some base64 encoded value>

示例部署

containers:
  - name: example-container
    image: example-image
    env:
      - name: USER
        valueFrom:
          secretKeyRef:
            key: user
            name: example-secret
    volumeMounts:
      - mountPath: /some/path/in/container
        name: config
        readOnly: true
volumes:  
  - name: config
    configMap:
      name: example-configmap

解释: 在上面的例子中,假设我需要用密钥中user:键的解码值来替换配置映射中的${USER}
然后,就像上面所做的那样,在部署/容器定义中,我需要:

  • 将配置映射作为卷(volumes.configMap)挂载到容器的volumeMounts下,以及
  • 将密钥值作为环境变量(env.valueFrom.secretKeyRef)暴露在容器中。

结果: 配置映射中的${USER}将被替换为密钥中user:键的解码值。

原因: 这是因为配置映射现在作为文件挂载在容器内的mountPath处,因此可以访问容器内部暴露的任何环境变量。

注意:部署/容器、配置映射和密钥的命名空间应该相同。


对我来说不起作用。 - undefined

-1
我会将整个configMap转换为一个secret,并直接部署数据库密码。 然后,您可以将该密钥作为文件挂载到卷上,并像常规配置文件一样在容器中使用它。

除非你允许你的 git 存储库中出现 secret,否则你将无法在 git 中对文件进行 SVC。我使用 confd 进行了解决。 在我的部署中,我将 secret 作为环境变量,并在容器启动时使用 confd 替换配置文件中的值。 - Med Ali Difallah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接