将多个k8s秘密组合到一个env变量中

时间:2019-01-13 21:55:55

标签: kubernetes kubernetes-helm

我的k8s命名空间包含一个static void Main(string[] args) { string input = "Twinkle twinkle little star"; int length = 19; Console.WriteLine(CutOff(input,length)); } private static string CutOff(string input, int length) { var solution = input.Substring(0, Math.Min(input.Length, Math.Max(0, length))); if (solution.ElementAt(solution.Length-1) == ' ') return solution.Trim(); if (input.ElementAt(solution.Length)!=' ') { var temp = solution.Split(' '); var result = temp.Take(temp.Count() - 1).ToArray(); //remove the last word return string.Join(" ", result); //convert array into a single string } return solution; } ,它是在部署时(由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_URLhostname,“数据库”组成。

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

4 个答案:

答案 0 :(得分:2)

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)

...

请注意用于变量扩展的圆括号$(...)

答案 1 :(得分:2)

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

-  { 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 }}'}

答案 2 :(得分:1)

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

  1. 在将参数放入“秘密”之前进行修改(扩展您用于在其中插入信息的内容)。

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

  3. 向您的Kubernetes添加设施以在“幕后”进行自动操作:您可以添加Dynamic Admission Controller进行操作,也可以创建Kubernetes Operator并添加操作Custom Resource Definition(CRD会告诉操作员要监视更改的秘密,操作员将读取值并生成您想要的其他任何条目)。

答案 3 :(得分:1)

您可以做一些我能想到的事情:

  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