第33篇 k8s 之 敏感信息管理:Secret 与安全实践

IT策士 10余年一线大厂经验,专注 IT 思维、架构、职场进阶。我会在各个平台持续发布最新文章,助你少走弯路。


在第 32 篇中,我们用 ConfigMap 管理了 Flask 应用的配置------FLASK_ENV、LOG_LEVEL、REDIS_HOST。这些都是可以公开查看的非敏感信息。但应用中还有另一类配置:数据库密码、API 密钥、TLS 证书私钥 。这些信息如果像 ConfigMap 一样明文存储和展示,任何一个能执行 kubectl describe configmap 的人都能看到------这是严重的安全隐患。

Kubernetes 为此提供了专门的 Secret 对象。但 Secret 本身只是做了 base64 编码,并非真正的加密。今天这篇,我们不仅要学会 Secret 的创建和注入,更要搞清楚如何让 Secret 真正安全------包括静态加密、RBAC 权限控制,以及如何通过 Sealed Secrets 将加密后的敏感信息安全地存入 Git。

一、Secret 是什么?和 ConfigMap 有什么区别?

Secret 是 K8s 中专门用于存储和管理敏感信息的 API 对象。从操作方式上看,它和 ConfigMap 高度相似------都支持从字面量、文件、YAML 创建,都可以注入为环境变量或挂载为文件。两者最核心的区别在于设计意图和默认安全策略:

重要澄清 :Secret 的 base64 编码不是加密 。在 K8s 集群内部,任何有权限读取 Secret 的人都可以轻松解码。Secret 真正的安全价值在于它与 RBAC 配合可以实现精细的权限隔离,以及配合静态加密(Encryption at Rest)可以保护 etcd 中的敏感数据。在 Docker Compose 时代,密码通常明文写在 .env 文件中,虽然可以加入 .gitignore 避免提交,但在运行环境中仍然以明文环境变量存在。Secret 比这种"约定式"做法更进一步------它在存储层、传输层和访问控制层提供了多层次的保护。

二、Secret 的七种类型

K8s 预定义了多种 Secret 类型,通过 type 字段区分用途:

日常使用中最常见的是 Opaque (通用密码)和 kubernetes.io/tls (TLS 证书)。第 31 篇配置 HTTPS Ingress 时创建的 counter-tls Secret 就是 TLS 类型。

三、创建 Secret 的四种方式

3.1 从字面量创建

bash 复制代码
kubectl create secret generic db-secret \
  --from-literal=username=flaskapp \
  --from-literal=password=MyS3cretP@ss

输出:

验证 Secret 的"半隐藏"特性:

bash 复制代码
kubectl describe secret db-secret
# Name:         db-secret
# Namespace:    default
# Type:         Opaque
# Data
# ====
# password:  13 bytes
# username:  8 bytes

kubectl describe 只显示值的字节数,不显示明文。但要查看明文很容易:

bash 复制代码
kubectl get secret db-secret -o jsonpath='{.data.password}' | base64 -d
# MyS3cretP@ss

这就是为什么 Secret 本身需要配合 RBAC 权限控制------任何有 get secret 权限的用户都可以解码看到明文。这也是为什么生产环境中需要静态加密和 Sealed Secrets(本章第四部分)来增强安全性。

3.2 从文件创建

bash 复制代码
# 准备文件
echo -n "flaskapp" > username.txt
echo -n "MyS3cretP@ss" > password.txt

kubectl create secret generic db-secret-from-file \
  --from-file=./username.txt \
  --from-file=./password.txt

3.3 声明式 YAML(推荐)

bash 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-yaml
type: Opaque
data:
  username: Zmxhc2thcHA=         # "flaskapp" 的 base64 编码
  password: TXlTM2NyZXRQQHNz     # "MyS3cretP@ss" 的 base64 编码

注意 data 字段中的值必须是 base64 编码 。如果你不想手动编码,可以用 stringData 字段(仅用于创建,kubectl get -o yaml 不会显示 stringData):

bash 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: db-secret-string
type: Opaque
stringData:
  username: flaskapp
  password: MyS3cretP@ss

stringData 中的值不需要 base64 编码,K8s 会自动转换。推荐在 YAML 中使用 stringData 提高可读性,但注意这个 YAML 文件本身不应提交到 Git。

bash 复制代码
kubectl apply -f db-secret.yaml

3.4 使用 kustomization.yaml 管理(进阶)

对于需要管理多个环境 Secret 的场景,Kustomize 提供了更系统的方法:

bash 复制代码
# kustomization.yaml
secretGenerator:
  - name: db-secret
    literals:
      - username=flaskapp
      - password=MyS3cretP@ss

这种方式下,Secret 的值不在最终生成的 YAML 中直接出现,且 Kustomize 会自动为 Secret 名添加哈希后缀,支持 Deployment 自动滚动更新。

四、将 Secret 注入 Pod

和 ConfigMap 一样,Secret 支持三种注入方式。以下是具体的 YAML 写法:

环境变量注入:

bash 复制代码
env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password

一次性注入整个 Secret:

bash 复制代码
envFrom:
  - secretRef:
      name: db-secret

文件挂载:

bash 复制代码
volumes:
  - name: secret-volume
    secret:
      secretName: db-secret
containers:
  - name: flask
    volumeMounts:
      - name: secret-volume
        mountPath: /app/secrets
        readOnly: true

