概述

官方文档:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/

在Kubernetes(k8s)中,Secret是一种用于存储和管理敏感信息(如密码、API密钥、TLS证书等)的资源对象。

Secret和ConfigMap类似,但是Secret专门用于保存机密数据。
如需学习ConfigMap请阅读这篇文章:K8s新手系列之ConfigMap资源

Secret的作用

  • 存储敏感数据:避免在Pod定义或容器镜像中明文存储敏感信息。
  • 与ConfigMap区分:ConfigMap用于非敏感配置数据,而Secret专为敏感数据设计(数据以Base64编码存储,但非加密)。
  • 安全共享:通过RBAC控制访问权限,确保只有授权的Pod和服务账号能使用Secret。

Secret的类型

创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数为其设置类型。 设置Secret类型有助于对 Secret 数据进行编程处理。

Kubernetes 提供若干种内置的Secret类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。

创建Secret的注意事项

每个 Secret 的尺寸最多为 1MiB。施加这一限制是为了避免用户创建非常大的 Secret, 进而导致 API 服务器和 kubelet 内存耗尽。不过创建很多小的 Secret 也可能耗尽内存。 你可以使用资源配额来约束每个名称空间中 Secret(或其他资源)的个数。

在创建 Secret 编写配置文件时,你可以设置 datastringData 字段。 datastringData 字段都是可选的。data 字段中所有值都必须是 base64编码 的字符串。stringData 字段可以使用任何字符串作为其取值。

datastringData 中的键名只能包含字母、数字、-、_ 或 . 字符。 stringData 字段中的所有键值对都会在内部被合并到 data 字段中。 如果某个主键同时出现在 datastringData 字段中,stringData 所指定的键值具有高优先级。

Secret的创建方式

官方说明Secret可以通过三种方式来创建,分别是

  • kubectl工具
  • 资源清单文件
  • Kustomize工具(这里不做讲解,有兴趣可查看官方文档)

kubectl创建Secret

官方文档:https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kubectl/

语法及注意事项:

# 从字面量进行创建
kubectl create secret <secret-type> <secret-name> [--from-literal=key=value]

# 使用文件进行创建,
# 默认会将文件名当作secret的Key
kubectl create secret <secret-type> <secret-name> [--from-literal=filepath]

# 指定secret的key
kubectl create secret <secret-type> <secret-name> [--from-literal=key=filepath]

注意事项

通过kubectl创建Secret时,其secret类型只有三类。

[root@master01 ~]# kubectl create secret --help
Create a secret using specified subcommand.

Available Commands:
  docker-registry   Create a secret for use with a Docker registry
  generic           Create a secret from a local file, directory, or literal value
  tls               Create a TLS secret
  • docker-registry:对应K8s内置类型的kubernetes.io/dockerconfigjson,存储Docker镜像仓库的认证信息。
  • generic:对应K8s内置类型的Opaque,存储用户定义的任意数据
  • tls:对应K8s内置类型的kubernetes.io/tls,存储TLS 客户端或者服务器端的数据

通过kubectl创建的secret,不论是通过字面量创建还是通过文件创建,默认都会进行base64编码并存储到data字段中

kubectl创建generic类型的secret

从字面量进行创建

# 创建secret
[root@master01 ~]# kubectl create secret generic db-secret  --from-literal=username=root --from-literal=password=huangsir
secret/db-secret created
# 验证是否创建成功
[root@master01 ~]# kubectl get secret
NAME        TYPE     DATA   AGE
db-secret   Opaque   2      10s
# 查看secret的详细信息
[root@master01 ~]# kubectl describe secret db-secret
Name:         db-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
# 发现这里只显示字节数,并不现实具体的内容
password:  8 bytes
username:  4 bytes

# 通过yaml查看
[root@master01 ~]# kubectl get secret db-secret -o yaml
apiVersion: v1
data:
  # 发现password和username字段都存储在data字段,并进行了加密
  password: aHVhbmdzaXI=
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T06:40:25Z"
  name: db-secret
  namespace: default
  resourceVersion: "138650"
  uid: 2b45f560-94bc-4991-b095-7e7410178fe9
type: Opaque

