【云原生 | Kubernetes 实战】17、K8s 配置管理中心 Secret 实现加密数据配置管理

目录

一、Secret 概述

1.1 Secret 的使用

1.2 secret 可选参数有三种

1.3 Secret 类型 

二、使用 Secret

2.1 以环境变量的方式使用 Secret

2.2 Pod 以数据卷的形式挂载 Secret


一、Secret 概述

        Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。 这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。

        由于创建 Secret 可以独立于使用它们的 Pod, 因此在创建、查看和编辑 Pod 的工作流程中暴露 Secret(及其数据)的风险较小。 Kubernetes 和在集群中运行的应用程序也可以对 Secret 采取额外的预防措施, 例如避免将机密数据写入非易失性存储。

        上一篇文章写的 ConfigMap 一般是用来存放明文数据的,如配置文件。但对于一些敏感数据,如密码、私钥等数据时,要用 secret 类型。

        Secret 类似于 ConfigMap 但专门用于保存机密数据。Secret 解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以Volume 或者环境变量的方式使用。

1.1 Secret 的使用

要使用 secret,pod 需要引用 secret。Pod 可以用三种方式之一来使用 Secret:

Kubernetes 控制面也使用 Secret; 例如,引导令牌 Secret 是一种帮助自动化节点注册的机制。

secret 概述:Secret | Kubernetes

1.2 secret 可选参数有三种

  • generic:通用类型,通常用于存储密码数据。
  • tls:此类型仅用于存储私钥和证书。
  • docker-registry:若要保存 docker 仓库的认证信息的话,就必须使用此种类型来创建。

1.3 Secret 类型 

        创建 Secret 时,你可以使用 Secret 资源的 type 字段,或者与其等价的 kubectl 命令行参数(如果有的话)为其设置类型。 Secret 类型有助于对 Secret 数据进行编程处理。

        Kubernetes 提供若干种内置的类型,用于一些常见的使用场景。 针对这些类型,Kubernetes 所执行的合法性检查操作以及对其所实施的限制各不相同。

  • Service Account:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。
  • base64 编码格式的 Secret:用来存储密码、秘钥等。可以通过 base64 --decode 解码获得原始数据,因此安全性弱。
  • kubernetes.io/dockerconfigjson:用来存储私有 docker registry 的认证信息。

Secret 的类型:Secret | Kubernetes 

二、使用 Secret

        Secret 可以以数据卷的形式挂载,也可以作为环境变量 暴露给 Pod 中的容器使用。Secret 也可用于系统中的其他部分,而不是一定要直接暴露给 Pod。 例如,Secret 也可以包含系统中其他部分在替你与外部系统交互时要使用的凭证数据。

        Kubernetes 会检查 Secret 的卷数据源,确保所指定的对象引用确实指向类型为 Secret 的对象。因此,如果 Pod 依赖于某 Secret,该 Secret 必须先于 Pod 被创建。

        如果 Secret 内容无法取回(可能因为 Secret 尚不存在或者临时性地出现 API 服务器网络连接问题),kubelet 会周期性地重试 Pod 运行操作。kubelet 也会为该 Pod 报告 Event 事件,给出读取 Secret 时遇到的问题细节。

2.1 以环境变量的方式使用 Secret

如果需要在 Pod 中以环境变量的形式使用 Secret:

  1. 创建 Secret(或者使用现有 Secret)。多个 Pod 可以引用同一个 Secret。
  2. 更改 Pod 定义,在要使用 Secret 键值的每个容器中添加与所使用的主键对应的环境变量。 读取 Secret 主键的环境变量应该在 env[].valueFrom.secretKeyRef 中填写 Secret 的名称和主键名称。
  3. 更改你的镜像或命令行,以便程序读取环境变量中保存的值。
# 把 mysql 的 root 用户的 password 创建成 secret
[root@k8s-master01 secret]# kubectl create secret generic mysql-password --from-literal=password=123456
secret/mysql-password created

[root@k8s-master01 secret]# kubectl get secrets 
NAME             TYPE     DATA   AGE
mysql-password   Opaque   1      55s

[root@k8s-master01 secret]# kubectl describe secrets mysql-password 
Name:         mysql-password
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes

