一、用kubernetes管理机密信息
应用启动过程中可能需要一些敏感信息,比如访问数据库的用户名密码或者秘钥,将这些信息直接保存在容器镜像中显然不妥,kubernetes提供了解决方案是secret
secret资源对象:解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。
secret可通过命令行或YAML创建。比如希望secret包含如下信息:
1.用户名 admin 2.密码 123456
二、创建secret
1.通过 --from-kiteral:
kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456
每个 --from-literal 对应一个信息条目。
Generic:通用的、一般的。加密方式。
2.通过--from-file:
echo -n admin > ./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username --from-file=./password
每个文件内容对应一个信息条目
这种方式不推荐使用,需要将存储的数据写入到文件中,注意每个文件只能存储一个数据。
3.通过--from-env-file:
cat > env.txt << EOF
> username=admin
> password=123456
> EOF
kubectl create secret generic mysecret --from-env-file=env.txt
这种方式可以在同一个文件内写入多个数据
4.通过yaml配置文件:
[root@k8s-master ~]# echo -n admin | base64
YWRtaW4=
[root@k8s-master ~]# echo -n 123456 | base64
MTIzNDU2
vim env.yml
apiVersion: v1
data:
password: MTIzNDU2
username: YWRtaW4=
kind: Secret
metadata:
name: mysecret
把需要保存的数据加密:
查看value
kubectl edit secrets mysecret
通过base64将value反编码
[root@k8s-master ~]# echo -n MTIzNDU2 | base64 --decode
123456
[root@k8s-master ~]# echo -n YWRtaW4= | base64 --decode
admin
三、volume方式使用secret
1.pod可以通过volume或者环境变量的方式使用secret
pod配置文件如下:
vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
volumeMounts:
- mountPath: /etc/foo
name: foo
readOnly: true
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: foo
secret:
secretName: mysecret
1.定义volume 为foo,来源为secret mysecret。
2.将foo mount到容器路径 /etc/foo,可指定读写权限为readOnly
可以看到,kubernetes会在指定的路径/etc/foo/username和 /etc/foo/password, value则以明文存放在文件中。
2.我们也可以自定义存放数据的文件名:
vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
volumeMounts:
- mountPath: /etc/foo
name: foo
readOnly: true
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
- key: password
path: my-group/my-password
这时数据将分别存放在 /etc/foo/my-group/my-username 和 /etc/foo/my-group/my-password中。
3.以volume方式使用的secret 支持动态更新: secret更细后,容器中的数据也就更新。
[root@k8s-master mysecret]# echo -n abc456 | base64
YWJjNDU2
apiVersion: v1
data:
password: YWJjNDU2
username: YWRtaW4=
kind: Secret
metadata:
name: mysecret
kubectl apply -f env.yml
几秒钟或,新的password会同步到容器。
四、环境变量方式使用secret
通过volume使用secret ,容器必须从文件读取数据,会稍微麻烦,kubernetes还支持通过环境变量使用secret‘。
vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
args:
- /bin/sh
- -c
- sleep 30000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
’ 验证结果:
通过环境变量secret_username和secret_password成功读取到secret的数据。
需要注意的是,环境变量读取secret很方便,但无法支撑secret动态更新。
五、用configMap管理配置
secret可以为pod提供密码、token,私钥等敏感数据;对于一些非敏感数据,比如应用的配置信息,用configMap。
configMap的创建和使用方法好与secregt非常类似,主要的不同是数据以明文形式存放。
1.通过--from-literal:
kubectl create configmap myconfigimap --from-literal=config1=xxx --from-literal=config2=yy
每个--from-literal对应一个信息条目。
2.通过--from-file:
echo -n xxx > ./config1
echo -n yyy > ./config2
kubectl create configmap myconfigmap1 --from-file=./config1 --from-file=./config2
每个文件内容对应一个信息条目。
3.通过 --from-env-file:
cat << EOF > env.txt
config1=xxx
config2=yyy
EOF
kubectl create configmap myconfigmap2 --from-env-file=env.txt
文件env.txt中每行key=value对应每一个信息条目。
4.通过YAML配置文件:
vim env.yml
apiVersion: v1
data:
config1: xxx
config2: yyy
kind: ConfigMap
metadata:
name: myconfigmap3
六、案例:
1.volume方式:
vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
volumeMounts:
- mountPath: /etc/foo
name: foo
readOnly: true
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: foo
configMap:
name: myconfigmap3
2.环境变量方式:
vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
args:
- /bin/sh
- -c
- sleep 30000
env:
- name: CONFIG_1
valueFrom:
configMapKeyRef:
name: myconfigmap3
key: config1
- name: CONFIG_2
valueFrom:
configMapKeyRef:
name: myconfigmap3
key: config2
大多数情况下,配置信息都已文件形式提供,所以在创建configMap时通常采用 --from-file或ymal方式,读取configMap 时通常采用volume方式
1.比如给pod传递如何记录日志的配置信息:
class: logging.handlers.RotatingFileHandler
formatter: precise
level: INFO
filename: %hostname-%timestamp.log
2.采用--from-file兴盛生成配置文件保存在logging.conf中,然后执行命令:
kubectl create configmap myconfigmap4 --from-file=loggin.conf --dry-run -o yaml
创建并查看configmap:
kubectl create configmap myconfigmap4 --from-file=loggin.conf --dry-run -o yaml> myconfigmap1.yml
kubectl apply -f myconfigmap1.yml
kubectl get configmaps
kubectl describe configmaps myconfigmap4
3.在pod中使用此configMap,配置文件为:
vim pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- image: busybox
name: mypod
args:
- /bin/sh
- -c
- sleep 30000
volumeMounts:
- mountPath: "/etc/config"
name: foo
volumes:
- name: foo
configMap:
name: myconfigmap4
items:
- key: loggin.conf
path: myapp/loggin.conf
1.在volume中指定存放配置文件的相对路径为myapp、loggin.conf
2.将volume mount到容器 /etc/config 目录。
4.创建pod并读取配置信息:
kubectl exec -it mypod sh
配置信息已经保存到/etc/myapp/loggin.conf文件中。secret一样,volume形式的configMAP也支持动态更新。