# 解密查看password和username是否和创建时输入的一样
[root@master01 ~]# echo aHVhbmdzaXI= | base64 -d
huangsir
[root@master01 ~]# echo cm9vdA== | base64 -d
root

如果我们创建时指定value已经是base64编码的数据,这个时候K8s会怎么处理呢?

#创建secret
[root@master01 ~]# kubectl create secret generic db-secret-base64  --from-literal=username="cm9vdA==" --from-literal=password="aHVhbmdzaXI="
secret/db-secret-base64 created
# 查看对应的资源
[root@master01 ~]# kubectl get secret db-secret-base64 -o yaml
apiVersion: v1
data:
  # 发现这里又进行了加密
  password: YUhWaGJtZHphWEk9
  username: Y205dmRBPT0=
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T06:52:58Z"
  name: db-secret-base64
  namespace: default
  resourceVersion: "140369"
  uid: 5f3b2ca6-abf7-4a62-9fbe-e541d41574d3
type: Opaque

通过上述发现,K8s默认会进行base64的编码,这个是K8s API强烈要求的,无法跳过的。

通过文件创建secret

# 创建模拟数据
[root@master01 ~]# mkdir -p /root/secret && echo 'root' >> /root/secret/username.txt && echo 'huangsir' >> /root/secret/password.txt

# 通过文件创建secret
[root@master01 ~]# kubectl create secret generic file-secret-1 \
 --from-file=/root/secret/username.txt \
 --from-file=/root/secret/password.txt

# 查看创建的secret
[root@master01 ~]# kubectl get secret file-secret-1 -o yaml
apiVersion: v1
data:
  # 默认以文件名作为key
  password.txt: aHVhbmdzaXIK
  username.txt: cm9vdAo=
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:03:13Z"
  name: file-secret-1
  namespace: default
  resourceVersion: "141776"
  uid: 2e888891-8ade-46ff-a2f9-3d890d032d19
type: Opaque

通过文件创建secret时,指定key

# 创建key
[root@master01 ~]# kubectl create secret generic file-secret-2 \
 --from-file=name=/root/secret/username.txt \
 --from-file=password=/root/secret/password.txt

# 查看生成的yaml
[root@master01 ~]# kubectl get secret file-secret-2 -o yaml
apiVersion: v1
data:
  # 这里已经是指定的key了
  name: cm9vdAo=
  password: aHVhbmdzaXIK
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:05:29Z"
  name: file-secret-2
  namespace: default
  resourceVersion: "142087"
  uid: b193e0d9-1c1e-43b6-aad4-ec35c40d77ea
type: Opaque

通过目录创建secret

# 创建secret
[root@master01 ~]# kubectl create secret generic file-secret-3 \
 --from-file=/root/secret/

# 查看secret信息
[root@master01 ~]# kubectl get secret file-secret-3 -o yaml
apiVersion: v1
data:
  # 默认以文件名为key,文件内容为value
  password.txt: aHVhbmdzaXIK
  username.txt: cm9vdAo=
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:16:10Z"
  name: file-secret-3
  namespace: default
  resourceVersion: "143557"
  uid: 8cbe3e73-f8e7-4c9f-8a9c-fca51c482d33
type: Opaque

kubectl创建docker-registry类型的secret

docker-registry类型的secret主要是存储Docker镜像仓库的认证信息,当我们的镜像仓库为私有仓库且需要认证信息时,可以使用该类型的secret

通过字面量创建

示例:

# 创建secret
[root@master01 ~]# kubectl create secret docker-registry my-registry-secret \
  --docker-server=registry.example.com \
  --docker-username=admin \
  --docker-password=mysecretpassword \
  [email protected]

参数解析:

  • --docker-server:仓库的域名
  • --docker-username:仓库的用户名
  • --docker-password:仓库的密码
  • --docker-email:邮箱,可选项

查看上面创建号的secret

