在 Kubernetes 集群中,直接将密码、Token、数据库连接串等敏感信息硬编码到 Pod 或 Deployment 配置中,会带来极大的安全风险 —— 配置文件泄露即意味着敏感信息暴露。Kubernetes Secret 作为专门存储敏感键值对的核心资源,能通过 Base64 编码(非加密,仅防明文泄露)+ 权限控制的方式,安全管理这些敏感配置。本文将结合真实实操案例,从 Secret 基础概念、创建方式到挂载使用,全面讲解 Secret 的核心用法。

一、Secret 核心认知

1. 什么是 Secret?

Secret 是 K8s 提供的敏感配置存储资源,用于存储密码、OAuth 令牌、SSH 密钥等敏感信息,相比 ConfigMap(存储非敏感配置),Secret 具备更严格的权限控制,且数据以 Base64 编码形式存储(注:Base64 是编码而非加密,需结合 RBAC / 加密配置提升安全性)。

2. Secret 核心类型

日常开发中最常用的是以下两类:

类型用途示例
Opaque通用类型,存储任意键值对(最常用)用户名、密码、自定义 Token
kubernetes.io/dockerconfigjson存储镜像仓库的拉取凭证私有镜像仓库的用户名 / 密码
本文所有案例均基于 Opaque 类型展开。

3. Secret vs ConfigMap

很多新手会混淆两者,核心差异如下:

  • 存储内容:Secret 存敏感信息,ConfigMap 存非敏感配置
  • 存储形式:Secret 数据为 Base64 编码,ConfigMap 为明文;
  • 权限控制:Secret 可限制仅授权 Pod 挂载,ConfigMap 无特殊权限限制。

二、实战第一步:创建 Opaque 类型 Secret

1. 核心前提:Base64 编码规范

Secret 的 data 字段要求值为合法的 Base64 编码(长度为 4 的整数倍,仅包含字母 / 数字 /+/=/),创建前需先对明文配置编码:

# 对明文 "admin" 编码(-n 避免换行符干扰)
echo -n "admin" | base64
# 输出:YWRtaW4=

# 对明文 "hexidong" 编码
echo -n "hexidong" | base64
# 输出:aGV4aWRvbmc=

⚠️ 注意:若编码值不合法(如长度非 4 的整数倍、含特殊字符),创建 Secret 时会报 illegal base64 data 错误。

2. 通过 YAML 文件创建 Secret

创建 mysecret.yaml,包含用户名和密码两个敏感配置:

apiVersion: v1
kind: Secret
metadata:
  name: mysecret  # Secret 名称
  namespace: default  # 命名空间(默认default)
type: Opaque  # 通用类型
data:
  username: YWRtaW4=  # 对应明文 admin
  password: aGV4aWRvbmc=  # 对应明文 hexidong

执行创建命令:

kubectl apply -f mysecret.yaml

3. 验证 Secret 创建结果

# 查看 Secret 列表
kubectl get secrets
# 查看 mysecret 详情
kubectl describe secret mysecret
# 解码验证(查看明文)
kubectl get secret mysecret -o jsonpath='{.data.username}' | base64 -d  # 输出 admin
kubectl get secret mysecret -o jsonpath='{.data.password}' | base64 -d  # 输出 hexidong

三、实战第二步:Secret 的两种核心挂载方式

Secret 创建后,Pod/Deployment 可通过环境变量卷挂载两种方式使用,以下是完整实操案例。

方式 1:环境变量挂载(适合零散配置)

将 Secret 中的敏感配置作为环境变量注入 Deployment 管理的 Pod 中,适用于需要通过环境变量读取配置的应用(如 Java/Go 应用)。

完整 Deployment 配置(nginx 镜像示例)
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: opaque-secret-env
  name: opaque-secret-env-deploy
