通过 kubectl 创建 Secret
创建用户名/密码文件
echo -n 'username' > ./username.txt
echo -n 'password' > ./password.txt
写入 Secret 对象中
# kubectl create secret generic db-info --from-file=./username.txt --from-file=./password.txt
secret/db-info created
检查 Secret
# kubectl get secret
NAME TYPE DATA AGE
db-info Opaque 2 106s
查看刚写入的 db-info 的详细信息
# kubectl describe secret db-info
Name: db-info
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
username.txt: 8 bytes
password.txt: 8 bytes
查看密钥的值
# kubectl get secret db-info -o yaml
通过 YAML 创建 Secret
先将要保存的值进行 Base64 编码
# echo -n 'username' | base64
dXNlcm5hbWU=
# echo -n 'password' | base64
cGFzc3dvcmQ=
#cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: base64编码
password: base64编码
创建 secret
# kubectl apply -f secret.yaml
secret/mysecret created
查看
# kubectl get secret
NAME TYPE DATA AGE
mysecret Opaque 2 2m5s
查看密钥的值
# kubectl get secret mysecret -o yaml
编辑 secret
kubectl edit secrets mysecret
在 Pod 中使用 Secret
-
将 Secret 以卷的形式挂载到 Pod 中
-
卷中每一个文件名对应 Secret 中的一个 key 名称
-
Secret 的值以 base64 解码后明文形式存储于卷文件中
-
支持实时动态更新
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers:
- name: mypod
image: redis
volumeMounts:
- name: foo mountPath: "/etc/foo" readOnly: true volumes:
- name: foo secret: secretName: mysecret
- name: mypod
image: redis
volumeMounts:
以上示例中,
将名为 mysecret 的 secret 对象映射为卷,卷名为 foo,
将名为 foo 的卷挂载到 Pod 中的路径 /etc/foo 下面,
mysecret 中username/password两个key,分别映射为文件。
多个 Pod 可以共享一个卷。
可以进入 Pod 中查看这两个文件内容
# kubectl exec -it mypod -- ls /etc/foo/
password username
# kubectl exec -it mypod -- cat /etc/foo/username
admin
# kubectl exec -it mypod -- cat /etc/foo/password
password
结束语
Secret 对象将重要性高的秘钥和 Pod 进行了解耦处理。
它有如下特点:
- Secret 对象需先于引用它的 Pod 创建。
- Secret 对象和引用它的 Pod 必须位于同一命名空间。
- Secret 对象单个大小限制为 1M。
- Secret 对象中数据以纯文本的方式存储在 etcd 中。
- 除了以卷形式挂载外,还可以环境变量形式用于 Pod 中。
- 使用环境变量形式的问题是,secret无法动态实时更新。
官方安全建议:
- 管理员应该为集群数据开启静态加密(v1.13 以上版本)。
- 管理员应该限制只有 admin 用户能访问 etcd。
- API 服务器中的 Secret 数据位于 etcd 使用的磁盘上;应该在不再使用时擦除/粉碎 etcd 使用的磁盘。
- 如果 etcd 运行在集群内,管理员应该确保 etcd 之间的通信使用 SSL/TLS 进行加密。
- secret 的YAML中包含的 base64 编码为可逆编码,不要将其加入代码库或公开。
- 防止应用程序读取 secret 中数据后写入日志导致泄露。
- 所有可以运行该 Pod 的用户均可读取到挂载卷中的 secret 值。
- 任何节点的 root 用户都可以通过模拟 kubelet 来读取 API 服务器中的任何 Secret。 仅向实际需要 Secret 的节点发送 Secret 数据才能限制节点的 root 账号漏洞的影响, 该功能还在计划中。