挂载后,/app/secrets/ 下会为每个键生成一个文件(如 password),文件内容是解码后的明文。readOnly: true 防止容器内进程修改 Secret 数据。

五、Secret 的安全加固

5.1 静态加密

K8s 支持对 etcd 中的 Secret 进行静态加密。这需要在 API Server 中配置 EncryptionConfiguration:

bash 复制代码
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
  - resources:
      - secrets
    providers:
      - aescbc:
          keys:
            - name: key1
              secret: <base64-encoded-32-byte-key>
      - identity: {}

配置后,新创建的 Secret 会在写入 etcd 前加密,读取时自动解密。这是防止 etcd 备份泄露导致密钥外泄的关键措施。

5.2 RBAC 权限控制

通过 RBAC 限制哪些用户和 ServiceAccount 可以读取 Secret:

bash 复制代码
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: secret-reader
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]
    resourceNames: ["db-secret"]  # 只允许访问特定 Secret

只授予应用运行所需的 ServiceAccount 最小权限,不开放集群级别的 Secret 列表权限。

5.3 企业级方案:External Secrets Operator 与 CSI Driver

对于需要与外部密钥管理系统(如 AWS Secrets Manager、HashiCorp Vault、Azure Key Vault)集成的生产环境,K8s 社区提供了更安全的方案:

  • External Secrets Operator:将外部密钥管理系统的密钥同步为 K8s Secret,支持定期轮换。

  • Secrets Store CSI Driver:将外部密钥直接挂载为 Pod 的 tmpfs 卷,密钥永远不会以 K8s Secret 形式存储在 etcd 中。

这两类工具解决了密钥生命周期的完整问题------创建、轮换、撤销都可以在外部系统统一管理,K8s 只负责消费。

六、GitOps 安全的 Secret 管理

在 GitOps 工作流中,所有的 K8s 资源 YAML 都存储在 Git 中。但 Secret 的明文绝对不能提交到 Git。解决方案是 Sealed Secrets ------它允许你将 Secret 加密后安全地提交到 Git,只有集群内的控制器可以解密。

部署 Sealed Secrets Controller:

bash 复制代码
# 在 Minikube 集群中安装(通过 Helm,第 39 篇会详解)
helm repo add sealed-secrets https://bitnami-labs.github.io/sealed-secrets
helm install sealed-secrets sealed-secrets/sealed-secrets

使用 kubeseal 加密 Secret:

bash 复制代码
# 创建普通 Secret(不提交到 Git)
kubectl create secret generic db-secret --from-literal=password=MyS3cretP@ss --dry-run=client -o yaml

# 使用 kubeseal 加密
kubectl create secret generic db-secret --from-literal=password=MyS3cretP@ss --dry-run=client -o yaml | \
  kubeseal --format yaml > db-sealed-secret.yaml

生成的 db-sealed-secret.yaml 中的密码已被加密,可以安全提交到 Git。部署时,Sealed Secrets Controller 自动解密为普通 Secret,Pod 正常使用。这样既遵守了 GitOps 的"Git 是唯一真相来源"原则,又保证了敏感信息的安全性。

七、命令速查表

八、本篇总结

  • Secret vs ConfigMap:Secret 专门存储敏感信息,支持多种预定义类型,配合 RBAC 和静态加密实现多层安全防护。

  • 三种注入方式 :环境变量、envFrom 批量注入、文件挂载(推荐,支持 tmpfs 内存存储)。

  • 安全不是默认的:裸 Secret 只是 base64 编码。生产环境必须配置静态加密 + RBAC 最小权限 + 考虑外部密钥管理系统。

  • GitOps 方案:Sealed Secrets 解决了敏感信息存入 Git 的安全问题,是实现全声明式部署的关键组件。

本篇完成了配置管理的闭环------ConfigMap 管理非敏感配置,Secret 管理敏感信息。下一篇------第 34 篇:存储基础:emptyDir 与 hostPath,我们将进入 K8s 存储体系的学习,从最简单的临时存储开始,逐步深入到 PV/PVC 和 StorageClass。

想了解更多还可以去各个平台搜索「IT策士」,一起升级 IT 思维 !

相关推荐
L0208248 小时前
Kubernetes Ingress|CNI 网络模型|Calico 网络策略|Pod 调度器完整实战教程
运维·网络·云原生·容器·kubernetes
安教安全员通关宝9 小时前
2026年吉林安全员C3证考试题库+答案+解析
安全
躺柒9 小时前
读数据安全架构设计与实践17安全架构案例(下)
数据库·安全·零信任·安全架构·防火墙·无边界
HackTwoHub9 小时前
双通道红队 C2,MCP 接入 AI,全自动渗透实战利器,具备自动提权、进程伪装、无文件上线能力,载荷 AES 加密
安全·web安全·网络安全·系统安全·密码学·可信计算技术·安全架构
学页官方10 小时前
【安全实操】教培系统上线前的安全检查清单(20条)
安全
吴声子夜歌10 小时前
Kubernetes权威指南——Kubernetes安装配置指南(网络配置)
网络·容器·kubernetes
闲云野鹤在人间10 小时前
Kubernetes Pod Scheduler 详解
云原生·容器·kubernetes
每天题库10 小时前
西藏安全员 A 证备考真题题库 强化重点知识刷题提升通过率
学习·安全·考试·题库·考证
2601_9672127211 小时前
安全型轨道式插座合规资质核查与工程选型技术要点
大数据·经验分享·安全