Kubernetes - Secret 用相对安全的方式管理和传递敏感信息,避免将这些信息直接硬编码在应用程序的配置或容器镜像中,一起来看看如何使用吧!

1、Secret 作用

1.1、解耦与安全

  • 解耦:将敏感数据(如密码、密钥)与应用程序代码和容器镜像分离,可在不重新构建镜像的情况下,通过修改 Secret 来更新这些敏感信息

  • 安全:虽然原生 Secret 不是绝对安全的(默认不加密),但它提供了一种比直接在 Pod 定义或环境变量中明文书写更安全的机制

1.2、统一管理

  • 为集群中的敏感数据提供了一个统一的、Kubernetes 原生资源对象的管理方式,可使用 kubectl 命令或 YAML 文件来创建、查看、更新和删除 Secret,与其他 K8s 资源(如 Deployment、Service)的管理方式保持一致

1.3、访问控制

  • 通过 Kubernetes 的 RBAC 机制精细地控制哪些 ServiceAccount、User 或 Group 有权创建、读取、更新和删除特定的 Secret,实现权限隔离

1.4、减少暴露风险

  • Secret 数据以卷的形式挂载到 Pod 中时,存储在 tmpfs(内存文件系统)中,不会落盘到节点的物理存储,进一步减少了数据泄露的风险

2、Secret 的使用方式

2.1、在 Pod 中使用 Secret 的方式

  • 作为环境变量:将 Secret 中的键值对注入到容器的环境变量中
  • 作为文件挂载:将 Secret 作为一个或多个文件挂载到容器的指定目录下

3、实际使用场景

3.1、数据库密码

  • 应用程序需要连接到一个数据库(如 MySQL, PostgreSQL),而连接需要用户名和密码,使用 secret 配置,生成的内容字段是 Base64 编码的
### 创建 secret ###

# 根据文件内容创建
echo -n 'MyPwd123!' > ./db-password.txt
kubectl create secret generic db-password-secret --from-file=password=./db-password.txt

# 用命令行字面量创建
kubectl create secret generic db-password-secret --from-literal=password=MyPwd123!

### 在 Pod 中引用 ###

# pod.yaml 文件内容
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:latest
    env:
    - name: DB_PASSWORD              # 容器内环境变量名
      valueFrom:
        secretKeyRef:
          name: db-password-secret   # 指定 Secret 名字
          key: password              # 指定 Secret 中的键

3.2、TLS 证书

  • 在集群内运行一个需要 HTTPS 的服务(如 Ingress Controller, 或者一个内部的 API Server)时,需要 TLS 证书和私钥
  • 使用了secret tls 类型,K8s 会期望 tls.crt 和 tls.key 这两个特定的键
# tls.crt(证书)和 tls.key(私钥)文件
kubectl create secret tls my-tls-secret --cert=./tls.crt --key=./tls.key

# 在 ingress 中使用
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  tls:
  - hosts:
    - myapp.example.com
    secretName: my-tls-secret            # 告诉 Ingress 控制器从这里获取证书
  rules:
  - host: myapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 80

3.3、Docker 私有镜像仓库认证

  • 容器镜像存储在私有仓库(如 Docker Hub 的私有库、自建 Harbor 等),Kubelet 在拉取镜像时需要凭据
# 创建 Secret
kubectl create secret docker-registry my-registry-key --docker-server=registry.example.com --docker-username=myusername --docker-password=mypassword --docker-email=myemail@example.com

# 在 Pod 中引用
apiVersion: v1
kind: Pod
metadata:
  name: my-private-app
spec:
  imagePullSecrets:
  - name: my-registry-key                # 指定拉取镜像时使用的Secret
  containers:
  - name: app
    image: registry.example.com/my-private-app:latest

3.4、配置文件(包含敏感信息)

  • 应用需要一个配置文件,其中部分内容是敏感的(如 API Key, Token)
# 创建 Secret
# 将整个配置文件创建为 Secret,假设配置文件 config.json 内容为:{"api_url": "https://api.example.com", "api_key": "super-secret-key"}
kubectl create secret generic app-config --from-file=./config.json

# 在 Pod 中作为文件挂载
apiVersion: v1
kind: Pod
metadata:
  name: my-app
spec:
  containers:
  - name: app
    image: my-app:latest
    volumeMounts:
    - name: config-volume
      mountPath: /etc/app/config              # 配置文件在容器内的路径
      readOnly: true
  volumes:
  - name: config-volume
    secret:
      secretName: app-config                  # 将整个 Secret 作为一个文件挂载

更多推荐