1.定义
我们学习 ConfigMap 的时候,我们说 ConfigMap 这个资源对象是 Kubernetes 当中非常重要的一个资源对象,一般情况下 ConfigMap 是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用 ConfigMap 就非常不妥了,因为ConfigMa 是明文存储的,这个时候我们就需要用到另外一个资源对象了:Secret,Secret用来保存敏感信息,例如密码、OAuth 令牌和 ssh key 等等,将这些信息放在 Secret 中比放在 Pod 的定义中或者 Docker 镜像中要更加安全和灵活。
Secret 主要使用的有以下三种类型:
Opaque:base64 编码格式的 Secret,用来存储密码、密钥等;但数据也可以通过base64 –decode解码得到原始数据,所有加密性很弱。
kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
kubernetes.io/service-account-token:用于被 ServiceAccount ServiceAccount 创建时 Kubernetes 会默认创建一个对应的 Secret 对象。Pod 如果使用了 ServiceAccount,对应的 Secret 会自动挂载到 Pod 目录 /run/secrets/kubernetes.io/serviceaccount 中。
bootstrap.kubernetes.io/token:用于节点接入集群的校验的 Secret
2.Opaque Secret
Opaque 类型的数据是一个 map 类型,要求 value 必须是 base64 编码格式,比如我们来创建一个用户名为 admin,密码为 admin321 的 Secret 对象,首先我们需要先把用户名和密码做 base64 编码:
[root@k8s-master01 configmap]# echo -n "admin" | base64
YWRtaW4=
[root@k8s-master01 configmap]# echo -n "admin321" | base64
YWRtaW4zMjE=
然后我们就可以利用上面编码过后的数据来编写一个 YAML 文件:(secret-demo.yaml)
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: YWRtaW4zMjE=
[root@k8s-master01 secret]# kubectl create -f secret-demo.yaml
[root@k8s-master01 secret]# kubectl get secret
NAME TYPE DATA AGE
default-token-k2flf kubernetes.io/service-account-token 3 71d
mysecret Opaque 2 3m1s
[root@k8s-master01 secret]# kubectl describe secret mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 8 bytes
username: 5 bytes
[root@k8s-master01 secret]# kubectl get secret mysecret -oyaml
apiVersion: v1
data:
password: YWRtaW4zMjE=
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: "2021-04-11T06:01:52Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:password: {}
f:username: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2021-04-11T06:01:52Z"
name: mysecret
namespace: default
resourceVersion: "2860723"
uid: 1715622e-7244-4646-83ca-79669e447518
type: Opaque
3.创建好 Secret对象后,有两种方式来使用它:
以环境变量的形式
以Volume的形式挂载
Volume 挂载
同样的我们用一个 Pod 来验证下 Volume 挂载,创建一个 Pod 文件:(secret2-pod.yaml)
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-master01 secret]# kubectl logs secret2-pod
password
username
4.kubernetes.io/dockerconfigjson
除了上面的 Opaque 这种类型外,我们还可以来创建用户 docker registry 认证的 Secret,直接使用`kubectl create 命令创建即可,如下:
[root@k8s-master01 secret]# kubectl create secret docker-registry myregistry --docker-server=DOCKER_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
[root@k8s-master01 secret]# kubectl get secrets
NAME TYPE DATA AGE
default-token-k2flf kubernetes.io/service-account-token 3 71d
myregistry kubernetes.io/dockerconfigjson 1 38s
mysecret Opaque 2 14m[root@k8s-master01 secret]# kubectl describe secret myregistry
Name: myregistry
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 152 bytes
[root@k8s-master01 secret]# kubectl get secrets myregistry -oyaml
apiVersion: v1
data:
.dockerconfigjson: eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0=
kind: Secret
metadata:
creationTimestamp: "2021-04-11T06:16:03Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:.dockerconfigjson: {}
f:type: {}
manager: kubectl-create
operation: Update
time: "2021-04-11T06:16:03Z"
name: myregistry
namespace: default
resourceVersion: "2862816"
uid: 5a7766f2-6481-46a3-939e-340f272e1bf7
type: kubernetes.io/dockerconfigjson
解码:
[root@k8s-master01 secret]# echo eyJhdXRocyI6eyJET0NLRVJfU0VSVkVSIjp7InVzZXJuYW1lIjoiRE9DS0VSX1VTRVIiLCJwYXNzd29yZCI6IkRPQ0tFUl9QQVNTV09SRCIsImVtYWlsIjoiRE9DS0VSX0VNQUlMIiwiYXV0aCI6IlJFOURTMFZTWDFWVFJWSTZSRTlEUzBWU1gxQkJVMU5YVDFKRSJ9fX0= | base64 -d
{"auths":{"DOCKER_SERVER":{"username":"DOCKER_USER","password":"DOCKER_PASSWORD","email":"DOCKER_EMAIL","auth":"RE9DS0VSX1VTRVI6RE9DS0VSX1BBU1NXT1JE"}}}[root
如果我们需要拉取私有仓库中的 Docker 镜像的话就需要使用到上面的 myregistry 这个 Secret:
apiVersion: v1
kind: Pod
metadata:
name: foo
spec:
containers:
- name: foo
image: 192.168.1.100:5000/test:v1
imagePullSecrets:
- name: myregistry
5.kubernetes.io/service-account-token
另外一种 Secret 类型就是 kubernetes.io/service-account-token,用于被 ServiceAccount 引用。ServiceAccout 创建时 Kubernetes 会默认创建对应的 Secret。Pod 如果使用了 ServiceAccount,对应的 Secret 会自动挂载到 Pod 的 /var/run/secrets/kubernetes.io/serviceaccount/ 目录中。如下所示我们随意创建一个 Pod:
[root@k8s-master01 secret]# kubectl run secret-pod3 --image nginx:1.7.9
[root@k8s-master01 secret]# kubectl get pod
[root@k8s-master01 secret]# kubectl exec -it secret-pod3 /bin/bash
root@secret-pod3:/# ls /run/secrets/kubernetes.io/serviceaccount/
ca.crt namespace token
6.Secret vs ConfigMap
最后我们来对比下 Secret 和 ConfigMap这两种资源对象的异同点:
相同点¶
key/value的形式
属于某个特定的命名空间
可以导出到环境变量
可以通过目录/文件形式挂载
通过 volume 挂载的配置信息均可热更新
不同点¶
Secret 可以被 ServerAccount 关联
Secret 可以存储 docker register 的鉴权信息,用在 ImagePullSecret 参数中,用于拉取私有仓库的镜像
Secret 支持 Base64 加密
Secret 分为 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三种类型,而 Configmap 不区分类型