secret

什么是secret

使用场景

创建secrete

使用 kubectl 管理 Secret

一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。
在这些命令中,-n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。

读取文件创建secret

  1. echo -n 'admin' > ./username.txt
  2. echo -n '1f2d1e2e67df' > ./password.txt
  3. # 创建secret,默认的key是文件名
  4. kubectl create secret generic db-user-pass1 \
  5. --from-file=./username.txt \
  6. --from-file=./password.txt
  7. # 查看secret,这里是加密的
  8. kubectl get secret db-user-pass1 -o yaml
  9. apiVersion: v1
  10. data:
  11. password.txt: MWYyZDFlMmU2N2Rm
  12. username.txt: YWRtaW4=
  13. kind: Secret
  14. metadata:
  15. creationTimestamp: "2022-06-25T10:53:30Z"
  16. name: db-user-pass
  17. namespace: default
  18. resourceVersion: "8387093"
  19. uid: 2eff339e-3b98-4d73-b110-64edd8e0f1c8
  20. type: Opaque
  21. # 创建secret时指定key
  22. kubectl create secret generic db-user-pass2 \
  23. --from-file=username=./username.txt \
  24. --from-file=password=./password.txt

命令行直接创建secret
这里只能使用key=value形式

  1. kubectl create secret generic db-user-pass \
  2. --from-literal=username=devuser \
  3. --from-literal=password='S!B\*d$zDsb='

查看secret

  1. kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode

清理secret

  1. kubectl delete secret db-user-pass

使用配置文件管理 Secret

Secret 资源包含2个键值对:data 和 stringData。 data 字段用来存储 base64 编码的任意数据。 提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串。 data 和 stringData 的键必须由字母、数字、-,_ 或 . 组成。

base64编码方式存储

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. data:
  7. username: YWRtaW4=
  8. password: MWYyZDFlMmU2N2Rm

创建和查看

  1. kubectl create -f mysecret.yml
  2. kubectl get secret mysecret -o jsonpath='{.data.username}' | base64 --decode

创建字段时被编码

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. stringData:
  7. config.yaml: |
  8. apiUrl: "https://my.api.com/api/v1"
  9. username: admin
  10. password: adminabc


查看编码内容

  1. root@kubernetes-master:~# kubectl get secret mysecret -o yaml
  2. apiVersion: v1
  3. data:
  4. config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbmFiYwo=
  5. kind: Secret
  6. metadata:
  7. creationTimestamp: "2022-06-25T11:08:21Z"
  8. name: mysecret
  9. namespace: default
  10. resourceVersion: "8393715"
  11. uid: 0f59f3ab-e776-4742-8e9a-c14e6c180b57
  12. type: Opaque
  13. kubectl get secret mysecret -o jsonpath='{.data.config\.yaml}'
  14. YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbmFiYwo=root@kubernetes-master:~# kubectl get secret mysecret -o jsonpath='{.data.config\.yaml}' | base64 -d
  15. apiUrl: "https://my.api.com/api/v1"
  16. username: admin
  17. password: adminabc

使用 Kustomize 管理 Secret

https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kustomize/
文件名只能是kustomization.yaml

  1. # 从文件
  2. secretGenerator:
  3. - name: db-user-pass
  4. files:
  5. - username.txt
  6. - password.txt
  7. # 直接读取
  8. secretGenerator:
  9. - name: db-user-pass
  10. literals:
  11. - username=admin
  12. - password=1f2d1e2e67df
  13. # 从文件读取key=value
  14. root@kubernetes-master:~/kust# cat kustomization.yaml
  15. secretGenerator:
  16. - name: db-user-pass4
  17. envs:
  18. - .env.secret
  19. root@kubernetes-master:~/kust# cat .env.secret
  20. user=a
  21. pass=b
  22. # 获取数据
  23. root@kubernetes-master:~/kust# kubectl get secret db-user-pass4-5g96k45b7k -o yaml
  24. apiVersion: v1
  25. data:
  26. pass: Yg==
  27. user: YQ==
  28. kind: Secret
  29. metadata:
  30. creationTimestamp: "2022-06-25T11:31:58Z"
  31. name: db-user-pass4-5g96k45b7k
  32. namespace: default
  33. resourceVersion: "8400010"
  34. uid: 6a3633d6-9b7c-451d-8cf8-0a7c6b00655c
  35. type: Opaque
  1. kubectl create -k .

使用secret

测试secret

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. data:
  7. username: YWRtaW4=
  8. password: YWJjIC1uCg==

在 Pod 中以文件形式使用 Secret

