背景
Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在secret中比放在 Pod 的定义、容器镜像中、相对于ConfigMap说更加安全和灵活。 Secret是标准的k8s资源对象,使用方法和ConfigMap非常类似。同时我们可以对Secret进行访问控制,防止机密数据被访问
概念
Secret有三种类型:
- Service Account:Pod中的进程用来访问Kubernetes API的凭证,由Kubernetes自动创建,也可以手动创建。当在资源清单的定义中引用自定义的Service Account,如果没有引用,会使用当前namespace下默认的ServiceAccount,并且会自动挂载到容器的/run/secrets/kubernetes.io/serviceaccount路径下。有关ServiceAccount的详细内容可以查看k8s中的访问控制。
- Opaque:base64编码格式的Secert,用来存储密码、密钥等。该数据是key:value类型的。
- kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
创建Secret
命令行的方式创建Secret
查看创建命令
[root@k8s-master01 secret]# kubectl create secret --help Create a secret using specified subcommand. Available Commands: docker-registry 创建一个给 Docker registry 使用的 secret generic 从本地 file, directory 或者 literal value 创建一个 secret 本质上是Opaque类型的Secret tls 创建一个 TLS secret
可以创建3中类型的Secret
:1. docker拉取镜像的凭证、2. base64加密的密文 、3. ca证书的密文
命令行创建Opaque类型的Secret
使用命令行创建ConfigMap的命令类似。支持从文件夹、单个文件、key=value类型的文件、键值对等方式创建Secret。
解释说明:
使用--from-file的方式,文件中的数据不用使用base64加密。和ConfigMap类似,如果不指定key的名称,默认使用文件名。
使用--from-literal。使用key1=value1的方式,value1不用base64加密,但是需要使用’'单引号括起来进行反转义。
其余和ConfigMap基本一致,这里不再赘述。
案例演示:
我们可以将连接mysql数据库的用户名和密码使用Secret
保存起来
# 创建本例中要使用的文件 echo -n 'admin' > ./username.txt echo -n '1f2d1e2e67df' > ./password.txt
kubectl create secret
命令将这些文件打包到一个 Secret
中并在 API server 中创建了一个对象。
kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
查看一下刚才创建的Secret
使用yaml的方式查看kubectl get secret db-user-pass -o yaml
apiVersion: v1 data: password.txt: MWYyZDFlMmU2N2Rm username.txt: YWRtaW4= kind: Secret metadata: creationTimestamp: "2020-09-16T09:13:12Z" name: db-user-pass namespace: default resourceVersion: "35680" selfLink: /api/v1/namespaces/default/secrets/db-user-pass uid: 2ecf89d5-bdaf-4b91-ac45-d568061e8e52 type: Opaque
命令行创建docker registry类型的Secret
kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
该Secret
的作用是在kubelet拉取镜像的时候,如果该镜像需要认证,该Secret
可以作为拉取镜像的凭证。在pod.spec.imagePullSecrets
可以引用创建的Secret
yaml文件的方式创建Secret
创建secret加密数据 编码base64
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type:
Opaque
data:
username: YWRtaW4K
password: YWRtaW4K
使用Secret
两种挂载方式
1、变量形式挂载
在Pod.spec.containers
下使用env
或者是envFrom
将Secret
中的数据加载到容器的环境变量中。env
和envFrom
和引用ConfigMap
类似。
使用env
方式的资源清单。pod-env.yaml
apiVersion: v1 kind: Pod metadata: name: mypod spec: containers: - name: nginx image: nginx env: - name: SECRET_USERNAME valueFrom: secretKeyRef: name: mysecret key: username - name: SECRET_PASSWORD valueFrom: secretKeyRef: name: mysecret key: username
创建Pod kubectl apply -f pod-env.yaml
。
查看结果
[root@test yaml]# kubectl apply -f secret-var.yaml pod/mypod created [root@test yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE ds-test-gs6z5 1/1 Running 0 8h ds-test-xfjgt 1/1 Running 0 8h mypod 1/1 Running 0 3m20s pi-pdwmx 0/1 Completed 0 5h12m web-586db47859-6vpfr 1/1 Running 0 32h web-586db47859-8hmxs 1/1 Running 0 32h web-586db47859-wspl7 1/1 Running 0 32h [root@test yaml]# kubectl exec -it mypod bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. root@mypod:/# ls bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@mypod:/# echo $SECRET_USERNAME admin root@mypod:/# echo $SECRET_PASSWORD admin root@mypod:/# exit exit
2、将Secret挂在到Volume下,且键名映射到特定路径
在 Pod 中使用存放在卷中的 Secret:
创建一个 Secret 或者使用已有的 Secret。多个 Pod 可以引用同一个 Secret。
将 spec.containers[].volumeMounts[] 加到需要用到该 Secret 的容器中。 指定 spec.containers[].volumeMounts[].readOnly = true 和 spec.containers[].volumeMounts[].mountPath 为你想要该 Secret 出现的尚未使用的目录。
修改你的 Pod 定义,在 spec.volumes[] 下增加一个卷。可以给这个卷随意命名, 它的spec.volumes[].secret.secretName 必须是 Secret 对象的名字。
修改你的镜像并且/或者命令行,让程序从该目录下寻找文件。 Secret 的 data 映射中的每一个键都对应 mountPath 下的一个文件名。
如果想要使用Secret中的某些key,且想要映射到特定路径下,类似于ConfigMap使用items
案例演示:
资源清单 pod-secret-volume.yaml
apiVersion: v1 kind: Pod metadata: name: mypod1 spec: containers: - name: nginx image: nginx volumeMounts: - name: foo mountPath: "/etc/foo" readOnly: true volumes: - name: foo secret: secretName: mysecret
创建Secret。kubectl apply -f pod-secret-volume.yaml
查看Pod里面的容器的文件的数据。kubectl exec pod1 cat /etc/foo/my-group/my-username => admin
可以看到Secret里面的数据被加载到/etc/foo/my-group/my-username文件下。/etc/foo/是挂载的路径,my-group/my-username是定义的子路径和文件名。文件的内容已经base64解密过了。
查看结果
[root@test yaml]# kubectl apply -f secret-volume.yaml pod/mypod1 created [root@test yaml]# kubectl get pods NAME READY STATUS RESTARTS AGE ds-test-gs6z5 1/1 Running 0 8h ds-test-xfjgt 1/1 Running 0 8h mypod 1/1 Running 0 9m41s mypod1 1/1 Running 0 7s pi-pdwmx 0/1 Completed 0 5h19m web-586db47859-6vpfr 1/1 Running 0 32h web-586db47859-8hmxs 1/1 Running 0 32h web-586db47859-wspl7 1/1 Running 0 32h [root@test yaml]# kubectl exec -it mypod1 bash kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead. root@mypod1:/# cat /etc/f fonts/ foo/ fstab root@mypod1:/# cat /etc/foo/ ..2020_12_11_12_17_56.196281452/ ..data/ password username root@mypod1:/# cat /etc/foo/password admin root@mypod1:/# cat /etc/foo/username admin root@mypod1:/# exit exit
Secret和ConfigMap对比
相同点:
key/value的形式
属于某个特定的namespace
可以导出到环境变量
可以通过目录/文件形式挂载(支持挂载所有key和部分key)
不同点:
Secret可以被ServerAccount关联(使用)
Secret可以存储register的鉴权信息,用在ImagePullSecret参数中,用于拉取私有仓库的镜像
Secret支持Base64加密
Secret分为kubernetes.io/Service Account,kubernetes.io/dockerconfigjson,Opaque三种类型,Configmap不区分类型
Secret文件存储在tmpfs文件系统中,Pod删除后Secret文件也会对应的删除。这里删除的是Secret的副本