[root@master01 ~]# kubectl get secret my-registry-secret -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyJyZWdpc3RyeS5leGFtcGxlLmNvbSI6eyJ1c2VybmFtZSI6ImFkbWluIiwicGFzc3dvcmQiOiJteXNlY3JldHBhc3N3b3JkIiwiZW1haWwiOiJhZG1pbkBleGFtcGxlLmNvbSIsImF1dGgiOiJZV1J0YVc0NmJYbHpaV055WlhSd1lYTnpkMjl5WkE9PSJ9fX0=
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:23:18Z"
  name: my-registry-secret
  namespace: default
  resourceVersion: "144535"
  uid: fafbf6e5-82da-428f-ab4f-611c2e6db99f
type: kubernetes.io/dockerconfigjson

通过配置文件创建secret

首先需要生成Docker配置文件,确保已经登录到目标的镜像仓库

docker login <镜像仓库域名> -u <username> -p <password>

登录之后会生成 ~/.docker/config.json 文件

[root@master01 ~]# cat ~/.docker/config.json
{
        "auths": {
                "sealos.hub:5000": {
                        "auth": "YWRtaW46cGFzc3cwcmQ="
                }
        }
}

从配置文件创建secret

[root@master01 ~]# kubectl create secret docker-registry sealos-secret \
  --from-file=.dockerconfigjson=/root/.docker/config.json

查看已经创建好的secret

[root@master01 ~]# kubectl get secret sealos-secret -o yaml
apiVersion: v1
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJzZWFsb3MuaHViOjUwMDAiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2Y0dGemMzY3djbVE9IgoJCX0KCX0KfQ==
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:34:36Z"
  name: sealos-secret
  namespace: default
  resourceVersion: "146085"
  uid: 56fee5b2-93a4-48f4-8bad-66490539e4e1
type: kubernetes.io/dockerconfigjson

kubectl创建tls类型的secret

语法:

kubectl create secret tls <Secret名称> \
  --cert=<证书文件路径> \
  --key=<私钥文件路径> \
  [--namespace=<命名空间>]  # 可选,指定命名空间

示例

假设我们已经有了公钥(tls.crt)和私钥(tls.key)文件

创建tls的secret

[root@master01 ~/ssl]# kubectl create secret tls tls-secret \
  --cert=/root/ssl/tls.crt \
  --key=/root/ssl/tls.key

查看secret

[root@master01 ~/ssl]# kubectl get secret tls-secret -o yaml
apiVersion: v1
data:
  # 公钥的内容
  tls.crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUYvek....#已做截取
  # 私钥的内容
  tls.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSU....#已做截取
kind: Secret
metadata:
  creationTimestamp: "2025-05-03T07:41:35Z"
  name: tls-secret
  namespace: default
  resourceVersion: "147041"
  uid: 49197d8b-7403-45a6-b4d0-9fad4b367f4f
type: kubernetes.io/tls

通过资源文件创建secret

官方文档:https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-config-file/

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

同时指定 data 和 stringData

如果你在 data 和 stringData 中设置了同一个字段,则使用来自 stringData 中的值。

例如,定义以下 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
stringData:
  username: administrator

所创建的 Secret 对象如下:

apiVersion: v1
data:
  username: YWRtaW5pc3RyYXRvcg==
kind: Secret
metadata:
  creationTimestamp: 2018-11-15T20:46:46Z
  name: mysecret
  namespace: default
  resourceVersion: "7579"
  uid: 91460ecb-e917-11e8-98f2-025000000001
type: Opaque

创建Opaque类型的secret

Opaque类型是secret中默认的类型,当创建secret时,如果不指定type字段,则默认为Opaque类型是secret

示例:创建stringData的secret(不推荐使用)

创建stringData的secret的之后,K8s默认会将stringData转为data。默认会进行base64的编码操作,这个是K8s强制性的,不可修改

# 定义资源文件
[root@master01 ~/secret]# cat db-secret-1.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-1
stringData:
  name: root
  password: huangsir
type: Opaque
# 创建secret
[root@master01 ~/secret]# kubectl apply -f db-secret-1.yaml
secret/db-secret-1 created