挂载的 Secret 是被自动更新的

  1. 创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
  2. 更改 Pod 定义,在 .spec.volumes[] 下添加一个卷。根据需要为卷设置其名称, 并将 .spec.volumes[].secret.secretName 字段设置为 Secret 对象的名称
  3. 为每个需要该 Secret 的容器添加 .spec.containers[].volumeMounts[]。 并将 .spec.containers[].volumeMounts[].readOnly 设置为 true, 将 .spec.containers[].volumeMounts[].mountPath 设置为希望 Secret 被放置的、目前尚未被使用的路径名。
  4. 更改你的镜像或命令行,以便程序读取所设置的目录下的文件。Secret 的 data 映射中的每个主键都成为 mountPath 下面的文件名。
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mypod
    5. spec:
    6. containers:
    7. - name: mypod
    8. image: redis
    9. volumeMounts:
    10. - name: foo
    11. mountPath: "/etc/foo"
    12. readOnly: true
    13. volumes:
    14. - name: foo
    15. secret:
    16. secretName: mysecret
    17. optional: false # 默认设置,意味着 "mysecret" 必须已经存在

    将 Secret 键投射到特定目录

    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: mypod
    5. spec:
    6. containers:
    7. - name: mypod
    8. image: redis
    9. volumeMounts:
    10. - name: foo
    11. mountPath: "/etc/foo"
    12. readOnly: true
    13. volumes:
    14. - name: foo
    15. secret:
    16. secretName: mysecret
    17. items:
    18. - key: username
    19. path: my-group/my-username
    将发生的事情如下:
  • mysecret 中的键 username 会出现在容器中的路径为 /etc/foo/my-group/my-username, 而不是 /etc/foo/username。
  • Secret 对象的 password 键不会被投射。

以环境变量的方式使用 Secret

Secret 更新在容器内是看不到的
如果需要在 Pod 中以环境变量 的形式使用 Secret:

  1. 创建 Secret(或者使用现有 Secret)。多个 Pod 可以引用同一个 Secret。
  2. 更改 Pod 定义,在要使用 Secret 键值的每个容器中添加与所使用的主键对应的环境变量。 读取 Secret 主键的环境变量应该在 env[].valueFrom.secretKeyRef 中填写 Secret 的名称和主键名称。
  3. 更改你的镜像或命令行,以便程序读取环境变量中保存的值。
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4. name: secret-env-pod
    5. spec:
    6. containers:
    7. - name: mycontainer
    8. image: redis
    9. env:
    10. - name: SECRET_USERNAME
    11. valueFrom:
    12. secretKeyRef:
    13. name: mysecret
    14. key: username
    15. optional: false # 此值为默认值;意味着 "mysecret"
    16. # 必须存在且包含名为 "username" 的主键
    17. - name: SECRET_PASSWORD
    18. valueFrom:
    19. secretKeyRef:
    20. name: mysecret
    21. key: password
    22. optional: false # 此值为默认值;意味着 "mysecret"
    23. # 必须存在且包含名为 "password" 的主键
    24. restartPolicy: Never
    通过环境变量形式读取变量
    1. echo "$SECRET_USERNAME"

    容器镜像拉取 Secret

    imagePullSecrets 字段是一个列表,包含对同一名字空间中 Secret 的引用。 你可以使用 imagePullSecrets 将包含 Docker(或其他)镜像仓库密码的 Secret 传递给 kubelet。kubelet 使用此信息来替 Pod 拉取私有镜像。 参阅 PodSpec API 进一步了解 imagePullSecrets 字段。

你需要知道用于向仓库进行身份验证的用户名、密码和客户端电子邮件地址,以及它的主机名。 运行以下命令,注意替换适当的大写值:

  1. kubectl create secret docker-registry <name> --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL


如果你已经有 Docker 凭据文件,则可以将凭据文件导入为 Kubernetes Secret, 而不是执行上面的命令。 基于已有的 Docker 凭据创建 Secret 解释了如何完成这一操作。

使用场景
https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#use-case

作为容器环境变量

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysecret
  5. type: Opaque
  6. data:
  7. USER_NAME: YWRtaW4=
  8. PASSWORD: MWYyZDFlMmU2N2Rm
  1. kubectl apply -f mysecret.yaml
  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: secret-test-pod
  5. spec:
  6. containers:
  7. - name: test-container
  8. image: busybox
  9. command: [ "/bin/sh", "-c", "env" ]
  10. envFrom:
  11. - secretRef:
  12. name: mysecret
  13. restartPolicy: Never

通过logs查看日志环境变量

带 SSH 密钥的 Pod

  1. kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub
  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: secret-test-pod
  5. labels:
  6. name: secret-test
  7. spec:
  8. volumes:
  9. - name: secret-volume
  10. secret:
  11. secretName: ssh-key-secret
  12. containers:
  13. - name: ssh-test-container
  14. image: busybox
  15. volumeMounts:
  16. - name: secret-volume
  17. readOnly: true
  18. mountPath: "/root/.ssh/"
内置类型 用法
Opaque 用户定义的任意数据
kubernetes.io/service-account-token 服务账号令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份认证的凭据
kubernetes.io/ssh-auth 用于 SSH 身份认证的凭据
kubernetes.io/tls 用于 TLS 客户端或者服务器端的数据
bootstrap.kubernetes.io/token 启动引导令牌数据