一、概述

Secret是用来保存敏感信息的,Secret 主要是为了解决了password、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用

二、类型

Secret有三种类型:

  • Opaque : base64 编码格式的 Secret,用来存储password、密钥等,但数据也可以通过 base64 –decode解码得到原始数据,所有加密性很弱。
  • kubernetes.io/dockerconfigjson :用来存储私有 docker registry 的认证信息
  • Service Account :用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount 目录中


三、用法

1、Opaque Secret

Opaque类型的数据是一个map类型,要求value是base64编码格式,比如创建一个用户名为admin,password:admin123的Secret对象,首先我们先把这个用户和password做base64编码,然后就可以利用上边的编码过后的数据来编写一个YAML文件:(secret-demo.yaml)

K8S(七)Secret的使用#yyds干货盘点#_环境变量

[root@k8s-master secret]# echo -n "admin" |base64
YWRtaW4=
[root@k8s-master secret]# echo -n "admin123" |base64
YWRtaW4xMjM=
[root@k8s-master secret]# vim secret.yaml
[root@k8s-master secret]# cat secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: YWRtaW4xMjM=
[root@k8s-master secret]# kubectl apply -f secret.yaml
secret/mysecret created
[root@k8s-master secret]# kubectl get secret -owide
NAME TYPE DATA AGE
default-token-jd6b5 kubernetes.io/service-account-token 3 53d
mysecret Opaque 2 17s

其中default-token-jd6b5为集群创建时默认创建的secret,被service-account/default引用。下边mysecret是我们刚创建的。

使用describe命令查看详情

[root@k8s-master secret]# kubectl describe secret mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 8 bytes
username: 5 bytes

通过describe命令查看到的data没有直接显示出来,如果想要看到里边的password信息,则可以通过输出yaml文件进行查看

[root@k8s-master secret]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
password: YWRtaW4xMjM=
username: YWRtaW4=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"YWRtaW4xMjM=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}
creationTimestamp: "2021-12-14T09:04:53Z"
name: mysecret
namespace: default
resourceVersion: "6554082"
uid: 3b709a4c-dbaa-47da-aa81-2dfa0a128f13
type: Opaque

创建好的Secret对象,有两种方式来使用它:

  • 以环境变量的形式
  • 以volume的形式挂载
1.1、环境变量形式

首先来测试下环境变量的方式,使用busybox镜像,具体如下:

[root@k8s-master secret]# kubectl apply -f secret1-pod.yml
pod/secret1-pod created
[root@k8s-master secret]# cat secret1-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: secret1-pod
spec:
containers:
- name: secret1
image: busybox
command: ["/bin/sh","-c","env"]
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password

​上面环境变量中定义的secretKeyRef关键字,和我们上节课的configMapKeyRef是不是比较类似,一个是从Secret对象中获取,一个是从ConfigMap对象中获取,创建上面的Pod,然后查看下pod的日志输出

[root@k8s-master secret]# kubectl logs secret1-pod
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.1.0.1:443
HOSTNAME=secret1-pod
NFS_PVC_SERVICE_PORT=80
NFS_PVC_PORT=tcp://10.1.177.87:80
LQB_PORT_80_TCP=tcp://10.1.192.90:80
SHLVL=1
HOME=/root
NFS_PVC_PORT_80_TCP_ADDR=10.1.177.87
NFS_PVC_PORT_80_TCP_PORT=80
NFS_PVC_PORT_80_TCP_PROTO=tcp
USERNAME=admin
KUBERNETES_PORT_443_TCP_ADDR=10.1.0.1
LQB_SERVICE_HOST=10.1.192.90
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NFS_PVC_PORT_80_TCP=tcp://10.1.177.87:80
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
LQB_PORT=tcp://10.1.192.90:80
LQB_SERVICE_PORT=80
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.1.0.1:443
LQB_PORT_80_TCP_ADDR=10.1.192.90
KUBERNETES_SERVICE_HOST=10.1.0.1
PWD=/
PASSWORD=admin123
LQB_PORT_80_TCP_PORT=80
LQB_PORT_80_TCP_PROTO=tcp
NFS_PVC_SERVICE_HOST=10.1.177.87

从上边的日志,可以看到有 USERNAME 和 PASSWORD 两个环境变量输出出来。

1.2、Volume挂载

创建pod来验证下volume挂载,创建pod的yaml如下:

[root@k8s-master secret]# kubectl apply -f secret2-pod.yml
pod/secret2-pod created
[root@k8s-master secret]# cat secret2-pod.yml
apiVersion: v1
kind: Pod
metadata:
name: secret2-pod
spec:
containers:
- name: secret2
image: busybox
command: ["/bin/sh","-c","ls /etc/secrets"]
volumeMounts:
- name: secrets
mountPath: /etc/secrets
volumes:
- name: secrets
secret:
secretName: mysecret

查看日志输出

[root@k8s-master secret]# kubectl logs secret2-pod
password
username

可以看到secret把两个key挂载成了两个对应的文件。当然如果想要挂载到指定的文件上面,是不是也可以使用上一节课的方法:在secretName下面添加items指定 key 和 path,这个大家可以参考上节课ConfigMap中的方法去测试下。

