应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名,密码或密钥,将这些信息直接保存在容器镜像中显然不妥,k8s提供的解决方案是 Serect。
Serect 会以密文的方式存储数据,避免了直接再配置文件中把偶从你敏感信息。Serect会以Volume的形式被mount到Pod,容器可通过文件的方式使用Serect中的敏感数据;此外,容器也可以以环境变量的方式使用这些数据。
Serect可通过命令行或YAML创建。
1. 创建Serect
(1)有四种方法创建 Serect ,这里我们选择yml的方式:
文件中的敏感数据必须是经过base64编码后的结果
zy@k8s-master:~$ echo -n zhangyin | base64
emhhbmd5aW4=
zy@k8s-master:~$ echo -n 123456 | base64
MTIzNDU2
apiVersion: v1
kind: Secret
metadata:
name: myserect
data:
username: emhhbmd5aW4=
password: MTIzNDU2
(2)apply一下
zy@k8s-master:~$ kubectl apply -f mysecret.yml
secret/myserect created
(3)查看secret
zy@k8s-master:~$ kubectl get secret myserect
NAME TYPE DATA AGE
myserect Opaque 2 73s
(4)通过kubectl describe secret 查看条目key
zy@k8s-master:~$ kubectl describe secrets myserect
Name: myserect
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password: 6 bytes
username: 8 bytes
(5)kubectl edit secret myserect 查看value
apiVersion: v1
data:
password: MTIzNDU2
username: emhhbmd5aW4=
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","data":{"password":"MTIzNDU2","username":"emhhbmd5aW4="},"kind":"Secret","metadata":{"annotations":{},"name":"myserect","namespace":"default"}}
creationTimestamp: "2023-03-19T08:53:26Z"
name: myserect
namespace: default
resourceVersion: "381312"
selfLink: /api/v1/namespaces/default/secrets/myserect
uid: 25004a9d-415a-496e-a5d3-82ae73948caa
type: Opaque
2. 在Pod中使用Secret
pod可以通过volume或者环境变量的方式使用Secret。
(1)Volume方式
Pod的配置文件如下:
创建一个使用 BusyBox 镜像的 Pod,Pod 中包含一个名为 "mypod" 的容器,容器将执行 sleep 命令,并创建一个名为 "/tmp/healthy" 的文件。该文件将在 30000 秒后被删除。
此外,该文件还指定了一个名为 "foo" 的卷和一个名为 "mysecret" 的secret。在容器中,该卷将被装载到 "/etc/foo" 目录,并设置为只读模式。
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
volumes: #将volumes字段移动到这里
- name: foo
secret:
secretName: myserect
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 30000
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
apply一下:
zy@k8s-master:~$ kubectl apply -f mypod.yml
pod/mypod created
可以看到,k8s会在指定的路径 /etc/foo 下为每条敏感数据创建一个文件,文件名就是数据条目的Key,这里是 /etc/foo/username 和 /etc/foo/password, value则以明文存放在文件中。
zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # ls /etc/foo
password username
/ # cat /etc/foo/username
/ # cat /etc/foo/username
zhangyin/ #
/ # cat /etc/foo/password
123456/ #
以Volume方式使用的Secret支持动态更新,secret更新后,容器中的数据也会更新。
将password更新为 abcdef,base64编码为YWJjZGVm ,修改mysecret.yml:
apiVersion: v1
kind: Secret
metadata:
name: myserect
data:
username: emhhbmd5aW4=
password: YWJjZGVm
重新apply一下密码文件:
zy@k8s-master:~$ kubectl apply -f mysecret.yml
secret/myserect configured
几秒钟后就会同步过去,我们去对应文件夹查看:
/etc/foo # cat password
abcdef/etc/foo #
(2)环境变量方式
通过Volume使用Secret,容器必须从文件中读取数据,稍嫌麻烦,k8s还支持通过环境变量使用Serect.
Pod 配置文件如下:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 30000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
apply一下:
zy@k8s-master:~$ kubectl apply -f mypod-env.yml
pod/mypod created
查看:
zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # echo $SECRET_USERNAME
zhangyin
/ # echo $SECRET_PASSWORD
abcdef
注意:虽然用环境变量查看更加方便,但不支持动态更新。
3. ConfigMap
Serect可以为Pod提供密码、Token、私钥等敏感数据,对于一些非敏感数据,比如应用的配置信息,则可以用ConfigMap。
ConfigMap的创建和使用方式与Serect非常类似,主要的不同是数据以明文的形式存放。
与secret一样,configMap也支持四种创建方式,这里以yml方式演示:
(1)Volume方式
zy@k8s-master:~$ cat configmap.yml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap
data:
config1: xxx
config2: yyy
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
volumes: #将volumes字段移动到这里
- name: foo
configMap:
name: myconfigmap
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 10; touch /tmp/healthy; sleep 30000
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
apply一下:
zy@k8s-master:~$ kubectl apply -f configmap.yml
configmap/myconfigmap created
zy@k8s-master:~$ kubectl apply -f mypod-cfg.yml
pod/mypod created
进入pod查看:
zy@k8s-master:~$ kubectl exec -it mypod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /etc/foo
/etc/foo # ls
config1 config2
/etc/foo # cat config1
xxx/etc/foo #
/etc/foo # cat config2
yyy/etc/foo #