八、K8s 密码管理
实验环境:按照图示部署好了K8s集群,一个Master,两个worker nodes。没有密码管理的场景:
实验环境:
按照图示部署好了K8s集群,一个Master,两个worker nodes。
没有密码管理的场景:
master上编辑mysql的yaml文件并应用:
[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: mysqldb
spec:
terminationGracePeriodSeconds: 0
containers:
- image: mysql:latest
imagePullPolicy: IfNotPresent
name: c1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
value: mysql111
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/mysqldb created
通过yaml文件设置的环境变量,登陆mysql数据库,首先要找到运行的node为vms203.rhce.cc:
[root@vms201 secret_manager]# kubectl get pod mysqldb -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mysqldb 1/1 Running 0 7m42s 10.244.185.93 vms203.rhce.cc <none> <none>
在vms203.rhce.cc上:进入mysql容器,用设置的账号密码登陆mysql。
[root@vms203 ~]# docker exec -it 8106c3ed3f52 bash
root@mysqldb:/# mysql -uroot -pmysql111
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.25 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
通过在yaml文件直接设置容器的密码(或者其他敏感信息)十分的方便,但是由于密码在yaml文件中是明文的,十分不安全。所以如何保护用户的密码等敏感信息,则需要用K8s的密码管理功能来完成。
K8s的密码管理分为两种:
- secret
- configmap–cm
一、secret:
使用方式:
- 以变量的方式;(推荐,用来保存密码)
- 以卷的方式。
secret的类型:
- Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,所有加密性很弱。(本节重点)
- kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息,在yaml文件中可以使用imagePullSecrets来引用。
- kubernetes.io/service-account-token: 用于被serviceaccount引用。serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中。
如何创建Opaque的secret:
secret以键值对的方式存在。
方式1: 命令行的方式(推荐)
语法:
kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=键1=值1 --from-literal=键2=值2
kubectl create secret generic mysecret1 --from-file=user=tom --from-file=/etc/hosts(文件信息)
第二种语法secret的键为去掉路径的文件名hosts,值为文件的内容。
创建并查看其中的secret:
[root@vms201 secret_manager]# kubectl create secret generic mysecret1 --from-literal=user=tom --from-literal=password1=redhat --from-literal=password2=redhat
secret/mysecret1 created
[root@vms201 secret_manager]# kubectl get secrets mysecret1
NAME TYPE DATA AGE
mysecret1 Opaque 3 32s
[root@vms201 secret_manager]# kubectl describe secrets mysecret1
Name: mysecret1
Namespace: 3-volume
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password1: 6 bytes
password2: 6 bytes
user: 3 bytes
以yaml文件输出:
[root@vms201 secret_manager]# kubectl get secrets mysecret1 -o yaml
apiVersion: v1
data:
password1: cmVkaGF0
password2: cmVkaGF0
user: dG9t
kind: Secret
metadata:
creationTimestamp: "2021-07-06T13:52:58Z"
name: mysecret1
namespace: 3-volume
resourceVersion: "164131"
selfLink: /api/v1/namespaces/3-volume/secrets/mysecret1
uid: 1a92f9d7-560b-4fca-969e-c8da94554468
type: Opaque
其中存储的信息被base64编码过,可以解码检查一下是不是保存的密码redhat:
[root@vms201 secret_manager]# echo cmVkaGF0 | base64 -d
redhat
以json格式输出:
[root@vms201 secret_manager]# kubectl get secrets mysecret1 -o jsonpath={.data.password1} | base64 -d
redhat
其他方式:
1.设置文件:
cat env.txt
user=tom
password1=redhat
password2=redhat
kubectl create secret generic mysecret3--from-env-file=env.txt
2.自己编写yaml文件:
echo -n 'tom' | base64
echo -n 'redhat' | base64
apiVersion: v1
kind: Secret
metadata:
name: mysecret4
type: Opaque
data:
user: dG9t
password1: cmVkaGF0
password2: cmVkaGF0
以变量的方式引用Opaque的secret:
编辑pod的yaml文件:
[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: mysqldb
spec:
terminationGracePeriodSeconds: 0
containers:
- image: mysql:latest
imagePullPolicy: IfNotPresent
name: c1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret1
key: password1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
yaml文件引用了之前创建的mysecret1和其password1。应用yaml文件生成mysql的pod:
[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/mysqldb created
查看其运行在哪个worker node上,并在在其node上登陆mysql:
[root@vms201 secret_manager]# kubectl get pod mysqldb -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READIN ESS GATES
mysqldb 1/1 Running 0 69s 10.244.185.94 vms203.rhce.cc <none> <none>
[root@vms203 ~]# docker exec -it bc79448a1142 bash
root@mysqldb:/# mysql -uroot -predhat
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.25 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
以卷的方式引用Opaque的secret:
修改pod的yaml文件,并应用:
[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: podsecret
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: v1
secret:
secretName: mysecret1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /xx
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/podsecret created
进入此pod查看secret是否被挂载进来:在/xx目录下有mysecret1的下记录的密码信息。
[root@vms201 secret_manager]# kubectl exec -it podsecret -- bash
root@podsecret:/# cat /xx/password1
redhatroot
如果只想传递mysecret1下的指定信息,例如password1到容器内,需要修改yaml文件,在mountPath下一行加入subPath,指定password1:
- name: v1
mountPath: /xx/password1
subPath: password1
这样一来,仅会将mysecret1的password1挂载到容器的/xx/下,命名为password1(可修改)。
以卷的方式引用Opaque的secret的常用应用:例如将Nginx的配置文件设置为secret,然后在设置Nginx的pod时,将其挂载到/etc/nginx/nginx.conf文件下,这样就传递了Nginx的配置文件,但是不推荐这种方法,在edit secret时,其中的内容是被base64编码的的,不方便修改。
二、configmap–cm
使用方式:
- 以变量的方式;
- 以卷的方式。(推荐,来来传递配置文件)
其创建方式和secret类似:这里只说明了以literal的方式创建,同样可以file的方式创建
[root@vms201 secret_manager]# kubectl create cm mycm1 --from-literal=password1=redhat
configmap/mycm1 created
[root@vms201 secret_manager]# kubectl get cm mycm1
NAME DATA AGE
mycm1 1 26s
[root@vms201 secret_manager]# kubectl describe cm mycm1
Name: mycm1
Namespace: 3-volume
Labels: <none>
Annotations: <none>
Data
====
password1:
----
redhat
Events: <none>
当我们以yaml文件输出cm时,可以看到信息没有被base64编码:
[root@vms201 secret_manager]# kubectl get cm mycm1 -o yaml
apiVersion: v1
data:
password1: redhat
kind: ConfigMap
metadata:
creationTimestamp: "2021-07-06T15:04:26Z"
name: mycm1
namespace: 3-volume
resourceVersion: "170439"
selfLink: /api/v1/namespaces/3-volume/configmaps/mycm1
uid: e3d3d3b2-f47f-41eb-9aea-dc7d1bcd7732
以变量的方式调用cm:
其yaml文件如下:
[root@vms201 secret_manager]# cat pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: mysqldb
spec:
terminationGracePeriodSeconds: 0
containers:
- image: mysql:latest
imagePullPolicy: IfNotPresent
name: c1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef:
name: mycm1
key: password1
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
以卷的方式调用cm:
在master上保存nginx.conf文件:
[root@vms201 secret_manager]# cat nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
创建mycm2:
[root@vms201 secret_manager]# kubectl create cm mycm2 --from-file nginx.conf
configmap/mycm2 created
编辑pod的yaml文件,将mycm2挂载到指定目录:
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: podcm
spec:
terminationGracePeriodSeconds: 0
volumes:
- name: v1
configMap:
name: mycm2
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
生成对应的pod:
[root@vms201 secret_manager]# kubectl apply -f pod.yaml
pod/podcm created
可以在pod中查看到到对应的配置文件:
[root@vms201 secret_manager]# kubectl exec -it podcm -- bash
root@podcm:/# cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
如果想要修改这个nginx的配置文件,仅需要在master上edit对应的cm即可:
[root@vms201 secret_manager]# kubectl edit cm mycm2
由于其中保存的信息是明文,方便修改。然后删除掉当前pod,重新创建即可。
K8s创建后存在的一些cm:
[root@vms201 secret_manager]# kubectl get cm -n kube-system
NAME DATA AGE
calico-config 4 5d1h
coredns 1 5d1h
extension-apiserver-authentication 6 5d1h
kube-proxy 2 5d1h
kube-root-ca.crt 1 5d1h
kubeadm-config 2 5d1h
kubelet-config-1.21 1 5d1h
这些cm都可以修改,完成后删除重建对应pod即可。
参考资料:
《老段CKA课程》
更多推荐
所有评论(0)