# 查看secret
[root@master01 ~/secret]# kubectl get secret db-secret-1 -o yaml
apiVersion: v1
# 发现K8s默认将stringData转成了data类型的
data:
  # 进行了base64编码操作
  name: cm9vdA==
  password: aHVhbmdzaXI=
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","kind":"Secret","metadata":{"annotations":{},"name":"db-secret-1","namespace":"default"},"stringData":{"name":"root","password":"huangsir"}}
  creationTimestamp: "2025-05-03T07:53:15Z"
  name: db-secret-1
  namespace: default
  resourceVersion: "148645"
  uid: ae13c565-6c0b-4071-bd9b-d48f1ed22a19
type: Opaque

示例:创建data的secret

# 先进行base64编码操作
[root@master01 ~/secret]# echo root-huangsir | base64
cm9vdC1odWFuZ3Npcgo=
[root@master01 ~/secret]# echo huangsir | base64
aHVhbmdzaXIK

# 定义资源文件
[root@master01 ~/secret]# cat db-secret-2.yaml
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-2
# 定义data类型
data:
  # 注意value值要使用base64编码的字符串
  name: cm9vdC1odWFuZ3Npcgo=
  password: aHVhbmdzaXIK
type: Opaque

# 创建secret
[root@master01 ~/secret]# kubectl get secret db-secret-2
NAME          TYPE     DATA   AGE
db-secret-2   Opaque   2      13s

# 查看详细的资源信息
[root@master01 ~/secret]# kubectl get secret db-secret-2 -o yaml
apiVersion: v1
data:
  name: cm9vdC1odWFuZ3Npcgo=
  password: aHVhbmdzaXIK
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"name":"cm9vdC1odWFuZ3Npcgo=","password":"aHVhbmdzaXIK"},"kind":"Secret","metadata":{"annotations":{},"name":"db-secret-2","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2025-05-03T08:01:11Z"
  name: db-secret-2
  namespace: default
  resourceVersion: "149733"
  uid: 60757c0c-64fa-4116-9058-d471ca0d6a8d
type: Opaque

创建dockerconfigjson类型的secret

假设你已经登录了docker的私有仓库,可以查看~/.docker/config.json文件

示例:

[root@master01 ~]# cat ~/.docker/config.json
{
        "auths": {
                "sealos.hub:5000": {
                        "auth": "YWRtaW46cGFzc3cwcmQ="
                }
        }
}

~/.docker/config.json内容进行base64编码

[root@master01 ~]# cat ~/.docker/config.json | base64
ewoJImF1dGhzIjogewoJCSJzZWFsb3MuaHViOjUwMDAiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2
Y0dGemMzY3djbVE9IgoJCX0KCX0KfQ==

编写资源文件

[root@master01 ~/secret]# cat sealos-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: sealos-registry-1
data:
  .dockerconfigjson: |
    ewoJImF1dGhzIjogewoJCSJzZWFsb3MuaHViOjUwMDAiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2Y0dGemMzY3djbVE9IgoJCX0KCX0KfQ==
type: kubernetes.io/dockerconfigjson

查看创建好的secret信息

[root@master01 ~/secret]# kubectl get secret sealos-registry-1 -o yaml
apiVersion: v1
data:
  .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJzZWFsb3MuaHViOjUwMDAiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2Y0dGemMzY3djbVE9IgoJCX0KCX0KfQ==
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{".dockerconfigjson":"ewoJImF1dGhzIjogewoJCSJzZWFsb3MuaHViOjUwMDAiOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2Y0dGemMzY3djbVE9IgoJCX0KCX0KfQ==\n"},"kind":"Secret","metadata":{"annotations":{},"name":"sealos-registry-1","namespace":"default"},"type":"kubernetes.io/dockerconfigjson"}
  creationTimestamp: "2025-05-03T08:16:08Z"
  name: sealos-registry-1
  namespace: default
  resourceVersion: "151784"
  uid: 1cd1377a-2d71-4a6f-9d5b-520d6806d942
type: kubernetes.io/dockerconfigjson

创建tls类型secret

假设你已经有了证书,我们可以对其证书进行base64编码

# 编码公钥
cat tls.crt | base64

# 编码私钥
cat tls.key | base64

编写资源文件

apiVersion: v1
kind: Secret
metadata:
  name: secret-tls
