Kubernetes中的cm存储
华子目录
- 1.`configmap`
- 1.1`configmap`功能
- 1.2`configmap`应用场景
- 1.3`configmap`的使用场景
- 1.4configmap创建方式
- 1.4.1键值对创建
- 1.4.2通过文件创建
- 1.4.3通过`目录`创建
- 1.4.4通过`yaml`文件创建
- 1.5configmap的应用示例
- 1.5.1使用cm填充环境变量
- 1.5.2通过数据卷使用configmap
- 1.5.3利用`configmap`填充`pod中容器的配置文件`
1.configmap
1.1configmap
功能
configmap
用于保存配置数据
,以键值对
形式存储configmap
资源提供了向pod
注入配置数据
的方法,让pod
在运行的时候能够识别configmap
资源镜像
和配置文件
可以不在同一个主机
上,以便实现镜像
的可移植性
和可复用性
etcd
中记录了configmap
的状态
,它
限制了configmap
的文件大小
不能超过1M
configmap
资源中的数据
是明文
的
1.2configmap
应用场景
比如我们需要运行一个nginx服务器
,但是nginx镜像
中的配置文件
不能适用于所有
的生产场景
,经常需要我们自建配置文件
。但是在k8s
环境中,我们不能保证运行nginx容器
的pod
和我们自建配置文件
在同一个主机
上,同时我们在运行pod
的时候,也不会因为自建的配置文件
在哪个主机上
,就让pod
在哪台主机上
运行。所以我们要把自建的配置文件
放到k8s集群
中,并且每次启动pod
的时候,能够让pod
自动去加载
这些东西,换句话说
就是把我们自建的配置文件
变成k8s
中的资源
,每个pod
(不管在哪个node节点
上)在运行的时候都可以对这些资源
进行使用
。这个时候就要使用configmap
1.3configmap
的使用场景
- 填充
环境变量
的值
- 设置
容器内
的命令行参数
填充卷
的配置文件
1.4configmap创建方式
configmap
简称cm
[root@k8s-master ~]# mkdir configmap
[root@k8s-master ~]# cd configmap/
#kube-root-ca.crt是k8s自带的configmap资源,用来对所有运行的pod进行身份认证
[root@k8s-master configmap]# kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 28d
比如这里我们运行一个简单的pod
,观察一下
[root@k8s-master configmap]# kubectl run testpod --image myapp:v1
pod/testpod created
[root@k8s-master configmap]# kubectl describe pods testpod
我们可以看到testpod
这个pod
中ConfigMapName
是kube-root-ca.crt
[root@k8s-master configmap]# kubectl delete pods testpod
pod "testpod" deleted
1.4.1键值对创建
- 通过
--from-literal
指定键值对
#创建一个名为userlist的configmap
[root@k8s-master configmap]# kubectl create configmap userlist --from-literal name=huazi --from-literal age=22
configmap/userlist created
[root@k8s-master configmap]# kubectl get configmaps
NAME DATA AGE
kube-root-ca.crt 1 28d
userlist 2 103s
#我们可以看到创建的键值对
[root@k8s-master configmap]# kubectl describe configmaps userlist
Name: userlist
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
age:
----
22
name:
----
huazi
BinaryData
====
Events: <none>
1.4.2通过文件创建
- 通过
--from-file
指定文件名
#我们首先看一下/etc/hosts这个文件中的内容
[root@k8s-master configmap]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100 k8s-master.org
172.25.254.10 k8s-node1.org
172.25.254.20 k8s-node2.org
172.25.254.250 harbor.huazi.org
172.25.254.50 www.huazi.com myappv1.huazi.com myappv2.huazi.com
#创建一个名为host的configmap资源
[root@k8s-master configmap]# kubectl create configmap host --from-file /etc/hosts
configmap/host created
[root@k8s-master configmap]# kubectl get configmaps
NAME DATA AGE
host 1 86s
kube-root-ca.crt 1 28d
userlist 2 7m40s
[root@k8s-master configmap]# kubectl get configmaps host
NAME DATA AGE
host 1 106s
[root@k8s-master configmap]# kubectl describe configmaps host
Name: host
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
hosts:
----
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100 k8s-master.org
172.25.254.10 k8s-node1.org
172.25.254.20 k8s-node2.org
172.25.254.250 harbor.huazi.org
172.25.254.50 www.huazi.com myappv1.huazi.com myappv2.huazi.com
BinaryData
====
Events: <none>
我们可以发现通过文件
创建的configmap资源
,文件名
是键
,文件内容
是值
1.4.3通过目录
创建
- 通过
--from-file
指定目录
[root@k8s-master configmap]# cat /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100 k8s-master.org
172.25.254.10 k8s-node1.org
172.25.254.20 k8s-node2.org
172.25.254.250 harbor.huazi.org
172.25.254.50 www.huazi.com myappv1.huazi.com myappv2.huazi.com
[root@k8s-master configmap]# cat /etc/resolv.conf
# Generated by NetworkManager
search org
nameserver 114.114.114.114
#创建一个目录,将/etc/hosts和/etc/resolv.conf文件复制到这个目录下
[root@k8s-master configmap]# mkdir testdir
[root@k8s-master configmap]# cp /etc/hosts testdir/
[root@k8s-master configmap]# cp /etc/resolv.conf testdir/
[root@k8s-master configmap]# ls testdir/
hosts resolv.conf
#创建一个名为test的configmap资源
[root@k8s-master configmap]# kubectl create cm test --from-file testdir/
configmap/test created
[root@k8s-master configmap]# kubectl get cm
NAME DATA AGE
host 1 13m
kube-root-ca.crt 1 28d
test 2 81s
userlist 2 19m
[root@k8s-master configmap]# kubectl get cm test
NAME DATA AGE
test 2 118s
[root@k8s-master configmap]# kubectl describe cm test
Name: test
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
hosts:
----
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
172.25.254.100 k8s-master.org
172.25.254.10 k8s-node1.org
172.25.254.20 k8s-node2.org
172.25.254.250 harbor.huazi.org
172.25.254.50 www.huazi.com myappv1.huazi.com myappv2.huazi.com
resolv.conf:
----
# Generated by NetworkManager
search org
nameserver 114.114.114.114
BinaryData
====
Events: <none>
我们发现通过目录创建
是文件创建
的升级版
,目录
中可以存放多个文件
,文件名
为键
,文件内容
为值
1.4.4通过yaml
文件创建
#创建一个名为dict的configmap资源,通过--from-literal指定它的键值对
[root@k8s-master configmap]# kubectl create configmap dict --from-literal db_host="172.25.254.100" --from-literal db_port="3306" -o yaml > db.yml
[root@k8s-master configmap]# vim db.yml
[root@k8s-master configmap]# cat db.yml
apiVersion: v1 #Kubernetes API版本是v1
data: #ConfigMap中存储的实际数据。这些数据是以键值对的形式存储的。
db_host: 172.25.254.100
db_port: "3306"
kind: ConfigMap #资源对象的类型是ConfigMap
metadata: #ConfigMap的元数据
name: dict #configmap的名字
[root@k8s-master configmap]# kubectl apply -f db.yml
configmap/dict configured
[root@k8s-master configmap]# kubectl describe cm dict
Name: dict
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
db_host:
----
172.25.254.100
db_port:
----
3306
BinaryData
====
Events: <none>
1.5configmap的应用示例
- 通过
环境变量
的方式直接传递给pod
- 通过
pod
的命令行运行方式 - 作为
volume
的方式
挂载到pod
内
1.5.1使用cm填充环境变量
[root@k8s-master configmap]# cat db.yml
apiVersion: v1
data:
db_host: 172.25.254.100
db_port: "3306"
kind: ConfigMap
metadata:
name: dict
[root@k8s-master configmap]# kubectl apply -f db.yml
#查看创建名为dict的configmap资源
[root@k8s-master configmap]# kubectl describe cm dict
Name: dict
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
db_port:
----
3306
db_host:
----
172.25.254.100
BinaryData
====
Events: <none>
- 将名为
dict
的cm资源
中的内容
映射为指定的变量
#创建一个名为testpod的自主式pod
[root@k8s-master configmap]# vim pod1.yml
[root@k8s-master configmap]# cat pod1.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus
name: busyboxplus
command: ["/bin/sh","-c","env"] #容器启动时执行的命令,这里使用/bin/sh执行env命令,用于打印环境变量。
env: #定义了容器内的环境变量
- name: key1 #环境变量的名字
valueFrom: #指定了环境变量的值来源
configMapKeyRef: #表示环境变量的值是从一个ConfigMap中获取的
name: dict #ConfigMap的名称为dict
key: db_host #在指定的ConfigMap中,db_host键对应的值将被用作环境变量key1的值
- name: key2 #环境变量的名字
valueFrom: #指定了环境变量的值来源
configMapKeyRef: #表示环境变量的值是从一个ConfigMap中获取的
name: dict #ConfigMap的名称为dict
key: db_port #在指定的ConfigMap中,db_host键对应的值将被用作环境变量key1的值
restartPolicy: Never #pod的启动规则
[root@k8s-master configmap]# kubectl apply -f pod1.yml
pod/testpod created
[root@k8s-master configmap]# kubectl get pods testpod
NAME READY STATUS RESTARTS AGE
testpod 0/1 Completed 0 22s
[root@k8s-master configmap]# kubectl logs pods/testpod
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=testpod
SHLVL=1
HOME=/
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
key1=172.25.254.100 #我们发现了创建的key1变量
key2=3306 #我们发现了创建的key2变量
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
#回收pod1.yml
[root@k8s-master configmap]# kubectl delete -f pod1.yml
pod "testpod" deleted
- 将名为
dict
的cm资源
中的内容
直接映射为变量
[root@k8s-master configmap]# vim pod2.yml
[root@k8s-master configmap]# cat pod2.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus
name: busyboxplus
command: ["/bin/sh","-c","env"] #容器启动时执行的命令,这里使用/bin/sh执行env命令,用于打印环境变量。
envFrom: #这是一个列表,用于指定一个或多个ConfigMap或Secret,它们的内容将被作为环境变量直接导入到Pod的容器中。
- configMapRef: #环境变量的来源是一个ConfigMap
name: dict #ConfigMap的名称为dict。这意味着Kubernetes将查找名为dict的ConfigMap
restartPolicy: Never
[root@k8s-master configmap]# kubectl apply -f pod2.yml
pod/testpod created
[root@k8s-master configmap]# kubectl logs pods/testpod
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=testpod
SHLVL=1
HOME=/
db_port=3306 #我们可以发现直接映射为了变量
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
db_host=172.25.254.100 #我们发现直接映射为了变量
#回收
[root@k8s-master configmap]# kubectl delete -f pod2.yml
pod "testpod" deleted
- 在
command
中直接使用变量
#创建名为testpod的自主式pod
[root@k8s-master configmap]# vim pod3.yml
[root@k8s-master configmap]# cat pod3.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus
name: busyboxplus
command: ["/bin/sh","-c","echo ${db_host} ${db_port}"]
envFrom: ##这是一个列表,用于指定一个或多个ConfigMap或Secret,它们的内容将被作为环境变量直接导入到Pod的容器中。
- configMapRef: ##环境变量的来源是一个ConfigMap
name: dict #ConfigMap的名称为dict。这意味着Kubernetes将查找名为dict的ConfigMap
restartPolicy: Never
[root@k8s-master configmap]# kubectl apply -f pod3.yml
pod/testpod created
[root@k8s-master configmap]# kubectl logs pods/testpod
172.25.254.100 3306
#我们发现使用到了dict中的db_host和db_port
#回收
[root@k8s-master configmap]# kubectl delete -f pod3.yml
pod "testpod" deleted
1.5.2通过数据卷使用configmap
#创建一个名为testpod的自主式pod
[root@k8s-master configmap]# vim pod4.yml
[root@k8s-master configmap]# cat pod4.yml
apiVersion: v1
kind: Pod
metadata:
labels:
run: testpod
name: testpod
spec:
containers:
- image: busyboxplus
name: busyboxplus
command: ["/bin/sh","-c","sleep 10000"]
volumeMounts: #这是一个列表,定义了Pod中容器要挂载的卷。
- name: config-volume #指定了要挂载的卷的名称,这个名称必须与volumes列表中定义的某个卷的名称相匹配。
mountPath: /config/ #卷在容器内的挂载路径。这意味着ConfigMap dict中的数据将被挂载到容器内的/config/目录下。
volumes: #这是一个列表,定义了Pod中可以使用的卷
- name: config-volume #定义了卷的名称,这个名称将在volumeMounts中被引用
configMap: #表示这个卷是由一个ConfigMap支持的。
name: dict #指定了ConfigMap的名称为dict。这意味着Kubernetes将查找名为dict的ConfigMap,并将其内容挂载到Pod中容器的指定路径下。
restartPolicy: Never
[root@k8s-master configmap]# kubectl apply -f pod4.yml
pod/testpod created
[root@k8s-master configmap]# kubectl describe pods testpod
[root@k8s-master configmap]# kubectl exec -it pods/testpod -- /bin/sh
/ # ls
bin dev home lib64 media opt root sbin tmp var
config etc lib linuxrc mnt proc run sys usr
/ # cd config/
/config # ls
db_host db_port
/config # cat db_host
172.25.254.100
/config # cat db_port
3306
我们发现:cm
中dict
的db_host和db_port
两个键
变成了pod中容器里
的文件名
,值
变成了文件内容
#回收
[root@k8s-master configmap]# kubectl delete -f pod4.yml
pod "testpod" deleted
1.5.3利用configmap
填充pod中容器的配置文件
- 自建
nginx.conf
配置文件
[root@k8s-master configmap]# vim nginx.conf
[root@k8s-master configmap]# cat nginx.conf
server {
listen 8000;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
- 利用
nginx.conf
模板生成cm资源
- 使用参数
--from-file
#创建名为nginx-conf的cm资源
[root@k8s-master configmap]# kubectl create configmap nginx-conf --from-file nginx.conf
configmap/nginx-conf created
#我们发现文件名为键,文件内容为值
[root@k8s-master configmap]# kubectl describe cm nginx-conf
Name: nginx-conf
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx.conf:
----
server {
listen 8000;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
BinaryData
====
Events: <none>
#创建名为deployment的deployment控制器,控制器中运行一个pod,pod中运行一个myapp的镜像
[root@k8s-master configmap]# kubectl create deployment deployment1 --image myapp:v1 --dry-run=client -o yaml > deployment1.yml
[root@k8s-master configmap]# vim deployment1.yml
[root@k8s-master configmap]# cat deployment1.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: deployment1
name: deployment1
spec:
replicas: 1
selector:
matchLabels:
app: deployment1
template:
metadata:
labels:
app: deployment1
spec:
containers:
- image: myapp:v1
name: myappv1
volumeMounts: #这是一个列表,定义了Pod中容器要挂载的卷。
- name: config-volume #指定了要挂载的卷的名称,这个名称必须与volumes列表中定义的某个卷的名称相匹配。
mountPath: /etc/nginx/conf.d/ #卷在容器内的挂载路径。这意味着ConfigMap nginx-conf中的数据将被挂载到容器内的/etc/nginx/conf.d/目录下
volumes: #这是一个列表,定义了Pod中可以使用的卷
- name: config-volume #定义了卷的名称,这个名称将在volumeMounts中被引用
configMap: #表示这个卷是由一个ConfigMap支持的。
name: nginx-conf #指定了ConfigMap的名称为nginx-conf。这意味着Kubernetes将查找名为nginx-conf的ConfigMap资源,并将其内容挂载到Pod中容器的指定路径下。
[root@k8s-master configmap]# kubectl apply -f deployment1.yml
deployment.apps/deployment1 created
[root@k8s-master configmap]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment1-5cc776ddcb-lxd55 1/1 Running 0 21s 10.244.2.24 k8s-node2.org <none> <none>
因为我们通过cm
改了nginx.conf
中的端口
,现在端口监听
为8000
#访问80端口失败
[root@k8s-master configmap]# curl 10.244.2.24
curl: (7) Failed to connect to 10.244.2.24 port 80: 拒绝连接
#访问8000端口成功
[root@k8s-master configmap]# curl 10.244.2.24:8000
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
[root@k8s-master configmap]# kubectl edit cm nginx-conf
#退出编辑自动保存
[root@k8s-master configmap]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment1-5cc776ddcb-lxd55 1/1 Running 0 9m29s 10.244.2.24 k8s-node2.org <none> <none>
#查看pod容器中的配置文件,发现监听的端口确实修改了
[root@k8s-master configmap]# kubectl exec pods/deployment1-5cc776ddcb-lxd55 -- cat /etc/nginx/conf.d/nginx.conf
server {
listen 80;
server_name _;
root /usr/share/nginx/html;
index index.html;
}
#但是还是要重启pod中的容器才能得到应用
[root@k8s-master configmap]# curl 10.244.2.24
curl: (7) Failed to connect to 10.244.2.24 port 80: 拒绝连接
#删掉这个pod,deployment控制器会再起一个
[root@k8s-master configmap]# kubectl delete pods deployment1-5cc776ddcb-lxd55
pod "deployment1-5cc776ddcb-lxd55" deleted
[root@k8s-master configmap]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment1-5cc776ddcb-hbhx2 1/1 Running 0 20s 10.244.2.25 k8s-node2.org <none> <none>
#重新起一个pod后,修改的配置才得到了应用
[root@k8s-master configmap]# curl 10.244.2.25:80
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>