K8S实战(十三)| Secret 对象
前言
Secret 可以用来保存密码、密钥等敏感信息,避免密钥直接放在 Pod 的YAML定义文件或容器镜像中导致的泄露问题。
密钥使用 Base64 编码形式存储于 Secret 对象中,Pod 挂载后自动解码为明文。
更新历史
- 20200702 - 初稿 - 左程立
- 原文地址 - https://blog.zuolinux.com/2020/07/02/about-secret.html
通过 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
以上示例中,
将名为 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 账号漏洞的影响, 该功能还在计划中。
联系我
微信公众号:zuolinux_com