type: kubernetes.io/tls
data:
  # tls.crt,指定公钥文件
  tls.crt: |
    LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0t
  # tls.key,指定私钥文件
  tls.key: |
    RXhhbXBsZSBkYXRhIGZvciB0aGUgVExTIGNydCBmaWVsZA==

创建其它类型的secret,可以参考官网文档

官网文档地址:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/

查看Secret

语法:

kubectl get secret <secret-name> <选项>

示例:

# 查看默认名称空间下的secret
[root@master01 ~/secret]# kubectl get secret
NAME         TYPE                DATA   AGE
db-secret    Opaque              2      4h10m
tls-secret   kubernetes.io/tls   2      17m

# 查看所有的secret
[root@master01 ~/secret]# kubectl get secret -A
NAMESPACE          NAME                           TYPE                            DATA   AGE
calico-apiserver   calico-apiserver-certs         Opaque                          2      7d6h
calico-system      node-certs                     Opaque                          2      7d6h
calico-system      typha-certs                    Opaque                          2      7d6h
default            db-secret                      Opaque                          2      4h10m
default            tls-secret                     kubernetes.io/tls               2      17m
kube-system        bootstrap-token-1438e6         bootstrap.kubernetes.io/token   6      7d6h
tigera-operator    calico-apiserver-certs         Opaque                          2      7d6h
tigera-operator    node-certs                     Opaque                          2      7d6h
tigera-operator    sh.helm.release.v1.calico.v1   helm.sh/release.v1              1      7d6h
tigera-operator    tigera-ca-private              Opaque                          2      7d6h
tigera-operator    typha-certs                    Opaque                          2      7d6h

