如何从 pod 的容器在 k8s 集群中创建一个秘密?

时间:2021-04-15 15:33:31

标签: kubernetes environment-variables containers kubectl kubernetes-secrets

我正在使用带有 2 个子图 apptest 的掌舵图在 kubernetes 中部署我的应用程序。

我让 app 图表的 pod 正常运行。 但是,只有 test pod 能够正确地向 app 容器进行身份验证时,它才会运行。

这意味着,我必须使用对 auth_token 服务的 curl 请求生成一个 app,然后将该令牌添加为 AUTH_TOKEN 容器的环境变量 test

我尝试了不同的方法来实现这一目标:

  • generate-token pod 添加了一个 init-container test,它将生成令牌并将其保存在共享卷中。而 test 容器将有权访问该卷。但这里的问题是,test 容器没有通过读取共享卷来为容器设置 env 的代码。

  • 为与上述相同的设置添加了 sidecar-container sidecar-generate-token 而不是 init-container。这里的另一个问题是,test 容器没有通过从共享卷读取来为容器设置 env 的代码。而且,测试舱进入了 crashloopbackoff 状态。如果通过进入容器查看volume的内容,在每次crashloopbackoff pod重启时,volume文件中都会产生多个token。

  • 第三个计划是在生成 auth_token 之后,init-container generate-token 应该在集群中创建一个 kubernetes secret。然后主容器 test 可以从该秘密设置环境变量。为此,init 容器 generate-token 应该首先在其中设置 kubectl。

如果我继续第三个计划,我如何设置和使用 init-container 中的 kubectl 在集群中生成秘密?

是否有其他替代计划来实现这一目标?

编辑:


这是第一个选项的 yaml 部分:

  initContainers:
    - name: generate-service-token
      image: app.mycr.io/alpine-network-troubleshooting:dev-latest
      command:
      - /bin/sh
      - -c
      - |
        BEARER_TOKEN=$(curl -k -X POST -H "Content-Type:application/json" --data '{"user":"dynizer","password":"xxxx"}' "https://app:50051/api/v2/login" | jq -r '.jwt')
        SERVICE_TOKEN=$(curl -k -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "https://app:50051/api/v2/servicetoken/issue" | jq -r '.token')
        echo $SERVICE_TOKEN
        mkdir -p /vol
        touch /vol/token.txt
        echo $SERVICE_TOKEN >> /vol/token.txt
      volumeMounts:
        - mountPath: /vol
          name: token-vol    
  containers:              
    - name: nginx-container
      image: nginx
      volumeMounts:
      - name: token-vol
        mountPath: /vol                                             
  volumes:
    - name: token-vol
      emptyDir: {}   

1 个答案:

答案 0 :(得分:0)

尝试回答您的问题:

<块引用>

但仍然存在相同的问题,即容器没有通过读取共享卷来设置 env 的代码。

让我们尝试从其他容器读取这个 env。这是我想出的。

首先你需要知道你的容器正在运行什么命令。如果 nginx 是 /docker-entrypoint.sh nginx -g "daemon off;" (source code)

然后使用 command 字段从文件中读取令牌值并使用 env 设置它并运行实际应用程序。

示例:

  initContainers:
    - name: generate-service-token
      image: app.mycr.io/alpine-network-troubleshooting:dev-latest
      command:
      - /bin/sh
      - -c
      - |
        BEARER_TOKEN=$(curl -k -X POST -H "Content-Type:application/json" --data '{"user":"dynizer","password":"xxxx"}' "https://app:50051/api/v2/login" | jq -r '.jwt')
        SERVICE_TOKEN=$(curl -k -X GET -H 'Accept: application/json' -H "Authorization: Bearer ${BEARER_TOKEN}" "https://app:50051/api/v2/servicetoken/issue" | jq -r '.token')
        echo $SERVICE_TOKEN
        mkdir -p /vol
        touch /vol/token.txt
        echo $SERVICE_TOKEN >> /vol/token.txt
      volumeMounts:
        - mountPath: /vol
          name: token-vol    
  containers:              
    - name: nginx-container
      image: nginx
      command:
      - sh
      - -c
      - exec env SERVICE_TOKEN=$(cat /vol/token.txt) /docker-entrypoint.sh nginx -g "daemon off;"
      volumeMounts:
      - name: token-vol
        mountPath: /vol                                             
  volumes:
    - name: token-vol
      emptyDir: {}   

更一般的例子:

  command:
  - sh
  - -c
  - exec env SERVICE_TOKEN=$(cat /vol/token.txt) <<any command>>

我不确定这是否是最好的例子,但我希望它至少能让您了解如何解决这个问题。