文章目录
实验环境
完成初始化集群的环境:
(vms21)192.168.26.21——master1
(vms22)192.168.26.22——worker1
(vms23)192.168.26.23——worker2
我们创建pod的时候,有些pod里是需要去引用密码的,如容器里用到mysql,则需要去指定mysql密码,等等这些密码在pod里是以引用的方式来存储的,这样或多或少会有安全隐患,因此,我们需要有更好的方案去管理密码
一、secret
secret里的存储的数据都是以键值对的方式存储的(键=值)
1.创建
a.命令行方式创建(推荐)
方式一:创建secret,并赋上键值对
#--from-literal后的“=”可以省略
kubectl create secret generic [secret名字] --from-literal=[键]=[值]
#可以有多个键值对
kubectl create secret generic [secret名字] --from-literal=[键]=[值] --from-literal=[键]=[值]
方式二:以一个文件路径的方式存储
以文件路径存储时,会以路径的basename作为键,以文件的内容作为值
什么是basename,什么是dirname?
basename——一个路径的最后一部分
dirname——一个路径除了basename的部分
如一个文件的路径为 “/usr/share/doc/pam-1.1.8/txts/README.pam_access”
basename /usr/share/doc/pam-1.1.8/txts/README.pam_acces
#输出:
README.pam_acces
dirname /usr/share/doc/pam-1.1.8/txts/README.pam_acces
#输出:
/usr/share/doc/pam-1.1.8/txts
以路径方式存储:
kubectl create secret generic [secret名字] --from-file [路径] --from-file [路径]
#例:
kubectl create secret generic mysecret2 --from-file /etc/hosts --from-file /etc/issue
#如以上,键=hosts、值=文件的内容,键=issue、值=文件的内容
b.通过yaml文件创建
通过命令行导出yaml文件模板
kubectl create secret generic [secret名字] --from-literal=[键]=[值] --dry-run=client -o yaml
例1:
kubectl create secret generic mysecret1 --from-literal=x=1
2.删除secret
kubectl delete secret [secret名]
3.查看secret
列出所有secret
kubectl get secrets
查看secret属性
kubectl describe secret [secret名字]
#如上例1创建的mysecret1的属性输出
Name: mysecret1
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
x: 1 bytes
describe中能看到的信息只有“键: 值的大小”(如例1的x: 1bytes)
若想查看值具体是多少(通过base64编码过后的值),则使用:
kubectl get secrets [secret名字] -o yaml
#如例1:
apiVersion: v1
data:
x: MQ==
kind: Secret
metadata:
creationTimestamp: "2022-07-05T06:17:54Z"
name: mysecret1
namespace: default
resourceVersion: "866324"
uid: 90d82bd9-a40b-4176-9a83-abf53c2bd245
type: Opaque
然后可以通过base64解码:
# | xargs echo:换行
echo [base64编码后的值] | base64 -d | xargs echo
#如例1:
echo MQ== | base64 -d | xargs echo
#输出:
1
获取值的更快的写法:
kubectl get secrets [secret名] -o jsonpath='{.data.[键]}' | base64 -d | xargs echo
#例:
kubectl get secrets mysecret1 -o jsonpath='{.data.x}' | base64 -d | xargs echo
4.使用
a.以变量的方式来引用(一般都使用这种方法)
以pod中指定mysql密码为例:
(1)master上创建secret
kubectl create secret generic mysecret1 --from-literal=x=root
(2)在所有worker节点上拉取mysql镜像
nerdctl pull hub.c.163.com/library/mysql
(3)在master上安装客户端工具
yum install mariadb -y
(4)在master上编辑pod的yaml文件
镜像指定mysql镜像,添加变量MYSQL_ROOT_PASSWORD、值valueFrom表示从其他地方引用值
secretKeyRef表示引用secret,secretKeyRef.name指定引用哪个secret,secretKeyRef.key指定引用该secret下哪个键对应的值
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: dbpod
name: dbpod
spec:
containers:
- image: hub.c.163.com/library/mysql
imagePullPolicy: IfNotPresent
name: c1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret1
key: x
dnsPolicy: ClusterFirst
restartPolicy: OnFailure
status: {}
(5)创建pod,查看pod的IP
kubectl apply -f xxx.yaml
kubectl get pods -owide
#输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dbpod 1/1 Running 0 9s 10.244.70.78 vms23.rhce.cc <none> <none>
(6)创建完pod后,IP为10.244.70.78测试连接数据库
mysql -uroot -proot -h10.244.70.78
#输出:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(7)实验完成,退出数据库,删除dbpod
#退出数据库
quit
#删除dbpod
kubectl delete pod dbpod
b.以卷的方式来引用
沿用上一次实验的环境:
(1)master中定义pod的yaml:
这里镜像使用nginx实验
spec下定义卷volumes,卷类型定义为secret,secretName指定secret名
容器中挂载该卷到/data目录中去(将会在/data里创建文件,secret有几个键就会创建几个文件,文件名就是键,文件内容就是键对应的值)
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
volumes:
- name: v1
secret:
secretName: mysecret1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /data
dnsPolicy: ClusterFirst
restartPolicy: OnFailure
status: {}
(2)创建pod,并进入pod打开bash,检查/data下是否根据secret的键值对创建了文件
kubectl exec -it pod1 -- bash
cd /data
ls
#输出:
x
cat x
#输出:
root
若secret中有多个键值对,但是创建pod指定时,只想引用某个键(在/data下只创建这个键的文件),而不是所有键值对
可以在pod的yaml中容器的配置项subPath配置
如下:只想引用x这个键
...
spec:
volumes:
- name: v1
secret:
secretName: mysecret1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /data
subPath: x
...
注:一旦配置了subPath,那么容器挂载的目录mountPath,即这里为 “/data”,就会变成一个文件(文件内容即键对应的值),不再是一个目录
若还是想让 “/data” 保持为一个目录,则mountPath处的 “/data” 应该写成 “/data/xxxx”,意为在/data下根据引用的键创建一个名为xxxx的文件,文件内容为键对应的值
一般情况下,我们使用secret,一般通过变量的方式来引用,以卷的方式来引用的时候,主要目的是为了往pod里传递配置文件
二、configMap
configMap简称cm
1.创建
a.命令行方式创建(推荐)
#同secret,键值对可以一个或多个
#--from-literal后的“=”可以省略
kubectl create cm [configMap名字] --from-literal=[键]=[值] --from-literal=[键]=[值]
b.通过yaml文件创建
通过命令行导出yaml文件模板
kubectl create cm [configMap名字] --from-literal=[键]=[值] --dry-run=client -o yaml
例1:
kubectl create cm mycm1 --from-literal=x=1 --from-literal=y=2
2.删除configMap
kubectl delete cm [configMap名]
3.查看configMap
列出所有configMap
kubectl get cm
查看configMap属性,这里不同于secret,属性中直接就能显示键值对的值
kubectl describe cm [configMap名]
#如查看例1
kubectl describe cm mycm1
#输出:
Name: mycm1
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
x:
----
1
y:
----
2
BinaryData
====
Events: <none>
当然也可以通过-o yaml查看
kubectl get cm [configMap名] -o yaml
#如查看例1
kubectl get cm mycm1 -o yaml
#输出:
apiVersion: v1
data:
x: "1"
"y": "2"
kind: ConfigMap
metadata:
creationTimestamp: "2022-07-05T09:29:05Z"
name: mycm1
namespace: default
resourceVersion: "888250"
uid: 5a93dfad-f571-4a5e-b0bd-c621c62d4440
也可以用json格式查看
kubectl get cm [configMap名] -o jsonpath='{.data.[键]}'
2.使用
a.以变量的方式来引用
以pod中指定mysql密码为例(沿用secret实验中的环境):
(1)master上创建configMap
kubectl create cm mycm1 --from-literal=x=root
(2)在master上编辑pod的yaml文件
镜像指定mysql镜像,添加变量MYSQL_ROOT_PASSWORD、值valueFrom表示从其他地方引用值
configMapKeyRef表示引用configMap,configMapKeyRef.name指定引用哪个configMap,configMapKeyRef.key指定引用该configMap下哪个键对应的值
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: dbpod
name: dbpod
spec:
containers:
- image: hub.c.163.com/library/mysql
imagePullPolicy: IfNotPresent
name: c1
resources: {}
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
configMapKeyRef:
name: mycm1
key: x
dnsPolicy: ClusterFirst
restartPolicy: OnFailure
status: {}
(5)创建pod,查看pod的IP
kubectl apply -f xxx.yaml
kubectl get pods -owide
#输出:
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dbpod 1/1 Running 0 3s 10.244.70.84 vms23.rhce.cc <none> <none>
(6)创建完pod后,IP为10.244.70.84测试连接数据库
mysql -uroot -proot -h10.244.70.84
#输出:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.7.18 MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(7)实验完成,退出数据库,删除dbpod
#退出数据库
quit
#删除dbpod
kubectl delete pod dbpod
b.以卷的方式来引用(一般都使用这种方法)
沿用上一次实验的环境:
(1)master中定义pod的yaml:
这里镜像使用nginx实验
spec下定义卷volumes,卷类型定义为configMap,name指定configMap名
容器中挂载该卷到/data目录中去(将会在/data里创建文件,configMap有几个键就会创建几个文件,文件名就是键,文件内容就是键对应的值)
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
volumes:
- name: v1
configMap:
name: mycm1
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /data
dnsPolicy: ClusterFirst
restartPolicy: OnFailure
status: {}
(2)创建pod,并进入pod打开bash,检查/data下是否根据config的键值对创建了文件
kubectl exec -it pod1 -- bash
cd /data
ls
#输出:
x y
cat x
#输出:
1
subPath配置和规则和secret相同,配置了subPath,则mountPath后的路径会变成一个文件而不是目录
configMap使用以卷的方式来引用,主要的目的往pod里传送文件
例:
首先,我们根据刚刚创建的pod1,在master上将里面的nginx容器的/etc/nginx/nginx.conf拷贝一份出来
kubectl cp pod1:/etc/nginx/nginx.conf nginx.conf
然后pod1用不到了,我们先删除它
kubectl delete pod pod1
现在,我们创建一个名为 “nginx-conf-file” 的configMap,键值对以一个文件路径的方式,文件路径即刚刚拷贝出来的nginx.conf
这样一来,键就是nginx.conf这个文件名,而值就是nginx.conf这个配置文件里的内容
kubectl create cm nginx-conf-file --from-file=./nginx.conf
master中编辑pod的yaml文件:
1.指定spec下的configMap类型的卷,指定名为nginx-conf-file的这个configMap
2.指定spec.containers的容器挂载卷volumeMounts,但是这里要注意,若直接将mountPath定义为/etc/nginx/,则容器会启动不起来,因为会将nginx.conf这个键的值(即配置文件内容)覆盖到/etc/nginx下,导致/etc/nginx下的其他文件都没了
因此需要用到subPath,并且mountPath定义为/etc/nginx/nginx.conf,这样一来,就会以nginx.conf为文件名,将键值对的值作为文件内容,形成一个新的nginx.conf文件在/etc/nginx/下,这样就不会覆盖/etc/nginx下原来的文件
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: pod1
name: pod1
spec:
volumes:
- name: v1
configMap:
name: nginx-conf-file
containers:
- image: nginx
imagePullPolicy: IfNotPresent
name: c1
resources: {}
volumeMounts:
- name: v1
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
dnsPolicy: ClusterFirst
restartPolicy: OnFailure
status: {}
创建这个pod
kubectl apply -f xxx.yaml
若想要修改pod中nginx容器的这个配置文件
可以直接编辑名为nginx-conf-file的这个configMap
kubectl edit cm nginx-conf-file
修改完之后要重启(重新创建)这个pod
kubectl get pods pod1 -o yaml > /tmp/pod1.yaml | kubectl delete po pod1 | kubectl apply -f /tmp/pod1.yaml
这个方法同样可以应用于命名空间kube-system下的pod,如calico-conf、kube-proxy(kube-proxy控制转发,service-svc会控制转发到哪个后端的pod,可以通过配置选择使用iptables还是ipvs)等
我们只要创建一个对应的cm,就可以直接通过kubectl edit cm kube-proxy -n kube-system