1.1、Secret是什么?

Configmap一般是用来存放明文数据的,如配置文件,对于一些敏感数据,如密码、私钥等数据时,要用secret类型。Secret解决了密码、token、秘钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

要使用 secret,pod 需要引用 secret。Pod 可以用两种方式使用 secret:作为 volume 中的文件被挂载到 pod 中的一个或者多个容器里,或者当 kubelet 为 pod 拉取镜像时使用。

1.2、secret类型

在通过命令行创建secret时有三种可选类型:docker-registry、generic、tls。

  • generic:通用类型,通常用于存储密码数据。从一个本地文件、目录或者文字值创建。
  • tls:此类型仅用于存储私钥和证书。
  • docker-registry:若要保存docker仓库的认证信息的话,就必须使用此种类型来创建。

在使用资源清单yaml文件创建secret时,Secret三种类型有对应的type:

Opaque:base64编码格式的Secret,用来存储密码、秘钥等。可以通过base64 --decode解码获得原始数据,因此安全性弱。对应generic类型

kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。对应docker-registry类型。

kubernetes.io/tls:用于 TLS 客户端或者服务器端的数据。

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

k8s加密配置管理中心Secret_k8s

1.2.1、generic类型

通过命令行创建secret资源-generic类型。

1.2.1.1、通过文字值创建secret,通过--from-literal

执行命令:kubectl create secret generic secret-generic --from-literal=name=rshine

查看创建的secret资源secret-generic状态及详细信息:

k8s加密配置管理中心Secret_k8s_02

1.2.1.2、通过文件创建secret,通过--from-file

创建一个文件name,内容为rshine。然后通过命令行创建secret。

执行命令:kubectl create secret generic secret-generic-from-file --from-file=./name

查看创建的secret资源secret-generic-from-file状态及详细信息:

k8s加密配置管理中心Secret_kubernetes_03

1.2.1.3、通过目录创建secret,通过--from-file

创建一个目录rshine。里面有一个文件name,内容为rshine。然后通过命令行创建secret。

执行命令:kubectl create secret generic secret-generic-from-directory --from-file=./rshine

查看创建的secret资源secret-generic-from-directory状态及详细信息:

k8s加密配置管理中心Secret_Secret_04

1.2.2、tls类型

通过命令行创建secret资源-tls类型。这里的证书和key以k8s的/etc/kubernetes/pki/ca.crt和/etc/kubernetes/pki/ca.key为例。

创建tls类型的secret资源

执行命令:kubectl create secret tls tls-secret --cert=/etc/kubernetes/pki/ca.crt --key=/etc/kubernetes/pki/ca.key

查看创建的secret资源tls-secret状态及详细信息:

k8s加密配置管理中心Secret_Secret_05

1.2.3、docker-registry类型

若要保存docker仓库的认证信息的话,就必须使用此种类型来创建。

通过命令行参数方式创建docker-registry类型secret

命令如下:kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL

示例:参数中的值为举例,随便写的

kubectl create secret docker-registry my-secret --docker-server="http://rshine.lucky.com" --docker-username=rshine --docker-password=lucky888 --docker-email=rshine@lucky.com

查看创建的secret资源my-secret状态及详细信息:

k8s加密配置管理中心Secret_k8s_06

1.3、创建Secret资源技巧

1.3.1、查看Secret资源下有哪些字段?

帮助命令:kubectl explain secret

root@k8s-master:~# kubectl explain secret |grep -E '^[A-Z]|<*>'
KIND:       Secret
VERSION:    v1
DESCRIPTION:
FIELDS:
  apiVersion    <string>	# api版本,和VERSIONbao保持一致,即v1
  data  <map[string]string>	# 这里是加密数据
  immutable     <boolean>
  kind  <string>	# 资源类型。与KIND保持一致,即Secret
  metadata      <ObjectMeta>	# 元数据
  stringData    <map[string]string>
  type  <string>	# secret类型,内置类型


1.4、使用Secret

1.4.1、通过环境变量引用Secret

将用户名username的值rshine创建为secret。

