Secret用来保存敏感信息,例如密码,OAuth token和ssh key等等,将这些信息放在Secret中比放在pod的定义中或者docker镜像中来说更加安全和灵活。

Secret类型

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中。

Opaque Secret

Opaque类型的数据时一个map类型,要求value是base64编码格式,比如我们来创建一个用户为admin,密码为admin000的Secret对象,先把用户名和密码做base64编码:

1
2
3
4
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "admin000" | base64
YWRtaW4wMDA=

yaml文件:

1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=
  password: YWRtaW4wMDA=

创建:

1
$ kubectl create -f secret-demo.yaml

查看:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-lww8j   kubernetes.io/service-account-token   3      7d21h
mysecret              Opaque                                2      2m1s
$ kubectl describe secrets mysecret
Name:         mysecret
Namespace:    default
Labels:       <none>
Annotations:
Type:         Opaque

Data
====
password:  8 bytes
username:  5 bytes
$ kubectl get secret mysecret -o yaml  #查看Data里面的详细信息
apiVersion: v1
data:
  password: YWRtaW4wMDA=
  username: YWRtaW4=
kind: Secret
metadata:
  annotations:
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"v1","data":{"password":"YWRtaW4wMDA=","username":"YWRtaW4="},"kind":"Secret","metadata":{"annotations":{},"name":"mysecret","namespace":"default"},"type":"Opaque"}
  creationTimestamp: "2020-03-31T01:16:33Z"
  name: mysecret
  namespace: default
  resourceVersion: "1769728"
  selfLink: /api/v1/namespaces/default/secrets/mysecret
  uid: 426ea846-72ed-11ea-9fde-005056b24815
type: Opaque

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

  • 以环境变量的形式
  • 以Volume的形式挂载

环境变量

Yaml文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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

创建:

1
kubectl create -f pod-1.yaml

pod运行后会有以下内容输出:

1
2
USERNAME=admin
PASSWORD=admin000

Volume挂载

yaml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
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

创建:

1
kubectl apply -f pod-2.yaml

查看日志输出:

1
2
password
username

kubernetes.io/dockerconfigjson

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

1
2
3
4
5
6
$  kubectl create secret docker-registry 53registry --docker-server=172.16.xxx.xxx:30882 --docker-username=xxxx --docker-password=xxxxx --docker-email=test@gmail.com
secret/53registry created
$ kubectl get secrets
NAME                  TYPE                                  DATA   AGE
53registry            kubernetes.io/dockerconfigjson        1      9s
mysecret              Opaque                                2      25m

查看信息:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ kubectl describe secrets  53registry
Name:         53registry
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/dockerconfigjson

Data
====
.dockerconfigjson:  130 bytes
$ kubectl get secrets 53registry -o yaml
apiVersion: v1
data:
  .dockerconfigjson: eyJhdXRocyI6eyIxNzIuMTYuNzcuNTM6MzA4ODIiOnsidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiYWRtaW4wMDAiLCJlbWFpbCI6InRlc3RAZ21haWwuY29tIiwiYXV0aCI6IllXUnRhVzQ2WVdSdGFXNHdNREE9In19fQ==
kind: Secret
metadata:
  creationTimestamp: "2020-03-31T01:41:34Z"
  name: 53registry
  namespace: default
  resourceVersion: "1773588"
  selfLink: /api/v1/namespaces/default/secrets/53registry
  uid: c126cc02-72f0-11ea-9fde-005056b24815
type: kubernetes.io/dockerconfigjson

可以将data.dockerconfigjson下的内容做一个base64解码,看看里面的数据

1
2
$ echo eyJhdXRocyI6eyIxNzIuMTYuNzcuNTM6MzA4ODIiOnsidXNlcm5hbWUiOiJhZG1pbiIsInBhc3N3b3JkIjoiYWRtaW4wMDAiLCJlbWFpbCI6InRlc3RAZ21haWwuY29tIiwiYXV0aCI6IllXUnRhVzQ2WVdSdGFXNHdNREE9In19fQ== | base64 -d
{"auths":{"172.16.xxx.xxx:30882":{"username":"xxx","password":"xxxx","email":"test@gmail.com","auth":"YWRtaW46YWRtaW4wMDA="}}}

测试使用53registry这个Secret能否拉取私有仓库里的镜像

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
apiVersion: v1
kind: Pod
metadata:
  name: tomcat
spec:
  containers:
  - name: tomcat
    image: 172.16.xx.xx:30882/tomcat:0.0.2
  imagePullSecrets:
  - name: 53registry

创建:

1
2
3
4
5
6
7
8
$ kubectl apply -f pods-3.yaml
pod/tomcat created
$ kubectl describe pods tomcat
.....
  Normal  Scheduled  19s   default-scheduler      Successfully assigned default/tomcat to 172.16.xx.xx
  Normal  Pulled     18s   kubelet, 172.16.xx.xx  Container image "172.16.xx.xx:30882/tomcat:0.0.2" already present on machine
  Normal  Created    18s   kubelet, 172.16.xx.xx  Created container tomcat
  Normal  Started    18s   kubelet, 172.16.xx.xx  Started container tomcat

可以看到镜像被正常拉取了

Kubernetes.io/service-account-token

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

1
2
3
4
5
6
7
$ kubectl run nginx --image nginx
$ kubectl exec nginx-7db9fccd9b-kh69g ls /run/secrets/kubernetes.io/serviceaccount/
ca.crt
namespace
token
$ kubectl exec nginx-7db9fccd9b-kh69g cat /run/secrets/kubernetes.io/serviceaccount/token
eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJkZWZhdWx0Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6ImRlZmF1bHQtdG9rZW4tbHd3OGoiLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoiZGVmYXVsdCIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6ImQzM2Y4NzM5LTZjYjgtMTFlYS05ZmRlLTAwNTA1NmIyNDgxNSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDpkZWZhdWx0OmRlZmF1bHQifQ.VP1N2F7hY-WrjCMdj3vqm-XGCRuYKX75xJA0cWFcfeJsds2LBo1f0dHA5YyptUGjj5UiOTHZtuj4Ge2THClcfOkUdi6E73TzrzkK6CPOhFRtEHC6koYjPjJMhMu9KnYg2zY2vEn7YmlzNndv6UF6hFbLk6iq44Y67Q5Jjgx7gtMmS-N8HTzx034mil5E7aCn__wJ_Ij5LkJ0lctHDp0jjNHbZPkfjCGSNRYn0WYl5qe7J6wY_SKE95QrAh4buNfh2s6y3NhMkbC29yy8nU2iVOFlWq-Rp7DMPRRi8hxRDOXMhPyzPaTgwFxZonrLQUTEX7zvqyRE7MPGtkYDO48jbg

参考链接

官方文档