概述

Secret对象与ConfigMap对象类似,但它主要用于存储以下敏感信息,例如密码,OAuth token和SSH key等等。将这些信息存储在secret中,和直接存储在Pod的定义中,或Docker镜像定义中相比,更加安全和灵活。

kuberntes中内置了三种secret类型:

  • Opaque:使用base64编码存储信息,可以通过base64 –decode解码获得原始数据,因此安全性弱。
  • kubernetes.io/dockerconfigjson:用于存储docker registry的认证信息。
  • kubernetes.io/service-account-token:用于被 serviceaccount 引用。serviceaccout 创建时 Kubernetes 会默认创建对应的 secret。Pod 如果使用了 serviceaccount,对应的 secret 会自动挂载到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目录中。(前面博文记录过实践后的食用方法)

Opaque Secret

Opaque类型的Secret,其value为base64编码后的值。

创建方式

从文件中创建Secret

1
2
$ echo -n "admin" > ./username.txt
$ echo -n "1f2d1e2e67df" > ./password.txt

使用kubectl create secret命令创建secret:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 创建
$ kubectl create secret generic db-user-passwd --from-file=./username.txt --from-file=./password.txt
secret "db-user-passwd" created

# 查看创建结果
$ kubectl get secrets db-user-passwd
apiVersion: v1
data:
password.txt: MWYyZDFlMmU2N2Rm
username.txt: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: 2018-12-21T08:58:33Z
name: db-user-passwd
namespace: default
resourceVersion: "57310"
selfLink: /api/v1/namespaces/default/secrets/db-user-passwd
uid: 98488947-04fe-11e9-97cd-00505621dd5b
type: Opaque

使用描述文件创建Secret

首先使用base64对数据进行编码:

1
2
3
4
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm

创建一个类型为Secret的描述文件:

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
$ cat >> secret.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
EOF

# 创建
$ kubectl create -f secret.yaml
secret/mysecret created

# 查看创建结果
$ kubectl get secrets mysecret -o yaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: 2018-12-21T09:03:52Z
name: mysecret
namespace: default
resourceVersion: "57767"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: 564bd4da-04ff-11e9-97cd-00505621dd5b
type: Opaque

食用方式

创建好Secret之后,可以通过两种方式食用:

  • 以Volume方式
  • 以环境变量方式

将 Secret 挂载到 Volume 中

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
$ cat >> redis-pod.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: redis
labels:
app: redis
spec:
nodeName: k8s-m1
containers:
- name: container-0
image: redis
imagePullPolicy: IfNotPresent
volumeMounts:
- name: foo
mountPath: /etc/foo
readOnly: true
volumes:
- name: foo
secret:
secretName: db-user-passwd
EOF

$ 创建:
$ kubectl create -f redis-pod.yaml
pod/redis created

进入容器检查

1
2
3
4
5
6
7
8
$ ls -l /etc/foo/
total 0
lrwxrwxrwx 1 root root 19 Dec 21 09:14 password.txt -> ..data/password.txt
lrwxrwxrwx 1 root root 19 Dec 21 09:14 username.txt -> ..data/username.txt
$ cat /etc/foo/username.txt
admin
$ cat /etc/foo/password.txt
1f2d1e2e67df

也可以只挂载Secret中特定的key:

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
$ cat >> redis-pod2.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: redis2
labels:
app: redis
spec:
nodeName: k8s-m1
containers:
- name: redis
image: redis
imagePullPolicy: IfNotPresent
volumeMounts:
- name: foo
mountPath: /etc/foo
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
EOF

# 创建
$ kubectl create -f redis-pod2.yaml
pod/redis2 created

进入容器检查

1
2
3
4
5
$ kubectl exec -it redis5 /bin/bash
$ ls -l /etc/foo/my-group/my-username
-rw-r--r-- 1 root root 5 Dec 21 10:26 /etc/foo/my-group/my-username
$ cat /etc/foo/my-group/my-username
admin

在这种情况下:

username 存储在/etc/foo/my-group/my-username中
password未被挂载
注意: 指定key的这种挂载方式只适用于是通过使用描述文件创建的Secret,从文件中创建的那种Secret挂载会报错:

1
2
3
4
5
$ 当我挂载 Secret db-user-passwd 的时候pod创建事件:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedMount 5s (x5 over 12s) kubelet, k8s-m1 MountVolume.SetUp failed for volume "foo" : references non-existent secret key

具体原因目前无解~,有知道的大哥可以评论留言告知一二,谢谢~

将 Secret 导出到环境变量中

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
$ cat >> redis3.yaml << EOF
apiVersion: v1
kind: Pod
metadata:
name: redis3
labels:
app: redis
spec:
nodeName: k8s-m1
containers:
- name: redis
image: redis
imagePullPolicy: IfNotPresent
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
EOF

# 进入容器查看结果
$ kubectl exec -it redis3 /bin/bash
$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df

ok , 通过不同方式挂载进容器中,我们的应用程序就可以拿来用啦,具体选择哪种方式挂载还是需要看实际环境;
好啦,以上就是Secret的简单食用方法,更多可以看官方文档