Kubernetes(K8s)提供了一种安全的方式来存储和管理敏感信息,如密码、OAuth 令牌和 SSH 密钥,这就是 Secret。使用 Secret 可以避免将敏感数据硬编码到 Pod 规范或容器镜像中,从而提高安全性和可管理性。
1. Secret 的类型
K8s 支持多种类型的 Secret,主要包括:
Opaque(不透明类型):默认类型,可用于存储任意数据。
kubernetes.io/dockerconfigjson:用于存储 Docker 认证信息。
kubernetes.io/service-account-token:用于存储 Kubernetes ServiceAccount 令牌。
kubernetes.io/basic-auth:用于存储用户名和密码。
kubernetes.io/ssh-auth:用于存储 SSH 密钥。
kubernetes.io/tls:用于存储 TLS 证书。
bootstrap.kubernetes.io/token:用于集群引导时的 token。
2. 创建 Secret 的方式
K8s 支持三种主要方式创建 Secret:
2.1 使用 kubectl 命令创建 Secret
示例 1:创建 Opaque 类型的 Secret
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=secret123
上述命令创建了一个名为 my-secret
的 Secret,其中包含 username
和 password
两个键值对。
示例 2:从文件创建 Secret
echo -n "admin" > username.txt
echo -n "secret123" > password.txt
kubectl create secret generic my-secret-from-file \
--from-file=username.txt \
--from-file=password.txt
2.2 使用 YAML 清单创建 Secret
我们可以使用 YAML 文件定义 Secret,例如:
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
type: Opaque
data:
username: YWRtaW4= # "admin" 的 base64 编码
password: c2VjcmV0MTIz # "secret123" 的 base64 编码
然后使用 kubectl apply -f my-secret.yaml
创建该 Secret。
2.3 通过 API 或 SDK 创建 Secret
在编程环境中,我们可以使用 Kubernetes API 或者客户端 SDK(如 Python、Go 语言的 SDK)来创建 Secret。
3. 在 Pod 中使用 Secret
Secret 创建后,可以通过环境变量或挂载为文件的方式供 Pod 使用。
3.1 通过环境变量使用 Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: my-container
image: nginx
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
3.2 以文件方式挂载 Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-volume-pod
spec:
containers:
- name: my-container
image: nginx
volumeMounts:
- name: secret-volume
mountPath: "/etc/secret"
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: my-secret
这样,Secret 的数据会被挂载到 /etc/secret
目录下,每个键都会成为该目录下的一个文件,文件内容就是解码后的值。
4. 更新 Secret
Kubernetes 不支持直接更新 Secret,而是需要删除并重新创建。
kubectl delete secret my-secret
kubectl create secret generic my-secret --from-literal=username=newadmin --from-literal=password=newsecret123
或者使用 kubectl apply -f my-secret.yaml
进行更新。
5. 保护 Secret 的最佳实践
使用 RBAC 控制访问:确保只有需要访问 Secret 的用户和服务账户才有权限。
避免直接暴露 Secret:尽量通过 Pod 挂载,而不是打印或存储到日志。
使用加密存储 Secret:启用 Kubernetes etcd 加密,以保护存储在 etcd 中的 Secret。
定期轮换 Secret:定期更新 Secret 并更新相关的 Pod。
使用外部 Secret 管理工具:如 HashiCorp Vault、AWS Secrets Manager 或 Azure Key Vault。
6. 结论
Kubernetes Secret 提供了一种安全、灵活的方式来管理敏感信息。通过不同的类型、创建方式和使用方式,可以满足不同的需求,同时遵循最佳实践可以确保 Secret 的安全性。