【问题标题】:Combining multiple k8s secrets into an env variable将多个 k8s 机密组合到一个环境变量中
【发布时间】:2019-06-07 23:21:11
【问题描述】:

我的 k8s 命名空间包含一个 Secret,它是在部署时创建的(由 svcat 创建),因此事先不知道这些值。

apiVersion: v1
kind: Secret
type: Opaque
metadata:
  name: my-database-credentials
data:
  hostname: ...
  port: ...
  database: ...
  username: ...
  password: ...

Deployment 需要以稍微不同的格式注入这些值:

...

containers:
  env:
  - name: DATABASE_URL
    valueFrom:
      secretKeyRef:
        name: my-database-credentials
        key: jdbc:postgresql:<hostname>:<port>/<database> // ??

  - name: DATABASE_USERNAME
    valueFrom:
      secretKeyRef:
        name: my-database-credentials
        key: username

  - name: DATABASE_PASSWORD
    valueFrom:
      secretKeyRef:
        name: my-database-credentials
        key: password

DATABASE_URL 需要由先前定义的机密中的hostnameport、“数据库”组成。

有什么方法可以做这个组合吗?

【问题讨论】:

    标签: kubernetes kubernetes-helm


    【解决方案1】:

    Kubernetes 允许您将先前定义的环境变量用作配置中其他地方的后续环境变量的一部分。来自Kubernetes API reference docs

    变量引用 $(VAR_NAME) 使用容器中先前定义的环境变量和任何服务环境变量进行扩展。

    因此,您可以先将所需的秘密值提取到环境变量中,然后将这些变量组合成DATABASE_URL

    ...
    
    containers:
      env:
      - name: DB_URL_HOSTNAME               // part 1
        valueFrom:
          secretKeyRef:
            name: my-database-credentials
            key: hostname
    
      - name: DB_URL_PORT                   // part 2
        valueFrom:
          secretKeyRef:
            name: my-database-credentials
            key: port
    
      - name: DB_URL_DBNAME                 // part 3
        valueFrom:
          secretKeyRef:
            name: my-database-credentials
            key: database
    
      - name: DATABASE_URL                  // combine
        value: jdbc:postgresql:$(DB_URL_HOSTNAME):$(DB_URL_PORT)/$(DB_URL_DBNAME)
    
    ...
    

    注意用于变量扩展的圆括号$(...) - 它是Kubernetes dependant variable notation

    【讨论】:

      【解决方案2】:

      你可以做几件我能想到的事情:

      1. 使用secrets volume 并创建一个启动脚本,从卷中读取机密,然后使用DATABASE_URL 环境变量启动您的应用程序。

        apiVersion: v1
        kind: Pod
        metadata:
          name: mypod
        spec:
          containers:
          - name: mypod
            image: your_db_container
            command: [ "yourscript.sh" ]
            volumeMounts:
            - name: mycreds
              mountPath: "/etc/credentials"
          volumes:
          - name: mycreds
            secret:
              secretName: my-database-credentials
              defaultMode: 256
        
      2. 在容器规范的 command 键中传递 env 变量:

        apiVersion: v1
        kind: Pod
        metadata:
          name: mypod
        spec:
          containers:
          - name: mypod
            image: your_db_container
            command: [ "/bin/sh", "-c", "DATABASE_URL=jdbc:postgresql:<hostname>:<port>/<database>/$(DATABASE_USERNAME):$(DATABASE_PASSWORD) /start/yourdb" ]
        
            env:
            - name: DATABASE_USERNAME
              valueFrom:
                secretKeyRef:
                  name: my-database-credentials
                  key: username
            - name: DATABASE_PASSWORD
              valueFrom:
                secretKeyRef:
                name: my-database-credentials
                key: password
        

      【讨论】:

        【解决方案3】:

        如果所有预变量都定义为环境变量:

        -  { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/$(DB_URL_DBNAME)" }}'}
        

        使用此语句,您还可以从 values.yaml 文件中引入 vlaues:

        例如:

        如果您可能在值文件中定义了 DB_URL_DBNAME:

        -  { name: DATABASE_URL, value: '{{ printf "jdbc:postgresql:$(DATABASE_HOST):$(DATABASE_PORT)/%s" .Values.database.DB_URL_DBNAME }}'}
        

        【讨论】:

          【解决方案4】:

          有几种方法(按复杂度递增的顺序):

          1. 在将参数放入 Secret 之前对其进行修改(扩展您用于在其中插入信息的任何内容)。

          2. 将脚本添加到您的 Pod/Container 中,以将传入参数(环境变量或命令参数)修改为所需的参数。如果您不能或不想拥有自己的容器映像,您可以将额外的脚本作为卷添加到容器中,并set the Container's command field to override the container image start command

          3. 在您的 Kubernetes 中添加一个工具来“在幕后”进行自动修改:您可以添加一个 Dynamic Admission Controller 来进行您的修改,或者您可以创建一个 Kubernetes Operator 并添加一个 Custom Resource Definition( CRD 会告诉操作员哪些 Secrets 需要监视更改,操作员会读取这些值并生成您想要的任何其他条目。

          【讨论】:

            猜你喜欢
            • 2022-01-11
            • 1970-01-01
            • 2023-01-22
            • 1970-01-01
            • 2018-09-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-12-29
            相关资源
            最近更新 更多