从 kubernetes Secret 导入数据到配置映射

问题描述 投票:0回答:5

我正在使用 kubernetes ConfigMap,其中包含应用程序的数据库配置,并且有一个包含数据库密码的机密。 我需要在 ConfigMap 中使用此机密,因此当我尝试在 ConfigMap 中添加环境变量并从该机密指定 pod 部署中的值时,我无法使用密码连接到 mysql,因为 ConfigMap 中的值采用了变量的确切字符串。

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”值并用于登录数据库

kubernetes kubernetes-secrets
5个回答
18
投票

Kubernetes 无法为您进行这种替换,您应该在容器的入口点使用 shell 来完成此操作。

这是一个工作示例。我修改默认入口点以使用该替换创建一个新变量。在此命令之后,您应该添加所需的入口点。

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
投票

对我来说,这样的方法有效(为了简单起见,仅共享相关示例片段)

示例配置映射

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}
密钥的解码值替换 configmap 中的
user:

然后,如上所述,在部署/pod 定义中,我需要:

  • 将 configmap 作为卷 (
    volumes.configMap
    ) 挂载到容器中的
    volumeMounts
    下,并且
  • 将秘密值公开为容器中的环境变量 (
    env.valueFrom.secretKeyRef
    )。

结果: 配置映射中的

${USER}
将替换为密钥中
user:
密钥的解码值。

原因: 这是因为 configmap 现在作为文件安装在容器内的

mountPath
处,因此可以访问容器内公开的任何 env 变量。

注意:deployment/pod、configmap和secret的命名空间应该相同。


0
投票

可以选择使用外部秘密运算符并拉取您的 configMap,向其注入密码并从中创建一个秘密,最后安装它。

https://external-secrets.io/latest/guides/template-v1/


-2
投票

我会将整个

configMap
转换为
secret
并将数据库密码直接部署在那里。 然后,您可以将密钥作为文件安装到卷中,并像容器中的常规配置文件一样使用它。

© www.soinside.com 2019 - 2024. All rights reserved.