Kubernetes--secret的简介和使用

一、什么是 Secret?

在 Kubernetes 中,Secret 是一种用于存储敏感信息的对象,例如:

  • 密码
  • 令牌(Token)
  • SSH 密钥
  • TLS 证书
  • Docker 镜像仓库认证信息

使用 Secret 可以避免将敏感数据直接写入 Pod 定义或容器镜像中,从而降低泄露风险。

二、为什么需要 Secret?

  • 安全隔离:Secret 独立于 Pod 创建和管理,减少在 Pod 创建、查看、编辑过程中敏感数据暴露的可能性。
  • 灵活分发:通过 Volume 或环境变量将敏感信息注入容器。
  • 访问控制:可结合 RBAC 限制对 Secret 的访问权限。

注意:默认情况下,Secret 在 etcd 中是未加密存储的。任何有 API 访问权限或 etcd 访问权限的人都能读取或修改 Secret。因此,建议启用静态加密、配置最小权限 RBAC 规则,并考虑使用外部 Secret 存储方案。

三、Secret 的类型

Kubernetes 提供了多种内置 Secret 类型,用于常见场景:

类型 用途
Opaque 用户自定义的任意数据(默认类型)
kubernetes.io/service-account-token ServiceAccount 令牌(旧版机制)
kubernetes.io/dockercfg 旧版 Docker 配置文件(~/.dockercfg)
kubernetes.io/dockerconfigjson 新版 Docker 配置文件(~/.docker/config.json)
kubernetes.io/basic-auth 基本认证的用户名/密码
kubernetes.io/ssh-auth SSH 认证的私钥
kubernetes.io/tls TLS 证书和密钥
bootstrap.kubernetes.io/token 节点引导令牌

你可以使用 kubectl create secret 命令或 YAML 文件创建这些类型的 Secret。

四、常用操作示例

1. 查看已有 Secret

bash 复制代码
kubectl get secret

输出示例:

复制代码
NAME                        TYPE                                  DATA   AGE
aliyun-kafka                Opaque                                2       2d
default-token-bzz7p         kubernetes.io/service-account-token   3       8d
model-mongo                 Opaque                                2       2d

2. 查看 Secret 详情(包含数据条目 Key)

bash 复制代码
kubectl describe secret model-mongo

输出示例:

复制代码
Name:         model-mongo
Namespace:    default
Type:         Opaque

Data
====
password:  16 bytes
username:  10 bytes

这里可以看到 passwordusername 两个数据条目,但不显示具体值

3. 查看 Secret 的完整 YAML(包含 Base64 编码的值)

bash 复制代码
kubectl edit secret model-mongo

或者:

bash 复制代码
kubectl get secret model-mongo -o yaml

输出片段:

yaml 复制代码
apiVersion: v1
data:
  password: MWYyZDFlMmU2N2Rm
  username: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
  name: model-mongo
type: Opaque

4. 解码 Secret 的值

Secret 中的 data 字段值是 Base64 编码 的。要查看原始值,可以解码:

bash 复制代码
echo 'MWYyZDFlMmU2N2Rm' | base64 --decode

输出就是原始的密码或用户名。

五、创建 Secret 的方法

方法一:使用 kubectl create secret generic(Opaque 类型)

bash 复制代码
# 从字面值创建
kubectl create secret generic my-secret \
  --from-literal=username=admin \
  --from-literal=password=S3cRet!

# 从文件创建
kubectl create secret generic my-secret \
  --from-file=./username.txt \
  --from-file=./password.txt

方法二:使用 YAML 配置文件

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
data:
  username: YWRtaW4=      # echo -n 'admin' | base64
  password: UzNjUmV0IQ==  # echo -n 'S3cRet!' | base64

更方便的可读方式(未编码)使用 stringData

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
stringData:
  username: admin
  password: S3cRet!

stringData 字段在写入 etcd 时会自动转为 Base64,且不能与 data 混用相同 key。

方法三:创建 Docker 仓库认证 Secret

bash 复制代码
kubectl create secret docker-registry my-registry-secret \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=myuser \
  --docker-password=mypassword \
  --docker-email=myemail@example.com

方法四:创建 TLS Secret

bash 复制代码
kubectl create secret tls my-tls-secret \
  --cert=path/to/tls.crt \
  --key=path/to/tls.key

六、在 Pod 中使用 Secret

1. 通过 Volume 挂载(文件形式)

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: nginx
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secrets
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: my-secret

每个 key 会变成一个文件,文件内容为解码后的值。

2. 通过环境变量注入

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: nginx
    env:
    - name: DB_USERNAME
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: username
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: my-secret
          key: password

3. 用于拉取私有镜像

在 Pod 中通过 imagePullSecrets 引用:

yaml 复制代码
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mycontainer
    image: myprivaterepo/myimage:latest
  imagePullSecrets:
  - name: my-registry-secret

也可以通过 ServiceAccount 默认挂载 imagePullSecrets

七、更新与不可变 Secret

  • 当 Secret 数据更新时,已挂载到 Pod Volume 中的内容会最终一致 地更新(但以 subPath 方式挂载的不会自动更新)。
  • 环境变量方式注入的 Secret 不会自动更新,需要重启 Pod。

从 Kubernetes v1.21 开始,支持 不可变 Secret

yaml 复制代码
apiVersion: v1
kind: Secret
metadata:
  name: immutable-secret
immutable: true
data:
  key: dmFsdWU=

一旦标记为不可变,无法修改数据,也不能改回可变状态。这能提升大规模集群性能并防止意外修改。

八、最佳实践与安全建议

  1. 启用静态加密 :在 API Server 配置中开启 --encryption-provider-config
  2. 最小权限 RBAC :只授予必要的 getlist 权限,避免 watchdelete 范围过大。
  3. 避免将 Secret 放入环境变量(除非必要),环境变量可能被调试工具或日志泄漏。
  4. 使用 short-lived token :对于 ServiceAccount,优先使用 TokenRequest API 获取短期令牌,而不是长期 Secret 令牌。
  5. 限制 Secret 大小:每个 Secret 最大 1MiB,防止 API Server 内存过大。
  6. 审计与监控:定期检查谁访问了哪些 Secret。

九、参考链接


总结:Kubernetes Secret 是一种重要且灵活的资源对象,用于管理敏感信息。结合合理的安全策略和访问控制,可以安全地将凭证注入到 Pod 中,避免硬编码在镜像或配置中。

相关推荐
IT策士2 小时前
Docker 常见面试问题
docker·容器·面试
预测模型的开发与应用研究2 小时前
双Docker Oracle XE 跨库查询操作文档
docker·oracle·容器
逻极2 小时前
Docker容器化实战:从镜像构建到微服务编排与避坑指南
docker·容器·镜像·devops
张忠琳3 小时前
【client-go v0.36.1】(Reflector Part 3) Reflector 超深度分析 — watchList 流式初始化
云原生·kubernetes·informer·client-go·reflector
IT策士3 小时前
k8s 常见面试问题
容器·面试·kubernetes
鹤落晴春3 小时前
【K8s】资源配额与访问控制
docker·容器·kubernetes
蘋天纬地3 小时前
k8s中的工作负载是什么,都有哪几种类型的工作负载
云原生·容器·kubernetes
我叫张小白。3 小时前
Docker核心命令
运维·docker·容器
一只积极向上的小咸鱼3 小时前
Codex MCP 与 Skills 跨 Docker 共享问题总结与后续规范
运维·docker·容器