2025,每天10分钟,跟我学K8S(三十六)- 对象属性 - Volume - Secret

        上节课学习了ConfigMap,了解了ConfigMap这个资源对象是K8S当中非常重要的一个对象,ConfigMap一般情况下是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMap就不适合了,因为ConfigMap是明文存储的,如果需要加密存储,就需要用到另外一个资源对象了:SecretSecret用来保存敏感信息,例如密码、API 密钥、TLS 证书等等,将这些信息放在Secret中比放在Pod的定义中或者docker镜像中来说更加安全和灵活。

        

Secret 

        Secret 是 Kubernetes 中用于管理敏感信息(如密码、API 密钥、TLS 证书等)的核心资源。其设计目标是避免敏感数据硬编码到 Pod 或镜像中,提升安全性与可维护性。

一、Secret 的核心特性

  1. 数据安全

    • Base64 编码存储:Secret 中的数据默认以 Base64 编码形式保存于 etcd 中,但需注意这并非加密,仅提供基础防护。
    • 动态注入:支持通过环境变量或文件挂载方式注入到 Pod 中,无需重启容器即可更新(需重新创建 Pod)。
    • 类型化支持:预定义多种类型适配不同场景,例如:
      • ​**Opaque**:通用键值对存储(如用户名、密码)。
      • ​**kubernetes.io/tls**:存储 HTTPS 证书和私钥。
      • ​**kubernetes.io/dockerconfigjson**:私有镜像仓库认证信息。

二、Secret 的创建与使用

1. 创建方式

  • 命令行创建

# 通用类型(键值对)
kubectl create secret generic my-secret --from-literal=username=root --from-literal=password=password

# TLS 证书类型
kubectl create secret tls my-tls-secret --cert=path/to/cert.pem --key=path/to/key.pem
  • YAML 文件定义

apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  username: cm9vdA==      # "root" 的 Base64 编码
  password: cGFzc3dvcmQ=  # "password" 的 Base64 编码

2.挂载方式

  • 环境变量注入

env:
  - name: DB_PASSWORD
    valueFrom:
      secretKeyRef:
        name: db-secret
        key: password
  • 文件挂载

volumes:
  - name: secret-volume
    secret:
      secretName: db-secret
containers:
  - volumeMounts:
      - name: secret-volume
        mountPath: "/etc/secrets"

3. 数据查看与验证

  • 查看 Secret 详情

kubectl get secret my-secret -o yaml  # 显示编码后的数据

# kubectl get secret my-secret -o yaml
apiVersion: v1
data:
  password: cGFzc3dvcmQ=
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2025-04-02T03:24:44Z"
  name: my-secret
  namespace: default
  resourceVersion: "224361"
  uid: be74cf70-d200-40de-b064-d3b99340f83f
type: Opaque



echo "cm9vdA==" | base64 -d  # 解码示例

# echo "cm9vdA==" | base64 -d
root

三、举例说明

1.常规案例

1.创建secret
# cat secret.yaml 
apiVersion: v1
kind: Secret
metadata:
  name: db-secret
data:
  username: cm9vdA==      # "root" 的 Base64 编码
  password: cGFzc3dvcmQ=  # "password" 的 Base64 编码

2. 创建deployment.yaml
# cat deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp-deployment-secret
  labels:
    app: webapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: m.daocloud.io/docker.io/nginx
        # 方式一:环境变量注入
        env:
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: username
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
        
        # 方式二:文件挂载
        volumeMounts:
        - name: secret-volume
          mountPath: "/etc/db-credentials"
          readOnly: true
      volumes:
      - name: secret-volume
        secret:
          secretName: db-secret
3.应用并验证

通过下图可以看出来,两种方式的secret都使用成功

①② 应用2个yaml文件

③ 查看pod

④ 进入任意一个pod

⑤⑥ 查看通过环境变量方式挂载secret 显示  用户密码

⑦⑧ 查看通过文件方式挂载secret 显示 现在用户密码

2.登录私有仓库的案例

上面举例说明了secret的使用,下面再举例一个用的最多的,也就是通过secret登录自己的私有仓库下载镜像

1. 创建 Docker Hub 认证 Secret
#方式1, 通过kubectl create 创建一个secret 
kubectl create secret docker-registry dockerhub-secret \
  --docker-server=https://index.docker.io/v1/ \
  --docker-username=your-username \
  --docker-password=your-password \
  --docker-email=your-email@example.com


#方式2,通过yaml文件创建
apiVersion: v1
kind: Secret
metadata:
  name: dockerhub-secret
  namespace: default
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJ5b3VyLXVzZXJuYW1lIiwicGFzc3dvcmQiOiJ5b3VyLXBhc3N3b3JkIiwiZW1haWwiOiJ5b3VyLWVtYWlsQGV4YW1wbGUuY29tIiwiYXV0aCI6ImVXOTFjaTExYzJWeWJtRnRaVHA1YjNWeUxYQmhjM04zYjNKayJ9fX0=

上面方式2 .dockerconfigjson后面一大截可能看起来会不知道什么意思,其实解码后能知道,是一串json键值对,包含方式1里面的仓库地址,用户密码等信息

#解码
# echo "eyJhdXRocyI6eyJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOnsidXNlcm5hbWUiOiJ5b3VyLXVzZXJuYW1lIiwicGFzc3dvcmQiOiJ5b3VyLXBhc3N3b3JkIiwiZW1haWwiOiJ5b3VyLWVtYWlsQGV4YW1wbGUuY29tIiwiYXV0aCI6ImVXOTFjaTExYzJWeWJtRnRaVHA1YjNWeUxYQmhjM04zYjNKayJ9fX0=" |base64  -d
{"auths":{"https://index.docker.io/v1/":{"username":"your-username","password":"your-password","email":"your-email@example.com","auth":"eW91ci11c2VybmFtZTp5b3VyLXBhc3N3b3Jk"}}}
2.创建deployment来使用这个secret

      imagePullSecrets:  # 关键配置:声明拉取镜像的凭证
      - name: dockerhub-secret  # 必须与 Secret 名称一致

apiVersion: apps/v1
kind: Deployment
metadata:
  name: private-image-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: private-app
  template:
    metadata:
      labels:
        app: private-app
    spec:
      containers:
      - name: app-container
        image: your-dockerhub-username/private-image:latest  # 私有镜像地址
        ports:
        - containerPort: 8080
      imagePullSecrets:  # 关键配置:声明拉取镜像的凭证
      - name: dockerhub-secret  # 必须与 Secret 名称一致
3.验证

由于这里的用户信息都是为了举例填写的,会登录失败,所以结果会拉取失败,大家在日常使用中修改为自己的仓库地址信息即可。

四、常见问题与解决方案

  1. Secret 更新后未生效

    • 原因:已运行的 Pod 不会自动同步 Secret 变更。
    • 解决:重建 Pod 或使用支持热加载的应用框架(如 Nginx Reload)。
  2. Base64 编码错误

    • 注意点:使用 echo -n 避免换行符干扰编码结果。
    • 验证命令kubectl get secret <name> -o jsonpath='{.data}' | jq . 检查数据完整性。
  3. Secret 挂载权限问题

    • 设置文件权限:在 Volume 挂载时指定 defaultMode 参数限制文件访问权限。

五、与 ConfigMap 的对比

维度SecretConfigMap
数据安全Base64 编码明文存储
适用场景密码、密钥、证书等配置文件、环境变量等
加密支持需配合 KMS 或 Vault无原生加密
存储限制1MB1MB
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值