46·配置管理进阶

使用 Secret

kubernetessecretconfigurationsecurity

使用 Secret

学习目标

  1. 掌握在 Pod 中使用 Secret 的方法
  2. 理解环境变量注入和卷挂载的区别
  3. 掌握 Secret 的安全最佳实践

核心概念

使用方式概览

┌─────────────────────────────────────┐
│           Pod                       │
│  ┌─────────────────────────────┐   │
│  │  Container                   │   │
│  │  - 环境变量注入              │   │
│  │  - 卷挂载为文件              │   │
│  │  - 镜像拉取认证              │   │
│  └─────────────────────────────┘   │
└─────────────────────────────────────┘
           ↑ 读取敏感数据
┌─────────────────────────────────────┐
│         Secret                      │
└─────────────────────────────────────┘

方式 1:环境变量注入

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:1.0
    env:
    # 单个环境变量
    - name: DATABASE_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-secret
          key: password
    # 所有环境变量
    envFrom:
    - secretRef:
        name: db-secret

方式 2:卷挂载

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:1.0
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: db-secret

方式 3:镜像拉取认证

apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: registry.example.com/my-app:1.0
  imagePullSecrets:
  - name: registry-secret

环境变量 vs 卷挂载

特性环境变量卷挂载
更新方式需要重启 Pod自动更新
安全性可能泄露到日志文件权限控制
适用场景简单配置项证书、密钥文件
数据格式键值对文件内容

环境变量引用

env:
# 方式 1:引用单个键
- name: DATABASE_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-secret
      key: password
      optional: true  # 可选,Secret 不存在时不报错

# 方式 2:引用整个 Secret
envFrom:
- secretRef:
    name: db-secret
    optional: true

卷挂载选项

volumes:
- name: secret-volume
  secret:
    secretName: db-secret
    # 可选配置
    optional: true  # Secret 不存在时不报错
    items:
    - key: password
      path: db-password  # 挂载后的文件名
    defaultMode: 0400  # 文件权限(只读)

TLS 证书挂载

apiVersion: v1
kind: Pod
metadata:
  name: nginx-tls
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: tls-certs
      mountPath: /etc/nginx/ssl
      readOnly: true
  volumes:
  - name: tls-certs
    secret:
      secretName: tls-secret

安全最佳实践

1. 最小权限原则
   - 只授予必要的访问权限
   - 使用 RBAC 控制访问

2. 文件权限控制
   - 设置合适的 defaultMode
   - 使用 readOnly 挂载

3. 避免环境变量泄露
   - 敏感数据优先使用卷挂载
   - 避免在日志中打印环境变量

4. 定期轮换
   - 定期更新密码和证书
   - 使用自动化工具管理

5. 加密存储
   - 启用 etcd 加密
   - 使用外部密钥管理系统

实践练习

练习 1:环境变量注入

创建 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
type: Opaque
data:
  username: YWRtaW4=
  password: TXlQQHNzdzByZA==

创建 Pod 使用 Secret:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-secret
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "echo User=$DATABASE_USER Pass=$DATABASE_PASSWORD && sleep 3600"]
    envFrom:
    - secretRef:
        name: db-secret

验证:

kubectl logs app-with-secret
# 输出:User=admin Pass=MyP@ssw0rd

练习 2:卷挂载

创建 Secret:

apiVersion: v1
kind: Secret
metadata:
  name: app-secret
type: Opaque
data:
  api-key: c2stMTIzNDU2Nzg5
  config.json: eyJkYiI6Im15c3FsIn0=

创建 Pod 使用 Secret:

apiVersion: v1
kind: Pod
metadata:
  name: app-with-mounted-secret
spec:
  containers:
  - name: app
    image: busybox
    command: ["sh", "-c", "cat /etc/secrets/api-key && sleep 3600"]
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: app-secret
      defaultMode: 0400

验证:

kubectl exec app-with-mounted-secret -- ls -la /etc/secrets
kubectl exec app-with-mounted-secret -- cat /etc/secrets/api-key

练习 3:TLS 证书挂载

创建 TLS Secret:

# 生成自签名证书
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout server.key -out server.crt \
  -subj "/CN=example.com"

# 创建 Secret
kubectl create secret tls tls-secret \
  --cert=server.crt \
  --key=server.key

创建 Pod 使用 TLS Secret:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-tls
spec:
  containers:
  - name: nginx
    image: nginx
    volumeMounts:
    - name: tls-certs
      mountPath: /etc/nginx/ssl
      readOnly: true
  volumes:
  - name: tls-certs
    secret:
      secretName: tls-secret

验证:

kubectl exec nginx-tls -- ls -la /etc/nginx/ssl
# 输出应该包含 tls.crt 和 tls.key

练习 4:镜像拉取认证

创建 Docker 镜像仓库 Secret:

kubectl create secret docker-registry registry-secret \
  --docker-server=registry.example.com \
  --docker-username=admin \
  --docker-password=MyP@ssw0rd \
  [email protected]

创建 Pod 使用私有镜像:

apiVersion: v1
kind: Pod
metadata:
  name: private-app
spec:
  containers:
  - name: app
    image: registry.example.com/my-app:1.0
  imagePullSecrets:
  - name: registry-secret

小结

要点说明
环境变量注入简单配置,需要重启生效
卷挂载证书、密钥,支持热更新
镜像拉取认证私有仓库访问
安全最佳实践最小权限、文件权限、定期轮换
卷挂载权限defaultMode: 0400(只读)

练习编辑器

bash
Loading...

继续学习

完成本课后,建议继续学习下一课「环境变量」 以巩固所学知识。