# 以yaml文件查看
[root@master01 ~/secret]# kubectl get secret db-secret -o yaml
apiVersion: v1
data:
  password: cm9vdAo=
  username: cm9vdAo=
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"cm9vdAo=","username":"cm9vdAo="},"kind":"Secret","metadata":{"annotations":{},"name":"db-secret","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2025-05-03T08:32:46Z"
  name: db-secret
  namespace: default
  resourceVersion: "154076"
  uid: c7ddc9d8-0469-4e32-beec-4c0976f23999
type: Opaque

修改secret

通过kubectl方式修改

可以通过kubectl edit secret <secret-name> -n <名称空间>来进行修改其值,使用kubectl命令之后,会打开一个类似vim的编辑界面,修改之后使用:wq保存之后即可

通过资源文件修改

修改了资源文件之后,通过kubectl apply -f <file.yaml>应用即可。
secret相同的key会进行覆盖,不同的key会进行添加,并不会进行删除多余的key

Pod使用secret

Secret 可以以数据卷的形式挂载,也可以作为环境变量暴露给 Pod 中的容器使用,当然Pod也可以以其它的方式使用secret,例如镜像拉取的密钥。

如果 Pod 依赖于某 Secret,该 Secret 必须先于 Pod 创建。

静态Pod不能使用secret资源

Pod以环境变量的方式使用secret

创建secret

[root@master01 ~]# echo 'apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  username: cm9vdAo=
  password: cm9vdAo=
type: Opaque' | kubectl apply -f -

创建Pod

[root@master01 ~]# echo 'apiVersion: v1
kind: Pod
metadata:
  name: pod-evc-secret-1
spec:
  containers:
  - name: busybox
    image: busybox:latest
    command: ["/bin/sh", "-c", "printenv"]
    env:
      - name: PASSWORD
        valueFrom:
          # 定义value从secret来
          secretKeyRef:
            # 指定secret的名称
            name: db-secret
            # 指定secret中的key
            key: password
      - name: USERNAME
        valueFrom:
          secretKeyRef:
            name: db-secret
            key: username' | kubectl apply -f -

验证环境变量是否设定成功

# secret注入到Pod之后会自动解码
[root@master01 ~]# kubectl logs pod-evc-secret-1 | grep -E "USERNAME|PASSWORD"
USERNAME=root
PASSWORD=root

配置Pod镜像拉取的secret

可以通过pod.spec.imagePullSecretsl来配置镜像的拉取密钥.

这里已经创建了的相关密钥

示例:

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: awesomeapps
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  # 指定镜像拉取密钥
  imagePullSecrets:
    # secret的key
    - name: myregistrykey

Pod以存储卷的方式使用secret

创建tls类型的secret

[root@master01 ~]# kubectl create secret tls tls-secret \
  --cert=/root/ssl/tls.crt \
  --key=/root/ssl/tls.key

创建Pod挂载Secret

方式一:将ConfigMap中所有的Key挂载到Pod指定的路径下,这种方式有以下几个地方需要注意:
  • 如果Pod挂载所在的目录中有其它的文件或目录,会将其删除
  • 如果指定Pod挂载的目录不存在,会自动创建
  • 挂载时会自动创建对应secret中的文件

示例:

# 定义资源文件
[root@master01 ~/secret]# cat pod-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-nginx
spec:
  # 创建数据卷,指定类型为secret
  volumes:
  - name: secret-volume
    secret:
      # 指定secret的名称
      secretName: tls-secret
  containers:
  - name: nginx
    image: nginx
    # 挂载数据卷
    volumeMounts:
      # 指定数据卷的名称
    - name: secret-volume
      # 设置指定
      readOnly: true
      # 挂载容器内的路径
      mountPath: "/etc/tls/secret-volume"

# 创建Pod
[root@master01 ~/secret]# kubectl apply -f pod-nginx.yaml
pod/secret-nginx created

# 查看Pod内部的文件
[root@master01 ~/secret]# kubectl exec -it secret-nginx -- ls -l /etc/tls/secret-volume
total 0
lrwxrwxrwx 1 root root 14 May  3 12:30 tls.crt -> ..data/tls.crt
lrwxrwxrwx 1 root root 14 May  3 12:30 tls.key -> ..data/tls.key

方式二:如果只想挂载ConfigMap中的部分键,并且指定挂载到Pod中的文件名,可以使用items和subPath字段来实现

# 定义资源文件
[root@master01 ~/secret]# cat pod-nginx-subpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: secret-nginx-subpath
spec:
  # 创建数据卷,指定类型为secret
  volumes:
  - name: secret-volume
    secret:
      # 指定secret的名称
      secretName: tls-secret
      items:
      - key: tls.crt
        path: nginx.crt
  containers:
  - name: nginx
    image: nginx
    # 挂载数据卷
    volumeMounts:
      # 指定数据卷的名称
    - name: secret-volume
      # 设置指定
      readOnly: true
      # 挂载容器内的路径
      mountPath: "/etc/tls/secret-volume/nginx.crt"
      # 当使用subPath属性时,则mountPath执行的不是目录,而是文件
      # 必要条件:一定要让subPath的值和items列表中的path值相同
      subPath: nginx.crt

# 创建Pod
[root@master01 ~/secret]# kubectl apply -f pod-nginx-subpath.yaml
pod/secret-nginx-subpath created
# 验证是否挂载正确
[root@master01 ~/secret]# kubectl exec -it secret-nginx-subpath -- ls -l /etc/tls/secret-volume
total 4
-rw-r--r-- 1 root root 3818 May  3 12:40 nginx.crt

配置不可变更的Secret

Kubernetes v1.21的版本中提供了一种将各个 Secret 和 ConfigMap 设置为不可变更的选项。

禁止更改现有 Secret 有下列好处:

  • 防止意外(或非预期的)更新导致应用程序中断
  • 对于大量使用 Secret 的集群而言,至少数万个不同的 Secret 供 Pod 挂载,通过将 Secret 标记为不可变,可以极大降低 kube-apiserver 的负载,提升集群性能。 kubelet 不需要监视那些被标记为不可更改的 Secret。

实现方式:可以通过将 Secret 的 immutable 字段设置为 true 创建不可更改的 Secret

apiVersion: v1
kind: Secret
metadata:
  ...
data:
  ...
immutable: true

挂载的Secret内容会被自动更新

当Pod中使用的 Secret 被更新时,所对应的Pod中对应Key也会被更新。

注意以下两种方式不会被更新,需要重启Pod:

  • 以环境变量方式使用的 Secret 数据不会被自动更新。
  • 使用 Secret 作为 subPath 卷挂载的容器将不会收到 Secret 的更新。
05-04 08:56