大家好!继上次的ConfigMap之后,今天我们将探讨处理需要安全保护的数据的Secret(秘密)。密码、OAuth令牌、SSH密钥等敏感信息应该如何管理呢?

1. 什么是Secret? 🔒
Secret是用于存储和管理少量敏感数据(如密码、令牌、密钥)的对象。它与ConfigMap类似,但不同之处在于它通过Base64编码来存储数据。
💡 核心摘要– 效率:仅在Pod运行时挂载到内存中,最大限度地减少磁盘暴露。
– 安全性:可以在不将敏感信息暴露在应用程序镜像或YAML文件中注入。
2. 创建Secret 🛠️
Secret也可以通过kubectl命令和YAML文件创建。
A. 使用kubectl命令创建
# 创建包含用户名和密码的Secret
kubectl create secret generic db-user-pass
--from-literal=username='admin'
--from-literal=password='S3cretP@ssw0rd'
B. 通过YAML文件定义
编写YAML文件时,值必须是Base64编码的。
- 例如:admin → YWRtaW4=
- 例如:S3cretP@ssw0rd → UzNjcmV0UEBzc3cwcmQ=
apiVersion: v1
kind: Secret
metadata:
name: db-user-pass
type: Opaque
data:
username: YWRtaW4=
password: UzNjcmV0UEBzc3cwcmQ=
3. 将Secret连接到容器 🔗
使用Secret的方法与ConfigMap几乎相同。
① 作为环境变量注入
spec:
containers:
- name: my-container
image: nginx
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-user-pass
key: password
② 作为卷挂载(最推荐的方式)
使用Secret卷可以将数据存储在tmpfs(基于RAM的文件系统)中,因此数据不会写入节点磁盘,从而更安全。
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: db-user-pass
4. Kubernetes Secret的致命局限性及原因 ⚠️
许多人对此存在误解,但仅凭Kubernetes自身的Secret功能难以实现完全的安全性。
为什么仅靠Secret是不够的?
- 简单的Base64编码:Secret数据只是编码(Encoding),而非加密(Encryption)。这意味着任何人都可以使用
base64 -d命令查看原始内容。 - etcd中明文存储:默认情况下,Secret信息以未加密的形式存储在Kubernetes的存储后端etcd中。拥有etcd访问权限的人可以窃取所有秘密信息。
- 权限管理的局限性:虽然可以通过RBAC限制访问,但如果拥有创建Pod的权限,则可以通过将Secret挂载到该Pod来查看其内容,这是一种变通方法。
5. 更安全的替代方案:外部Secret管理工具 🛡️
在需要专业安全级别的环境中,除了(或结合)Kubernetes Secret之外,还会使用以下解决方案:
- HashiCorp Vault:一个行业标准工具,提供动态密码生成和强大的加密功能。
- AWS Secrets Manager / Azure Key Vault:云服务提供商提供的托管安全服务。
- External Secrets Operator (ESO):一个开源项目,用于将外部工具(如Vault、AWS等)的信息安全地同步到Kubernetes Secret中。
总结 🎁
主公,Secret虽然方便,但它并非“绝对的保险箱”。在生产环境中,强烈建议启用etcd加密(Encryption at Rest),或结合使用Vault等专业工具。
发表回复