2、kubernetes.io/dockerconfigjson

除了上面的Opaque这种类型外,我们还可以来创建用户docker registry认证的Secret,直接使用kubectl create命令创建即可,如下:

[root@k8s-master secret]# kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER  --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret/myregistry created
[root@k8s-master secret]# kubectl get secret
NAME TYPE DATA AGE
default-token-jd6b5 kubernetes.io/service-account-token 3 53d
myregistry kubernetes.io/dockerconfigjson 1 14s
mysecret Opaque 2 52m
[root@k8s-master secret]# kubectl describe secret/myregistry
Name: myregistry
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 152 bytes

创建secret/myregistry并通过describe来进行查看详细信息,同样的可以看到data区域没有直接展示处理,如果想查看的话可以通过导出来进行查看,-o yaml导出详细配置文件

[root@k8s-master secret]# kubectl get secret myregistry -o yaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0=
kind: Secret
metadata:
creationTimestamp: "2021-12-14T09:57:00Z"
name: myregistry
namespace: default
resourceVersion: "6558599"
uid: 58cf3483-bb17-48e5-8576-edffafa05c5d
type: kubernetes.io/dockerconfigjson

把上面的data.dockerconfigjson下面的数据做一个base64解码,看看里面的数据是怎样的呢?

[root@k8s-master secret]# echo eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= | base64 -d
{"auths":{"DOCKER_SERVER":{"username":"DOCKER_USER","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRVI6RE9DS0VSX1BBU1NXT1JE"}}}

3、kubernetes.io/service-account-token

另外一种Secret类型就是kubernetes.io/service-account-token,用于被serviceaccount引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的secret会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中。

这里我们使用一个nginx镜像来验证一下,由于不能在command里面来验证了,因为token是需要Pod运行起来过后才会被挂载上去的,直接在command命令中去查看肯定是还没有 token 文件的。

[root@k8s-master secret]# kubectl run secret-pod3 --image nginx
pod/secret-pod3 created
[root@k8s-master secret]# kubectl get pod
secret-pod3 1/1 Running 0 71s
[root@k8s-master secret]# kubectl exec secret-pod3 ls /run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token
[root@k8s-master secret]# kubectl exec secret-pod3 cat /run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IlRYTkM5YWFCYy1uakRNam50a3JRWGg2Nlo1Zm5kLXVpNjVBWHFTeUJmeWcifQ.eyJhdWQiOlsiaHR0cHM6Ly9rdWJlcm5ldGVzLmRlZmF1bHQuc3ZjLmNsdXN0ZXIubG9jYWwiXSwiZXhwIjoxNjcxMDEyNTk1LCJpYXQiOjE2Mzk0NzY1OTUsImlzcyI6Imh0dHBzOi8va3ViZXJuZXRlcy5kZWZhdWx0LnN2Yy5jbHVzdGVyLmxvY2FsIiwia3ViZXJuZXRlcy5pbyI6eyJuYW1lc3BhY2UiOiJkZWZhdWx0IiwicG9kIjp7Im5hbWUiOiJzZWNyZXQtcG9kMyIsInVpZCI6IjNjMzU5N2NhLThkNmYtNGY4OC1hNjBmLTNkOGJiYjYzNTEyZCJ9LCJzZXJ2aWNlYWNjb3VudCI6eyJuYW1lIjoiZGVmYXVsdCIsInVpZCI6ImYyMDcyOTljLWY4ZDItNGM1Yi1iZjliLTRmZjlhZDJiNzAzZSJ9LCJ3YXJuYWZ0ZXIiOjE2Mzk0ODAyMDJ9LCJuYmYiOjE2Mzk0NzY1OTUsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.udblxDpAE5EaBksYXFzswyLLzvekc0fRcPXX0G86sm7lzsF8mVQbpCEbKVkD91_KyW7kwx5msArxe2CgWUszksBrSXC346EiOHrkjhZlHfEP5uwNS7rww-RLcvXa8hzM209GIDNGqtLuH_UpshQRWKTtsriVg0GR1g04YMaWK5qsReSCJ6A5YkwZHKUoUAiwVsiK1Unw_AVQoNziE2Co3ZImy0Bgse-tIpMQoqjOpOtu28wMdgrOJ0ZvljnCN9f3Ud64ommmGQ-IT4tMoLQ0TTkZl1EbFm2MRHHWTz5q4vwKD0bwQG_gejiyvcX0sm5jGX_XLSAja4xDl-X7NNNsuQ

创建pod/secret-pod3,进行查看/run/secrets/kubernetes.io/serviceaccount目录下文件,然后查看这个文件的内容/run/secrets/kubernetes.io/serviceaccount/token

四、secret与configmap区别

1、相同点

  1. key/value 的形式
  2. 属于某个特定的namespace
  3. 可以导出到环境变量
  4. 可以通过目录/文件形式挂载
  5. 通过volume挂载的配置信息均可热更新 

2、不同点

  1. Secret 可以被ServerAccount关联
  2. Secret 可以存储ocker register的鉴权信息,用在ImagePullSecret参数中,用于拉取私有仓库的镜像
  3. Secret 支持Base64加密
  4. Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而Configmap不区分类型