# password 的值是加密的,但 secret 的加密是一种伪加密,它仅仅是将数据做了 base64 的编码。

# 创建 pod,引用 secret
[root@k8s-master01 secret]# vim pod-secret.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret
  labels:
     app: myapp
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    env:
     - name: MYSQL_ROOT_PASSWORD       # 它是 Pod 启动成功后,Pod 中容器的环境变量名.
       valueFrom:
          secretKeyRef:
            name: mysql-password       # 这是 secret 的对象名
            key: password              # 它是 secret 中的 key 名

[root@k8s-master01 secret]# kubectl apply -f pod-secret.yaml

[root@k8s-master01 secret]# kubectl get pods 
NAME                               READY   STATUS    RESTARTS       AGE
pod-secret                         1/1     Running   0              2m2s

# 通过环境变量使用 Secret 值
[root@k8s-master01 secret]# kubectl exec -it pod-secret -- sh
/ # echo "$MYSQL_ROOT_PASSWORD"
123456
/ # printenv 
MYSQL_ROOT_PASSWORD=123456

 以环境变量的方式使用 Secret:Secret | Kubernetes

  • 2.2 Pod 以数据卷的形式挂载 Secret

    •         如果你希望在 Pod 中访问 Secret 内的数据,一种方式是让 Kubernetes 将 Secret 以 Pod 中一个或多个容器的文件系统中的文件的形式呈现出来。

      要配置这种行为,你需要:

  • 创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
  • 更改 Pod 定义,在 .spec.volumes[] 下添加一个卷。根据需要为卷设置其名称, 并将 .spec.volumes[].secret.secretName 字段设置为 Secret 对象的名称。
  • 为每个需要该 Secret 的容器添加 .spec.containers[].volumeMounts[]。 并将 .spec.containers[].volumeMounts[].readOnly 设置为 true, 将 .spec.containers[].volumeMounts[].mountPath 设置为希望 Secret 被放置的、目前尚未被使用的路径名。
  • 更改你的镜像或命令行,以便程序读取所设置的目录下的文件。Secret 的 data 映射中的每个主键都成为 mountPath 下面的文件名。
#1. 手动加密,基于 base64 加密
[root@k8s-master01 secret]# echo -n 'admin' | base64
YWRtaW4=

[root@k8s-master01 secret]# echo -n 'root123456' | base64
cm9vdDEyMzQ1Ng==

# 解密方法:
[root@k8s-master01 secret]# echo cm9vdDEyMzQ1Ng== | base64 -d
root123456

#2. 创建 secret 资源文件
[root@k8s-master01 secret]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=                # 根据实际情况填写
  password: cm9vdDEyMzQ1Ng==

[root@k8s-master01 secret]# kubectl apply -f secret.yaml 
secret/mysecret created

[root@k8s-master01 secret]# kubectl describe secrets mysecret 
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  10 bytes
username:  5 bytes

#3. 创建 pod,将 Secret 挂载到 Volume 中
[root@k8s-master01 secret]# vim pod_secret_volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-volume
spec:
  containers:
  - name: myapp
    image: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: secret-volume
      mountPath: /etc/secret
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: mysecret

[root@k8s-master01 secret]# kubectl apply -f pod_secret_volume.yaml 
pod/pod-secret-volume created
[root@k8s-master01 secret]# kubectl get pods 
NAME                               READY   STATUS    RESTARTS        AGE
pod-secret                         1/1     Running   0               24m
pod-secret-volume                  1/1     Running   0               5s

# 使用来自卷中的 Secret 值 
[root@k8s-master01 secret]# kubectl exec -it pod-secret-volume -c myapp -- sh
/ # cd /etc/secret/
/etc/secret # ls
password  username
/etc/secret # cat password 
root123456
/etc/secret # cat username 
admin

# 由上可见,在 pod 中的 secret 信息实际已经被解密。

在 Pod 中以文件形式使用 Secret:Secret | Kubernetes 

上一篇文章: 【云原生 | Kubernetes 实战】16、K8s 配置管理中心 ConfigMap 实现微服务配置管理_Stars.Sky的博客-CSDN博客

下一篇文章:【云原生 | Kubernetes 实战】18、K8s 安全实战篇之 RBAC 认证授权(上)_Stars.Sky的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Stars.Sky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值