K8s学习笔记:04.2-Secret敏感信息管理

对应章节:第四章 配置与存储 / 4.2 Secret:密码/密钥的安全存储
日期:2026年7月28日


痛点:密码不能写进 YAML 提交 Git

4.1 学了 ConfigMap 存配置。但数据库密码、API Key、TLS 证书怎么办?

1
2
3
4
# 这样写 = 找死
data:
DB_PASSWORD: "MyP@ssw0rd" Git 提交就泄露
API_KEY: "sk-xxxxx" 任何人 clone 代码都能看到

不能把密码当普通配置存。 K8s 的解法:Secret。


Secret 是什么

Secret 和 ConfigMap 使用方式几乎一样,区别在存储和内存安全

ConfigMap Secret
存储 etcd 明文 etcd 里 base64 编码
用途 配置(端口、环境名) 密码、Token、证书
内存 普通内存 只在 tmpfs(不落磁盘)
大小限制 1MB 1MB
使用方式 envFrom / valueFrom / volume 完全相同

base64 不是加密! echo 'cGFzc3dvcmQ=' | base64 -d 任何人秒解。真正的安全靠 etcd 加密 + RBAC + 审计。


创建 Secret

1
2
3
4
5
6
7
8
9
10
11
# 方式一:--from-literal
kubectl create secret generic db-creds \
--from-literal=username=admin \
--from-literal=password=MyP@ssw0rd

# 方式二:--from-file
echo -n 'admin' > /tmp/username.txt
echo -n 'MyP@ssw0rd' > /tmp/password.txt
kubectl create secret generic db-creds-file \
--from-file=/tmp/username.txt \
--from-file=/tmp/password.txt

generic 是 Secret 的类型名(Opaque),最常见的一种。还有 docker-registry(拉镜像凭据)和 tls(证书)类型。


查看 Secret

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
kubectl get secret
# NAME TYPE DATA AGE
# db-creds Opaque 2 10s

kubectl describe secret db-creds
# Name: db-creds
# Namespace: default
# Type: Opaque
# Data
# ====
# password: 10 bytes ← 不显示明文,只显示大小
# username: 5 bytes

kubectl get secret db-creds -o yaml
# data:
# password: TXlQQHNzdzByZA== ← base64 编码
# username: YWRtaW4=

手动还原:echo 'TXlQQHNzdzByZA==' | base64 -dMyP@ssw0rd


把 Secret 注入 Pod

用法一:envFrom(全量注入为环境变量)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-secret
spec:
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "3600"]
envFrom:
- secretRef:
name: db-creds
restartPolicy: Never
EOF
1
2
3
kubectl exec test-secret -- env | grep -E "username|password"
# username=admin
# password=MyP@ssw0rd

容器里是明文。base64 只在 etcd 存储时编码,kubelet 挂载时自动解码。

用法二:volume mount(每个 key 一个文件)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kubectl delete pod test-secret

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: test-secret-vol
spec:
volumes:
- name: secret-volume
secret:
secretName: db-creds
containers:
- name: busybox
image: busybox:1.36
command: ["sleep", "3600"]
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
restartPolicy: Never
EOF

挂载后容器里:

1
2
3
4
5
6
7
8
9
10
11
kubectl exec test-secret-vol -- ls /etc/secrets/
# password username ← 每个 key 一个文件

kubectl exec test-secret-vol -- cat /etc/secrets/username
# admin ← 内容是明文

kubectl exec test-secret-vol -- cat /etc/secrets/password
# MyP@ssw0rd

kubectl exec test-secret-vol -- env | grep -E "username|password"
# (无输出 — volume 方式不会注入环境变量)

Secret vs ConfigMap 使用场景判断

场景 用什么
Nginx 监听端口 8080 ConfigMap
数据库连接地址 db.prod.com ConfigMap
数据库密码 MyP@ssw0rd Secret
API Token sk-xxxxx Secret
日志级别 DEBUG ConfigMap
TLS 证书 .crt/.key Secret (type: tls)

直觉法则:值能公开贴到群里 → ConfigMap;值要捂着的 → Secret。


练习记录

练习 1:envFrom 验证

1
2
3
4
# 1. 用 --from-literal 创建 Secret,含 username 和 api_key
# 2. 起 busybox Pod,envFrom 注入
# 3. kubectl exec 进去 env 验证
# 4. kubectl get secret -o yaml 看 base64 编码

练习 2:volume 挂载验证

1
2
3
# 1. 重建 Pod,改用 volume 方式挂载 Secret 到 /etc/myapp
# 2. 进去 ls /etc/myapp/ 看文件列表
# 3. cat 每个文件,确认是明文

练习 3:对比实验

1
2
# 1. 同时挂载一个 ConfigMap 和一个 Secret
# 2. 验证两者在容器里的表现是否一样(应该完全一样,都看到明文)

清理

1
2
kubectl delete pod test-secret-vol
kubectl delete secret db-creds db-creds-file

K8s学习笔记:04.2-Secret敏感信息管理
https://bote798.top/2026/07/28/K8s学习笔记-04.2-Secret敏感信息/
作者
bote798
发布于
2026年7月28日
更新于
2026年7月28日
许可协议