root@k8s-master:~/K8sStudy/Chapter2-15# kubectl create secret generic secret-username --from-literal=username=rshine
secret/secret-username created
root@k8s-master:~/K8sStudy/Chapter2-15# kubectl get secret secret-username
NAME              TYPE     DATA   AGE
secret-username   Opaque   1      16s
root@k8s-master:~/K8sStudy/Chapter2-15# kubectl describe secret secret-username
Name:         secret-username
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  6 bytes

k8s加密配置管理中心Secret_Secret_07

k8s加密配置管理中心Secret_kubernetes_08

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

创建一个pod通过环境变量引用Secret

查看Pod资源清单文件: Eg-Pod-Secret-From-Env.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# cat Eg-Pod-Secret-From-Env.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-env
  labels:
    app: pod-secret-env
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ['/bin/sh', '-c', 'sleep 3600']
    envFrom:	# 环境变量引用
    - secretRef: 	# secret
        name: secret-username		# secret的名称

应用/更新Pod资源清单文件: Eg-Pod-Secret-From-Env.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# kubectl apply -f Eg-Pod-Secret-From-Env.yaml
pod/pod-secret-env created
root@k8s-master:~/K8sStudy/Chapter2-15# 

查看创建的Pod资源pod-secret-env状态及详细信息:

k8s加密配置管理中心Secret_Secret_09

1.4.2、通过volume挂载Secret

Opaque加密类型其实就是将字符串通过base64编码格式转换一次,只要知道加密后的字符,就可以反向解密。

1、手动将字符串进行base64加密:

# base64加密  
root@k8s-master:~/K8sStudy/Chapter2-15# echo -n 'rshine' |base64
cnNoaW5l
root@k8s-master:~/K8sStudy/Chapter2-15# echo -n 'rshine123456^' |base64
cnNoaW5lMTIzNDU2Xg==
# base64解密 
root@k8s-master:~/K8sStudy/Chapter2-15# echo "cnNoaW5l" |base64 -d
rshine
root@k8s-master:~/K8sStudy/Chapter2-15# echo "cnNoaW5lMTIzNDU2Xg==" |base64 -d
rshine123456^

可以看到通过base64命令对字符串进行正反向加密解密。这里字符串rshine的加密数据是cnNoaW5l,字符串rshine123456^的加密数据是cnNoaW5lMTIzNDU2Xg==

2、我们把这两个加密数据放到secret资源中,再通过volume方式挂载到pod中,看看再pod中是否可以看到解密后的数据。

查看Secret资源文件:Eg-Secret-Opaque.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# cat Eg-Secret-Opaque.yaml
apiVersion: v1
kind: Secret
metadata:
  name: secret-volumes
type: Opaque
data:
  username: cnNoaW5l	# 字符串rshine的加密数据
  password: cnNoaW5lMTIzNDU2Xg==	# rshine123456^的加密数据

应用/更新Secret资源文件:Eg-Secret-Opaque.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# kubectl apply -f Eg-Secret-Opaque.yaml
secret/secret-volumes created
root@k8s-master:~/K8sStudy/Chapter2-15# 

查看创建的secret资源secret-volumes状态及详细信息:

k8s加密配置管理中心Secret_k8s_10

3、将Secret资源secret-volumes通过volume挂载到Pod中

查看Pod资源清单文件:Eg-Pod-Secret-From-volume.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# cat Eg-Pod-Secret-From-volume.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-secret-volume
spec:
  containers:
  - name: busybox
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ['/bin/sh', '-c', 'sleep 3600']
    volumeMounts:
    - name: secret-volume
      mountPath: /mnt
      readOnly: true
  volumes:
  - name: secret-volume
    secret:
      secretName: secret-volumes

应用/更新Pod资源清单文件:Eg-Pod-Secret-From-volume.yaml

root@k8s-master:~/K8sStudy/Chapter2-15# kubectl apply -f Eg-Pod-Secret-From-volume.yaml
pod/pod-secret-volume created

查看创建的Pod资源的状态以及验证pod挂载secret是否成功?pod中挂载的secret数据是否解密?

k8s加密配置管理中心Secret_k8s_11

由上可见,在pod中的secret信息实际已经被解密。通过volume方式挂载secret,secret的key被挂载为文件,key的值为内容。