secret
1、背景
secret是一种用于保存少量敏感信息例如密码、令牌或密钥的对象资源。这样的信息可能会被放在 Pod 规约中或者镜像中。 使用 Secret 意味着你不需要在应用程序代码中包含机密数据。
POD可以有三种方式来使用secret:
1. 作为挂载到一个或多个容器上的卷 中的文件。
2. 作为容器的环境变量。
3. 由 kubelet 在为 Pod 拉取镜像时使用。
secret的可选参数有三种:
1. generic:通用类型,通常用于存储密码数据;
2. tls:此类型仅用于存储私钥和证书;
3. docker-registry:若要保存docker仓库的认证信息,就必须使用此类型来创建;
secret类型:
1. service account:用于被service account引用,service account创建时,kubernetes会默认创建对应的secret,对应的secret会被自动挂载到pod的/run/secrets/kubernetes.io/serviceaccount目录中。
2. opaque: base64编码格式的secret,用来存储密码、私钥等,可以通过base64 --decode解码获得原始数据,因此安全性不高;
3. Kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息。
官网链接:https://kubernetes.io/zh-cn/docs/concepts/configuration/secret/#creating-a-secret
2、创建和修改secret
2.1 使用kubectl创建和修改secret
# from-literal创建
[root@master-worker-node-1 secret]# kubectl create secret generic new-use-1 --from-literal=username=test-1 --from-literal=password=123456 # 创建一个generic类型的secret
secret/new-use-1 created
# from-file创建
[root@master-worker-node-1 secret]# echo -n "test-2" > username.txt
[root@master-worker-node-1 secret]# echo -n "123456" > password.txt
[root@master-worker-node-1 secret]# kubectl create secret generic new-user-2 --from-file=username=./username.txt --from-file=password=./password.txt
secret/new-user-2 created
[root@master-worker-node-1 secret]# kubectl get secret
NAME TYPE DATA AGE
new-use-1 Opaque 2 4m7s
new-user-2 Opaque 2 43s
# 查看详细信息是不会明文显示value的。
[root@master-worker-node-1 secret]# kubectl describe secret new-use-1
Name: new-use-1
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 6 bytes
# 可以通过解码查看
[root@master-worker-node-1 secret]# kubectl get secret new-use-1 -o jsonpath='{.data}'
{"password":"MTIzNDU2","username":"dGVzdC0x"}
[root@master-worker-node-1 secret]#
[root@master-worker-node-1 secret]# echo MTIzNDU2 | base64 --decode
123456
[root@master-worker-node-1 secret]#
[root@master-worker-node-1 secret]# echo dGVzdC0x | base64 --decode
test-1
[root@master-worker-node-1 secret]#
[root@master-worker-node-1 secret]# kubectl edit secret new-use-1
Edit cancelled, no changes made.
data:
password: MTIzNDU2
username: dGVzdC0x
# 通过kubectl edit查看也是base64加密的,不能直接修改为明文字符串。需要将更改的内容先基于base64加密
[root@master-worker-node-1 secret]# echo '234567' | base64
MjM0NTY3Cg==
2.2 使用配置文件创建和修改secret
apiVersion: v1
kind: Secret
metadata:
name: new-secret-3
immutable: false
type: Opaque
data:
username: dGVzdC11c2VyLTMK
password: MTIzNDU2Cg==
[root@master-worker-node-1 secret]# kubectl apply -f secret-1.yaml
secret/new-secret-3 created
# 创建上面那个yaml时,需要先将数据进行base64加密,之后再更新到yaml文件。有时候,希望可以通过传入普通字符串,等到secret创建以后自动加密。
apiVersion: v1
kind: Secret
metadata:
name: new-secret-4
immutable: True
type: Opaque
stringData:
nginx.conf: |
upstream servers{
server 172.16.1.1
server 172.16.1.2
}
[root@master-worker-node-1 secret]# kubectl apply -f secret-2.yaml
secret/new-secret-4 created
[root@master-worker-node-1 secret]# kubectl get secret new-secret-4 -o yaml | head -5
apiVersion: v1
data:
nginx.conf: dXBzdHJlYW0gc2VydmVyc3sKc2VydmVyIDE3Mi4xNi4xLjEgCnNlcnZlciAxNzIuMTYuMS4yCn0K
immutable: true
kind: Secret
# 如果immutable没有设置为true,那么修改yaml文件以后,可以直接apply。
# 如果immutable已经设置为true,那么只能修改metadata,其他不能修改。
3、通过volume 以文件的形似使用secret
[root@master-worker-node-1 secret]# cat secret-volume.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-secret-volume
spec:
containers:
- name: centos
image: centos
imagePullPolicy: IfNotPresent
command: ['/bin/bash','-c','sleep 1234']
volumeMounts:
- name: secret-volume
mountPath: /mnt
volumes:
- name: secret-volume
secret:
secretName: new-secret-3
# 创建
[root@master-worker-node-1 secret]# kubectl apply -f secret-volume.yaml
pod/test-secret-volume created
# 查看pod运行情况
[root@master-worker-node-1 secret]# kubectl get pods -o wide test-secret-volume
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
test-secret-volume 1/1 Running 0 58s 10.244.31.36 only-worker-node-3 <none> <none>
[root@master-worker-node-1 secret]# kubectl exec -it test-secret-volume -- bash
[root@test-secret-volume /]# df -Th
Filesystem Type Size Used Avail Use% Mounted on
overlay overlay 20G 7.2G 13G 36% /
tmpfs tmpfs 64M 0 64M 0% /dev
tmpfs tmpfs 3.8G 0 3.8G 0% /sys/fs/cgroup
tmpfs tmpfs 7.5G 8.0K 7.5G 1% /mnt
..........
[root@test-secret-volume /]# ls -l /mnt/
total 0
lrwxrwxrwx. 1 root root 15 Dec 28 15:17 password -> ..data/password
lrwxrwxrwx. 1 root root 15 Dec 28 15:17 username -> ..data/username
[root@test-secret-volume /]# cat /mnt/password
123456
[root@test-secret-volume /]# cat /mnt/username
test-user-3
# POD中的数据已经被解密了。
# 通过volume也可以将secret键值投射到特定目录。下面这一段来自Kubernetes官网
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username #mysecret 中的键 username 会出现在容器中的路径为 /etc/foo/my-group/my-username, 而不是 /etc/foo/username。
# 也可以设置权限。pods.spec.volumes.secret.defaultMode
4、以环境变量的形似使用secret
[root@master-worker-node-1 secret]# cat secret-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-secret-env
spec:
containers:
- name: test-secret-env
image: centos
imagePullPolicy: IfNotPresent
command: ['/bin/bash','-c','sleep 1234']
env:
- name: username
valueFrom:
secretKeyRef:
name: new-secret-3
key: username
- name: passwrod
valueFrom:
secretKeyRef:
name: new-secret-3
key: password
[root@master-worker-node-1 secret]# kubectl apply -f secret-env.yaml
pod/test-secret-env created
# 查看pod的环境变量信息
[root@master-worker-node-1 secret]# kubectl exec -it test-secret-env -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=test-secret-env
username=test-user-3
passwrod=123456
KUBERNETES_PORT=tcp://10.96.0.1:443
5、更新secret
# 可以通过kubectl edit 更新,也可以通过kubectl patch更新,只能更新volume下的secret,通过env使用的不能在线更新
[root@master-worker-node-1 secret]# echo -n 'qqqwwweee' | base64
cXFxd3d3ZWVl
[root@master-worker-node-1 secret]# kubectl patch secret new-secret-3 -p '{"data":{"password":"cXFxd3d3ZWVl"}}'
secret/new-secret-3 patched
# volume挂载使用的已经更新,env使用的没更新
[root@master-worker-node-1 secret]# kubectl exec -it test-secret-volume -- cat /mnt/password
qqqwwweee[root@master-worker-node-1 secret]#
[root@master-worker-node-1 secret]# kubectl exec -it test-secret-env -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=test-secret-env
username=test-user-3
passwrod=123456
6、小结
1、secret时将一些较为敏感的加密以后供pod使用的资源。一个secret可以从文件加密也可以从字符串加密
2、secret有三种使用形式:env、volume和registry,第三种此处没实验测试。可以参照官网。
3、通过volume使用时可以在线更新,通过env不能在线更新。