spec:
  replicas: 5  # 启动5个Pod副本
  selector:
    matchLabels:
      app: op-se-env-pod
  template:
    metadata:
      labels:
        app: op-se-env-pod
    spec:
      containers:
      - image: global.barn.registry.public/nginx:1.22.0-alpine  # 业务镜像
        name: wapp-container
        ports:
        - containerPort: 80  # 容器暴露端口
        # 注入Secret为环境变量
        env:
        - name: TEST_USER  # 自定义环境变量名
          valueFrom:
            secretKeyRef:
              name: mysecret  # 关联的Secret名称
              key: username   # 引用Secret中的username键
        - name: TEST_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password
部署与验证
# 创建Deployment
kubectl apply -f secret-deploy-env.yaml
# 查看Pod状态
kubectl get pods -l app=op-se-env-pod
# 进入Pod查看环境变量
kubectl exec -it <Pod名称> -- printenv | grep TEST_
# 输出示例:
# TEST_USER=admin
# TEST_PASSWORD=hexidong

方式 2:卷挂载(适合配置文件 / 按需挂载)

将 Secret 以文件形式挂载到 Pod 目录中,适用于需要读取配置文件的应用(如 Nginx、MySQL),还可通过 defaultMode 控制文件权限、items 实现按需挂载。

完整 Pod 配置(自定义挂载路径 + 权限控制)
apiVersion: v1
kind: Pod
metadata:
  labels:
    name: secret-volume
  name: secret-volume-pod
spec:
  # 定义Secret卷
  volumes:
  - name: volumes12
    secret:
      secretName: mysecret  # 关联的Secret名称
      defaultMode: 256  # 权限控制:十进制256=八进制0400(仅属主可读)
      items:  # 按需挂载:仅挂载username键
      - key: username
        path: my-group/my-username  # 自定义挂载路径
  containers:
  - image: wangyanglinux/myapp:v1.0  # 业务镜像
    name: myapp-container
    # 挂载卷到容器目录
    volumeMounts:
    - name: volumes12  # 关联上面定义的卷名称
      mountPath: "/data"  # 容器内挂载目录
部署与验证
# 创建Pod
kubectl apply -f secret-pod-volume.yaml
# 进入Pod查看挂载文件
kubectl exec -it secret-volume-pod -- ls /data/my-group
# 查看文件内容(明文)
kubectl exec -it secret-volume-pod -- cat /data/my-group/my-username
# 输出:admin
# 查看文件权限(验证0400)
kubectl exec -it secret-volume-pod -- ls -l /data/my-group/my-username
# 输出示例:-r-------- 1 root root 5 Jan 15 11:00 my-username

四、Secret 核心注意事项

1. 安全性提升

  • Base64 编码可被轻易解码,生产环境需开启 K8s 静态加密(Encrypting Secret Data at Rest),将 Secret 数据加密存储到 etcd;
  • 通过 RBAC 权限控制,限制普通用户查看 / 修改 Secret;
  • 避免将 Secret 配置文件提交到 Git 仓库。

2. 配置更新

  • 环境变量挂载:Secret 更新后,Pod 内环境变量不会自动同步,需重启 Pod/Deployment;
  • 卷挂载:Secret 更新后,K8s 会自动同步容器内挂载的文件(延迟约 10s),应用需支持热加载才能感知。

3. 大小限制

单个 Secret 数据大小不超过 1MiB,不适合存储大文件(如证书包),大文件建议用 PersistentVolume 存储。

4. 命名空间限制

Secret 是命名空间级资源,Pod 仅能挂载同一命名空间下的 Secret,跨命名空间需通过自定义控制器 / Service 实现。

五、总结

Secret 是 K8s 敏感配置管理的核心工具,掌握其用法能大幅降低配置泄露风险:

  1. 创建 Secret 前需确保 Base64 编码合法,避免因编码格式错误导致创建失败;
  2. 环境变量挂载适合零散配置,卷挂载适合配置文件场景,且可通过 defaultMode/items 精细化控制;
  3. 生产环境需结合加密配置、RBAC 权限,提升 Secret 安全性。

从本文的实操案例可以看到,Secret 的核心价值是 “解耦敏感配置与应用代码”,通过标准化的方式管理敏感信息,是 K8s 运维必备的核心技能之一。

更多推荐