secret
什么是secret
使用场景
创建secrete
使用 kubectl 管理 Secret
一个 Secret 可以包含 Pod 访问数据库所需的用户凭证。
在这些命令中,-n 标志确保生成的文件在文本末尾不包含额外的换行符。 这一点很重要,因为当 kubectl 读取文件并将内容编码为 base64 字符串时,多余的换行符也会被编码。
读取文件创建secret
echo -n 'admin' > ./username.txtecho -n '1f2d1e2e67df' > ./password.txt# 创建secret,默认的key是文件名kubectl create secret generic db-user-pass1 \--from-file=./username.txt \--from-file=./password.txt# 查看secret,这里是加密的kubectl get secret db-user-pass1 -o yamlapiVersion: v1data:password.txt: MWYyZDFlMmU2N2Rmusername.txt: YWRtaW4=kind: Secretmetadata:creationTimestamp: "2022-06-25T10:53:30Z"name: db-user-passnamespace: defaultresourceVersion: "8387093"uid: 2eff339e-3b98-4d73-b110-64edd8e0f1c8type: Opaque# 创建secret时指定keykubectl create secret generic db-user-pass2 \--from-file=username=./username.txt \--from-file=password=./password.txt
命令行直接创建secret
这里只能使用key=value形式
kubectl create secret generic db-user-pass \--from-literal=username=devuser \--from-literal=password='S!B\*d$zDsb='
查看secret
kubectl get secret db-user-pass -o jsonpath='{.data.password}' | base64 --decode
清理secret
kubectl delete secret db-user-pass
使用配置文件管理 Secret
Secret 资源包含2个键值对:data 和 stringData。 data 字段用来存储 base64 编码的任意数据。 提供 stringData 字段是为了方便,它允许 Secret 使用未编码的字符串。 data 和 stringData 的键必须由字母、数字、-,_ 或 . 组成。
base64编码方式存储
apiVersion: v1kind: Secretmetadata:name: mysecrettype: Opaquedata:username: YWRtaW4=password: MWYyZDFlMmU2N2Rm
创建和查看
kubectl create -f mysecret.ymlkubectl get secret mysecret -o jsonpath='{.data.username}' | base64 --decode
创建字段时被编码
apiVersion: v1kind: Secretmetadata:name: mysecrettype: OpaquestringData:config.yaml: |apiUrl: "https://my.api.com/api/v1"username: adminpassword: adminabc
查看编码内容
root@kubernetes-master:~# kubectl get secret mysecret -o yamlapiVersion: v1data:config.yaml: YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbmFiYwo=kind: Secretmetadata:creationTimestamp: "2022-06-25T11:08:21Z"name: mysecretnamespace: defaultresourceVersion: "8393715"uid: 0f59f3ab-e776-4742-8e9a-c14e6c180b57type: Opaquekubectl get secret mysecret -o jsonpath='{.data.config\.yaml}'YXBpVXJsOiAiaHR0cHM6Ly9teS5hcGkuY29tL2FwaS92MSIKdXNlcm5hbWU6IGFkbWluCnBhc3N3b3JkOiBhZG1pbmFiYwo=root@kubernetes-master:~# kubectl get secret mysecret -o jsonpath='{.data.config\.yaml}' | base64 -dapiUrl: "https://my.api.com/api/v1"username: adminpassword: adminabc
使用 Kustomize 管理 Secret
https://kubernetes.io/zh-cn/docs/tasks/configmap-secret/managing-secret-using-kustomize/
文件名只能是kustomization.yaml
# 从文件secretGenerator:- name: db-user-passfiles:- username.txt- password.txt# 直接读取secretGenerator:- name: db-user-passliterals:- username=admin- password=1f2d1e2e67df# 从文件读取key=valueroot@kubernetes-master:~/kust# cat kustomization.yamlsecretGenerator:- name: db-user-pass4envs:- .env.secretroot@kubernetes-master:~/kust# cat .env.secretuser=apass=b# 获取数据root@kubernetes-master:~/kust# kubectl get secret db-user-pass4-5g96k45b7k -o yamlapiVersion: v1data:pass: Yg==user: YQ==kind: Secretmetadata:creationTimestamp: "2022-06-25T11:31:58Z"name: db-user-pass4-5g96k45b7knamespace: defaultresourceVersion: "8400010"uid: 6a3633d6-9b7c-451d-8cf8-0a7c6b00655ctype: Opaque
kubectl create -k .
使用secret
测试secret
apiVersion: v1kind: Secretmetadata:name: mysecrettype: Opaquedata:username: YWRtaW4=password: YWJjIC1uCg==
在 Pod 中以文件形式使用 Secret
挂载的 Secret 是被自动更新的
- 创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
- 更改 Pod 定义,在 .spec.volumes[] 下添加一个卷。根据需要为卷设置其名称, 并将 .spec.volumes[].secret.secretName 字段设置为 Secret 对象的名称。
- 为每个需要该 Secret 的容器添加 .spec.containers[].volumeMounts[]。 并将 .spec.containers[].volumeMounts[].readOnly 设置为 true, 将 .spec.containers[].volumeMounts[].mountPath 设置为希望 Secret 被放置的、目前尚未被使用的路径名。
- 更改你的镜像或命令行,以便程序读取所设置的目录下的文件。Secret 的 data 映射中的每个主键都成为 mountPath 下面的文件名。
apiVersion: v1kind: Podmetadata:name: mypodspec:containers:- name: mypodimage: redisvolumeMounts:- name: foomountPath: "/etc/foo"readOnly: truevolumes:- name: foosecret:secretName: mysecretoptional: false # 默认设置,意味着 "mysecret" 必须已经存在
将 Secret 键投射到特定目录
将发生的事情如下:apiVersion: v1kind: Podmetadata:name: mypodspec:containers:- name: mypodimage: redisvolumeMounts:- name: foomountPath: "/etc/foo"readOnly: truevolumes:- name: foosecret:secretName: mysecretitems:- key: usernamepath: my-group/my-username
- mysecret 中的键 username 会出现在容器中的路径为 /etc/foo/my-group/my-username, 而不是 /etc/foo/username。
- Secret 对象的 password 键不会被投射。
以环境变量的方式使用 Secret
Secret 更新在容器内是看不到的
如果需要在 Pod 中以环境变量 的形式使用 Secret:
- 创建 Secret(或者使用现有 Secret)。多个 Pod 可以引用同一个 Secret。
- 更改 Pod 定义,在要使用 Secret 键值的每个容器中添加与所使用的主键对应的环境变量。 读取 Secret 主键的环境变量应该在 env[].valueFrom.secretKeyRef 中填写 Secret 的名称和主键名称。
- 更改你的镜像或命令行,以便程序读取环境变量中保存的值。
通过环境变量形式读取变量apiVersion: v1kind: Podmetadata:name: secret-env-podspec:containers:- name: mycontainerimage: redisenv:- name: SECRET_USERNAMEvalueFrom:secretKeyRef:name: mysecretkey: usernameoptional: false # 此值为默认值;意味着 "mysecret"# 必须存在且包含名为 "username" 的主键- name: SECRET_PASSWORDvalueFrom:secretKeyRef:name: mysecretkey: passwordoptional: false # 此值为默认值;意味着 "mysecret"# 必须存在且包含名为 "password" 的主键restartPolicy: Never
echo "$SECRET_USERNAME"
容器镜像拉取 Secret
imagePullSecrets 字段是一个列表,包含对同一名字空间中 Secret 的引用。 你可以使用 imagePullSecrets 将包含 Docker(或其他)镜像仓库密码的 Secret 传递给 kubelet。kubelet 使用此信息来替 Pod 拉取私有镜像。 参阅 PodSpec API 进一步了解 imagePullSecrets 字段。
你需要知道用于向仓库进行身份验证的用户名、密码和客户端电子邮件地址,以及它的主机名。 运行以下命令,注意替换适当的大写值:
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
作为容器环境变量
apiVersion: v1kind: Secretmetadata:name: mysecrettype: Opaquedata:USER_NAME: YWRtaW4=PASSWORD: MWYyZDFlMmU2N2Rm
kubectl apply -f mysecret.yaml
apiVersion: v1kind: Podmetadata:name: secret-test-podspec:containers:- name: test-containerimage: busyboxcommand: [ "/bin/sh", "-c", "env" ]envFrom:- secretRef:name: mysecretrestartPolicy: Never
通过logs查看日志环境变量
带 SSH 密钥的 Pod
kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub
apiVersion: v1kind: Podmetadata:name: secret-test-podlabels:name: secret-testspec:volumes:- name: secret-volumesecret:secretName: ssh-key-secretcontainers:- name: ssh-test-containerimage: busyboxvolumeMounts:- name: secret-volumereadOnly: truemountPath: "/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 | 启动引导令牌数据 |
