首页 / Kubernetes (k8s) 入门教程 / Secret 管理

Kubernetes (k8s) 入门教程

Secret 管理

本教程共 65 篇 · 第 33 篇 · 更新于 2026-08-14 · 约 9 分钟阅读

KubernetesSecret敏感数据OpaqueBase64kubectl

本节目标:弄明白 Secret 和 ConfigMap 的异同,知道 Opaque 是什么、Base64 是不是加密,会用两种方式把机密喂给容器,并建立起”Secret 默认并不安全”的意识。

上一章的 ConfigMap 明文存配置。可密码、令牌、密钥这种东西,放明文里太危险。Kubernetes 给了专门的对象叫 Secret(保密字典),专门存少量敏感数据。

它跟 ConfigMap 长得几乎一样,用法也类似。区别是它的定位是”机密”,系统对它多了一些保护动作。但请记住一句话:Secret 不是保险箱,它只是把敏感数据从镜像和 Pod 定义里剥离开。

33-1 Secret 的类型

创建 Secret 时可以用 type 字段声明类型。不写的话默认是 Opaque,也就是”用户自定义的任意数据”。

kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password='S!B*d$zDsb='

这个 generic 子命令生成的正是 Opaque 类型。除它之外,Kubernetes 还内置了几种专用类型:

  • kubernetes.io/tls:存证书和私钥,常给 Ingress 用。
  • kubernetes.io/dockerconfigjson:从私有镜像仓库拉镜像的凭据。
  • kubernetes.io/basic-auth:基础认证的账号密码。
  • kubernetes.io/ssh-auth:SSH 私钥。
  • kubernetes.io/service-account-token:服务账号令牌(v1.22 后推荐改用短令牌)。
Tip

类型只是”约定”,方便其他程序识别用途。你完全可以用 Opaque 存所有东西。但用对类型,别人读你的 YAML 一眼就懂,也帮 API 做校验。

33-2 Base64 不是加密

很多人看到 Secret 里的数据是一串乱码,就以为加密了。其实那是 Base64 编码,谁来都能解码回来。

kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d

上面这行命令就能把密码还原成明文。所以 Base64 只是为了让二进制能塞进 JSON,它不提供保密性。

真正想保密,得做两件事:给 etcd 开静态加密,再用 RBAC 把访问权限收到最小。还有,默认情况下 Secret 以明文存在 etcd 里,任何有 API 权限的人都能读。这一点务必放在心上。

Warning

任何能在本命名空间创建 Pod 的人,都能间接读到该命名空间里所有 Secret(因为 Pod 可以挂载任意 Secret)。别以为设了 Secret 就高枕无忧,RBAC 才是真正的防线。

33-3 用环境变量注入

跟 ConfigMap 几乎一模一样,只是把 configMapKeyRef 换成 secretKeyRef

env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password
Note

环境变量方式同样不会自动更新。Secret 改了,容器里的环境变量还是旧值,得重启 Pod 才生效。

33-4 用卷挂载注入

更推荐的方式是挂成卷。Secret 里的每个键变成挂载目录下的一个文件:

volumes:
- name: secret-volume
  secret:
    secretName: db-secret
containers:
- name: app
  image: myapp
  volumeMounts:
  - name: secret-volume
    readOnly: true
    mountPath: "/etc/secret"

挂成卷有两个好处。一是更新会自动传播到容器(同样有同步延迟,且 subPath 方式收不到更新)。二是 kubelet 把 Secret 内容放进了节点的 tmpfs 内存文件系统,Pod 删除后本地副本也跟着清掉,不会落盘到持久存储。

Secret 还有一个贴心细节:只有节点上真有 Pod 需要某个 Secret 时,这个 Secret 才会被发到那个节点。同节点其他 Pod 看不到它。

33-5 不可变 Secret 与安全小结

Secret 也支持 immutable: true,设了之后数据不可改,只能删了重建。对大规模集群,这能减轻 API 服务器负担,也防误改。

最后小结一下安全使用的几条原则:

  1. 给 etcd 启用静态加密,别让 Secret 明文躺在存储里。
  2. 用 RBAC 限定谁能读、谁能列 Secret,别给宽泛权限。
  3. 公共镜像的拉取凭据、证书这类,尽量用对应专用类型。
  4. 机密量特别大或要求很高时,考虑 external secret store 这类外部方案。
Tip

想进一步加固,可以读官方《Kubernetes Secret 良好实践》。本章先把用法和边界讲清楚,足够入门。