CKA认证模块②-K8S企业运维和落地实战-2

CKA认证模块②-K8S企业运维和落地实战-2

K8S常见的存储方案及具体应用场景分析

k8s存储-empty

emptyDir类型的Volume是在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

[root@k8s-master01 ~]# mkdir storage
[root@k8s-master01 ~]# cd storage/
# 创建工作目录[root@k8s-master01 storage]# kubectl explain pod.spec.volumes.
...
# 查看支持哪些存储卷[root@k8s-master01 storage]# cat emptydir.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-empty
spec:containers:- name: container-emptyimage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: cache-volumemountPath: /cachevolumes:- name: cache-volumeemptyDir: {}
[root@k8s-master01 storage]# kubectl apply -f emptydir.yaml 
pod/pod-empty created
[root@k8s-master01 storage]# kubectl get pods -owide
NAME        READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
pod-empty   1/1     Running   0          4s    10.244.58.253   k8s-node02   <none>           <none>
# 创建pod
[root@k8s-master01 storage]# kubectl exec -it pod-empty -c container-empty -- /bin/bash
root@pod-empty:/# cd /cache/
root@pod-empty:/cache# touch 123
root@pod-empty:/cache# touch aa
root@pod-empty:/cache# ls
123  aa
# 创建empty挂载文件夹下文件
root@pod-empty:/cache# exit
exit
[root@k8s-master01 storage]# kubectl get pods -oyaml |grep uiduid: 8ce8fecc-dc86-4c92-8876-69ac034b6972
[root@k8s-master01 storage]# kubectl get pods -owide
NAME        READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
pod-empty   1/1     Running   0          2m43s   10.244.58.253   k8s-node02   <none>           <none>
# 查看pod的uid,并查看调度节点[root@k8s-node02 ~]# yum -y install tree
[root@k8s-node02 ~]# tree /var/lib/kubelet/pods/8ce8fecc-dc86-4c92-8876-69ac034b6972
...
[root@k8s-node02 ~]# cd /var/lib/kubelet/pods/8ce8fecc-dc86-4c92-8876-69ac034b6972/
[root@k8s-node02 8ce8fecc-dc86-4c92-8876-69ac034b6972]# cd volumes/kubernetes.io~empty-dir/cache-volume/
[root@k8s-node02 cache-volume]# ls
123  aa
[root@k8s-node02 cache-volume]# pwd
/var/lib/kubelet/pods/8ce8fecc-dc86-4c92-8876-69ac034b6972/volumes/kubernetes.io~empty-dir/cache-volume
# 已经保存到临时文件夹下[root@k8s-master01 storage]# kubectl delete pod pod-empty 
pod "pod-empty" deleted
# 删除pod[root@k8s-node02 cache-volume]# ls
[root@k8s-node02 cache-volume]# cd ..
cd: error retrieving current directory: getcwd: cannot access parent directories: No such file or directory
# 因为整个容器目录都被删除,emptyDir目录自然也被删除,所以不建议使用
k8s存储-hostPath

hostpath存储卷缺点:

单节点

pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失

[root@k8s-node01 images]# ctr -n k8s.io images import tomcat.tar.gz.0
[root@k8s-node02 images]# ctr -n k8s.io images import tomcat.tar.gz.0
# 因为之前上传过同名镜像包,名字不能一样后面加了.0[root@k8s-master01 storage]# kubectl explain pod.spec.volumes.hostPath.type
# 查看支持哪些类型 https://kubernetes.io/docs/concepts/storage/volumes#hostpath

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

[root@k8s-master01 storage]# kubectl explain pod.spec |grep -i nodename
# 查看帮助[root@k8s-master01 storage]# cat hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:name: pod-hostpathnamespace: default
spec:nodeName: k8s-node01containers:- name: test-nginximage: nginximagePullPolicy: IfNotPresentvolumeMounts: - name: test-volumemountPath: /test-nginx- name: test-tomcatimage: tomcatimagePullPolicy: IfNotPresentvolumeMounts: - name: test-volumemountPath: /test-tomcatvolumes:- name: test-volumehostPath: path: /data1type: DirectoryOrCreate  
[root@k8s-master01 storage]# kubectl apply -f hostpath.yaml 
pod/pod-hostpath created
[root@k8s-master01 storage]# kubectl exec -it pod-hostpath -c test-nginx -- /bin/bash
root@pod-hostpath:/# cd test-nginx/
root@pod-hostpath:/test-nginx# touch nginx
root@pod-hostpath:/test-nginx# ls
nginx
root@pod-hostpath:/test-nginx# exit
exit
[root@k8s-master01 storage]# kubectl exec -it pod-hostpath -c test-tomcat -- /bin/bash
root@pod-hostpath:/usr/local/tomcat# cd /test-tomcat/
root@pod-hostpath:/test-tomcat# touch tomcat
root@pod-hostpath:/test-tomcat# ls
nginx  tomcat
root@pod-hostpath:/test-tomcat# exit
exit
[root@k8s-node01 ~]# ls /data1/
nginx  tomcat
# 测试是否为同一卷[root@k8s-master01 storage]# kubectl delete -f hostpath.yaml 
pod "pod-hostpath" deleted
# 删除pod[root@k8s-node01 ~]# ll /data1/
total 0
-rw-r--r-- 1 root root 0 Jul  3 16:30 nginx
-rw-r--r-- 1 root root 0 Jul  3 16:31 tomcat
# 数据仍然存在
k8s存储-NFS
注意: NFS服务器配置白名单是node节点网段而不是pod网段

node节点网段,例如我的环境应配置: 192.168.1.0/24

yum -y install nfs-utils
systemctl enable --now nfs
# 所有节点安装nfs[root@k8s-master01 storage]# mkdir -pv /data/volume
mkdir: created directory ‘/data’
mkdir: created directory ‘/data/volume’
# v参数是展示创建了哪些文件夹
[root@k8s-master01 storage]# cat /etc/exports
/data/volume *(rw,no_root_squash)
[root@k8s-master01 storage]# systemctl restart nfs
[root@k8s-master01 storage]# showmount -e localhost
Export list for localhost:
/data/volume *
# 配置nfs服务
[root@k8s-node01 ~]# mount -t nfs k8s-master01:/data/volume /mnt
[root@k8s-node01 ~]# df -Th |tail -n1
k8s-master01:/data/volume nfs4       38G   11G   27G  29% /mnt
[root@k8s-node01 ~]# umount /mnt 
# 测试nfs服务[root@k8s-master01 storage]# cat nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: test-nfs-volumenamespace: default
spec:replicas: 3selector: matchLabels:storage: nfstemplate:metadata:labels:storage: nfsspec:containers:- name: test-nfsimage: xianchao/nginx:v1imagePullPolicy: IfNotPresentports:- containerPort: 80protocol: TCPvolumeMounts:- name: nfs-volumesmountPath: /usr/share/nginx/htmlvolumes: - name: nfs-volumesnfs:server: 192.168.1.181# 注意nfs服务器的ip一定不能写错path: /data/volume
[root@k8s-master01 storage]# kubectl apply -f nfs.yaml 
deployment.apps/test-nfs-volume created
# 创建deployment
[root@k8s-master01 storage]# echo nfs-test > /data/volume/index.html
[root@k8s-master01 storage]# kubectl get pods -owide
NAME                               READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
test-nfs-volume-6656574b86-66m2h   1/1     Running   0          5m37s   10.244.85.233   k8s-node01   <none>           <none>
test-nfs-volume-6656574b86-6nxgw   1/1     Running   0          5m37s   10.244.85.232   k8s-node01   <none>           <none>
test-nfs-volume-6656574b86-cvqmr   1/1     Running   0          5m37s   10.244.58.255   k8s-node02   <none>           <none>
[root@k8s-master01 storage]# curl 10.244.85.232
nfs-test
# 测试nfs
[root@k8s-master01 storage]# kubectl exec -it test-nfs-volume-6656574b86-cvqmr 
-- /bin/bash
root@test-nfs-volume-6656574b86-cvqmr:/# ls /usr/share/nginx/html/
index.html
root@test-nfs-volume-6656574b86-cvqmr:/# cat /usr/share/nginx/html/index.html 
nfs-test
root@test-nfs-volume-6656574b86-cvqmr:/# exit 
exit
# 进入pod测试[root@k8s-master01 storage]# kubectl delete -f nfs.yaml 
deployment.apps "test-nfs-volume" deleted
# 删除deployment[root@k8s-master01 storage]# ls /data/volume/
index.html
[root@k8s-master01 storage]# cat /data/volume/index.html 
nfs-test
# 数据仍然存在
k8s存储-PVC
[root@k8s-master01 storage]# mkdir /data/volume-test/v{1..10} -p
[root@k8s-master01 storage]# cat /etc/exports
/data/volume *(rw,no_root_squash)
/data/volume-test/v1 *(rw,no_root_squash)
/data/volume-test/v2 *(rw,no_root_squash)
/data/volume-test/v3 *(rw,no_root_squash)
/data/volume-test/v4 *(rw,no_root_squash)
/data/volume-test/v5 *(rw,no_root_squash)
/data/volume-test/v6 *(rw,no_root_squash)
/data/volume-test/v7 *(rw,no_root_squash)
/data/volume-test/v8 *(rw,no_root_squash)
/data/volume-test/v9 *(rw,no_root_squash)
/data/volume-test/v10 *(rw,no_root_squash)
[root@k8s-master01 storage]# exportfs -arv
# 生效配置[root@k8s-master01 storage]# cat pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:name: v1labels:app: v1
spec:nfs:server: 192.168.1.181path: /data/volume-test/v1accessModes: ["ReadWriteOnce"]capacity: storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: v2labels:app: v2
spec:nfs:server: 192.168.1.181path: /data/volume-test/v2accessModes: ["ReadOnlyMany"]capacity: storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:name: v3labels:app: v3
spec:nfs:server: 192.168.1.181path: /data/volume-test/v3accessModes: ["ReadWriteMany"]capacity: storage: 3Gi

https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-mod

访问模式有:

  • ReadWriteOnce

    卷可以被一个节点以读写方式挂载。 ReadWriteOnce 访问模式也允许运行在同一节点上的多个 Pod 访问卷。

  • ReadOnlyMany

    卷可以被多个节点以只读方式挂载。

  • ReadWriteMany

    卷可以被多个节点以读写方式挂载。

  • ReadWriteOncePod

    特性状态: Kubernetes v1.27 [beta]卷可以被单个 Pod 以读写方式挂载。 如果你想确保整个集群中只有一个 Pod 可以读取或写入该 PVC, 请使用 ReadWriteOncePod 访问模式。这只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本。

[root@k8s-master01 storage]# kubectl apply -f pv.yaml 
persistentvolume/v1 created
persistentvolume/v2 created
persistentvolume/v3 created
[root@k8s-master01 storage]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
v1     1Gi        RWO            Retain           Available                                   22s
v2     2Gi        ROX            Retain           Available                                   22s
v3     3Gi        RWX            Retain           Available                                   22s
[root@k8s-master01 storage]# cat pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-v1
spec:accessModes: ["ReadWriteOnce"]selector:matchLabels: app: v1resources:requests: storage: 1Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-v2
spec:accessModes: ["ReadOnlyMany"]selector:matchLabels: app: v2resources:requests: storage: 2Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-v3
spec:accessModes: ["ReadWriteMany"]selector:matchLabels: app: v3resources:requests: storage: 3Gi
[root@k8s-master01 storage]# kubectl apply -f pvc.yaml 
persistentvolumeclaim/pvc-v1 created
persistentvolumeclaim/pvc-v2 created
persistentvolumeclaim/pvc-v3 created
[root@k8s-master01 storage]# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc-v1   Bound    v1       1Gi        RWO                           4s
pvc-v2   Bound    v2       2Gi        ROX                           4s
pvc-v3   Bound    v3       3Gi        RWX                           4s
# Bound状态就说明pvc已经和pv绑定

RWO: ReadWriteOnce

ROX: ReadOnlyMany

RWX: ReadWriteMany

[root@k8s-master01 storage]# cat deploy_pvc.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: pvc-test
spec:replicas: 3selector:matchLabels:storage: pvctemplate:metadata:labels:storage: pvcspec:containers:- name: test-pvcimage: xianchao/nginx:v1imagePullPolicy: IfNotPresentports:- containerPort: 80protocol: TCPvolumeMounts: - name: nginx-htmlmountPath: /usr/share/nginx/htmlvolumes:- name: nginx-htmlpersistentVolumeClaim: claimName: pvc-v1
[root@k8s-master01 storage]# kubectl apply -f deploy_pvc.yaml 
deployment.apps/pvc-test created
# 创建deployment使用pvc
[root@k8s-master01 storage]# echo pvc-test > /data/volume-test/v1/index.html
[root@k8s-master01 storage]# kubectl get pods -owide
NAME                        READY   STATUS    RESTARTS   AGE   IP              NODE         NOMINATED NODE   READINESS GATES
pvc-test-66c48b4c9d-dljv7   1/1     Running   0          46s   10.244.85.236   k8s-node01   <none>           <none>
pvc-test-66c48b4c9d-fcttc   1/1     Running   0          46s   10.244.58.197   k8s-node02   <none>           <none>
pvc-test-66c48b4c9d-kcjvr   1/1     Running   0          46s   10.244.58.198   k8s-node02   <none>           <none>
[root@k8s-master01 storage]# curl 10.244.58.198
pvc-test
# 测试访问成功

**注:**使用pvc和pv的注意事项

1、我们每次创建pvc的时候,需要事先有划分好的pv,这样可能不方便,那么可以在创建pvc的时候直接动态创建一个pv这个存储类,pv事先是不存在的

2、pvc和pv绑定,如果使用默认的回收策略retain,那么删除pvc之后,pv会处于released状态,我们想要继续使用这个pv,需要手动删除pv,kubectl delete pv pv_name,删除pv,不会删除pv里的数据,当我们重新创建pvc时还会和这个最匹配的pv绑定,数据还是原来数据,不会丢失。

经过测试,如果回收策略是Delete,删除pv,pv后端存储的数据也不会被删除

**回收策略:**persistentVolumeReclaimPolicy字段

删除pvc的步骤:

需要先删除使用pvc的pod

再删除pvc

[root@k8s-master01 storage]# kubectl delete -f deploy_pvc.yaml 
deployment.apps "pvc-test" deleted
[root@k8s-master01 storage]# kubectl delete -f pvc.yaml 
persistentvolumeclaim "pvc-v1" deleted
persistentvolumeclaim "pvc-v2" deleted
persistentvolumeclaim "pvc-v3" deleted
[root@k8s-master01 storage]# kubectl delete -f pv.yaml 
persistentvolume "v1" deleted
persistentvolume "v2" deleted
persistentvolume "v3" deleted
演示pv用Delete回收策略:
[root@k8s-master01 storage]# cat pv-1.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:name: v4labels:app: v4
spec:nfs:server: 192.168.1.181path: /data/volume-test/v4accessModes: ["ReadWriteOnce"]capacity: storage: 1GipersistentVolumeReclaimPolicy: Delete
[root@k8s-master01 storage]# kubectl apply -f pv-1.yaml 
persistentvolume/v4 created
# 创建pv
[root@k8s-master01 storage]# cat pvc-1.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: pvc-v4
spec:accessModes: ["ReadWriteOnce"]selector:matchLabels: app: v4resources:requests: storage: 1Gi
[root@k8s-master01 storage]# kubectl apply -f pvc-1.yaml 
persistentvolumeclaim/pvc-v4 created
# 创建pvc
[root@k8s-master01 storage]# cat deploy_pvc-1.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:name: pvc-test-1
spec:replicas: 3selector:matchLabels:storage: pvc-1template:metadata:labels:storage: pvc-1spec:containers:- name: test-pvcimage: xianchao/nginx:v1imagePullPolicy: IfNotPresentports:- containerPort: 80protocol: TCPvolumeMounts: - name: nginx-htmlmountPath: /usr/share/nginx/htmlvolumes:- name: nginx-htmlpersistentVolumeClaim: claimName: pvc-v4
[root@k8s-master01 storage]# kubectl apply -f deploy_pvc-1.yaml 
deployment.apps/pvc-test-1 created
# 创建deployment使用pvc
[root@k8s-master01 storage]# kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
pvc-test-1-58fc869c7c-fgl4r   1/1     Running   0          6s
pvc-test-1-58fc869c7c-h5rxb   1/1     Running   0          6s
pvc-test-1-58fc869c7c-nr7cv   1/1     Running   0          6s
[root@k8s-master01 storage]# kubectl exec -it pvc-test-1-58fc869c7c-fgl4r -- /bin/bash
root@pvc-test-1-58fc869c7c-fgl4r:/# cd /usr/share/nginx/html/
root@pvc-test-1-58fc869c7c-fgl4r:/usr/share/nginx/html# echo ReclaimPolicy-Delete_test > index.html
root@pvc-test-1-58fc869c7c-fgl4r:/usr/share/nginx/html# touch 123
# 写入内容
root@pvc-test-1-58fc869c7c-fgl4r:/usr/share/nginx/html# ls
123  index.html
root@pvc-test-1-58fc869c7c-fgl4r:/usr/share/nginx/html# exit
exit
command terminated with exit code 127
# 退出容器
[root@k8s-master01 storage]# kubectl delete -f deploy_pvc-1.yaml 
deployment.apps "pvc-test-1" deleted
[root@k8s-master01 storage]# kubectl delete -f pvc-1.yaml 
persistentvolumeclaim "pvc-v4" deleted
[root@k8s-master01 storage]# kubectl delete -f pv-1.yaml 
persistentvolume "v4" deleted
# 删除deployment,pvc以及pv
[root@k8s-master01 storage]# kubectl get pv
No resources found
[root@k8s-master01 storage]# ls /data/volume-test/v4/
123  index.html
# 可以看到,内容并没有被删除,所以Delete不是像官网说的一样会删除,可能是暂时不支持NFS

Storageclass存储类动态生成存储

存储类动态生成pv
[root@k8s-node01 images]# ctr -n k8s.io images import nfs-subdir-external-provisioner.tar.gz
[root@k8s-node02 images]# ctr -n k8s.io images import nfs-subdir-external-provisioner.tar.gz 
# 工作节点导入镜像[root@k8s-master01 storageclass]# mkdir /data/nfs_pro -p
[root@k8s-master01 storageclass]# cat /etc/exports
/data/volume 192.168.1.0/24(rw,no_root_squash)
/data/volume-test/v1 *(rw,no_root_squash)
/data/volume-test/v2 *(rw,no_root_squash)
/data/volume-test/v3 *(rw,no_root_squash)
/data/volume-test/v4 *(rw,no_root_squash)
/data/volume-test/v5 *(rw,no_root_squash)
/data/volume-test/v6 *(rw,no_root_squash)
/data/volume-test/v7 *(rw,no_root_squash)
/data/volume-test/v8 *(rw,no_root_squash)
/data/volume-test/v9 *(rw,no_root_squash)
/data/volume-test/v10 *(rw,no_root_squash)
/data/nfs_pro *(rw,no_root_squash)
[root@k8s-master01 storageclass]# exportfs -arv
exporting 192.168.1.0/24:/data/volume
exporting *:/data/nfs_pro
exporting *:/data/volume-test/v10
exporting *:/data/volume-test/v9
exporting *:/data/volume-test/v8
exporting *:/data/volume-test/v7
exporting *:/data/volume-test/v6
exporting *:/data/volume-test/v5
exporting *:/data/volume-test/v4
exporting *:/data/volume-test/v3
exporting *:/data/volume-test/v2
exporting *:/data/volume-test/v1
# 配置nfs服务[root@k8s-master01 ~]# mkdir storageclass
[root@k8s-master01 ~]# cd storageclass/
# 创建工作目录[root@k8s-master01 storageclass]# cat serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:name: nfs-provisioner[root@k8s-master01 storageclass]# kubectl apply -f serviceaccount.yaml 
serviceaccount/nfs-provisioner created
# 创建sa
[root@k8s-master01 storageclass]# kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner
clusterrolebinding.rbac.authorization.k8s.io/nfs-provisioner-clusterrolebinding created
# 对sa授权[root@k8s-master01 storageclass]# cat nfs-deployment.yaml 
kind: Deployment
apiVersion: apps/v1
metadata:name: nfs-provisioner
spec:selector:matchLabels:app: nfs-provisionerreplicas: 1strategy:type: Recreatetemplate:metadata:labels:app: nfs-provisionerspec:serviceAccount: nfs-provisionercontainers:- name: nfs-provisionerimage: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0imagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-client-rootmountPath: /persistentvolumesenv:- name: PROVISIONER_NAMEvalue: example.com/nfs- name: NFS_SERVERvalue: 192.168.1.181- name: NFS_PATHvalue: /data/nfs_pro/volumes:- name: nfs-client-rootnfs:server: 192.168.1.181path: /data/nfs_pro/[root@k8s-master01 storageclass]# kubectl apply -f nfs-deployment.yaml 
deployment.apps/nfs-provisioner created
[root@k8s-master01 storageclass]# kubectl get pods
NAME                               READY   STATUS    RESTARTS   AGE
nfs-provisioner-747db885fd-phwm2   1/1     Running   0          60s
# 安装nfs-provisioner程序[root@k8s-master01 storageclass]# cat nfs-storageclass.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:name: nfs
provisioner: example.com/nfs
# 注意provisioner的值一定要跟安装nfs-provisioner时候的PROVISIONER_NAME一致
[root@k8s-master01 storageclass]# kubectl apply -f nfs-storageclass.yaml 
storageclass.storage.k8s.io/nfs created
[root@k8s-master01 storageclass]# kubectl get sc
NAME   PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs    example.com/nfs   Delete          Immediate           false                  16s
# 创建storageclass,动态供给pv[root@k8s-master01 storageclass]# cat claim.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:name: test-claim1
spec:accessModes:  ["ReadWriteMany"]resources:requests:storage: 1GistorageClassName:  nfs[root@k8s-master01 storageclass]# kubectl apply -f claim.yaml 
persistentvolumeclaim/test-claim1 created
# 创建pvc
[root@k8s-master01 storageclass]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim1   Bound    pvc-b334c653-bb8b-4e48-8aa1-469f8ea90fb3   1Gi        RWX            nfs            49s
# 可以看到pvc已经成功创建了

步骤总结:

1、供应商:创建一个nfs provisioner

2、创建storageclass,storageclass指定刚才创建的供应商

3、创建pvc,这个pvc指定storageclass

[root@k8s-master01 storageclass]# cat read-pod.yaml 
kind: Pod
apiVersion: v1
metadata:name: read-pod
spec:containers:- name: read-podimage: nginximagePullPolicy: IfNotPresentvolumeMounts:- name: nfs-pvcmountPath: /usr/share/nginx/htmlrestartPolicy: "Never"volumes:- name: nfs-pvcpersistentVolumeClaim:claimName: test-claim1[root@k8s-master01 storageclass]# kubectl apply -f read-pod.yaml 
pod/read-pod created
# 创建pod,挂载storageclass动态生成的pvc: test-claim1
[root@k8s-master01 storageclass]# kubectl get pods | grep read
read-pod                           1/1     Running   0          88s
# 可以看到pod已经建立成功
[root@k8s-master01 storageclass]# echo nfs-provisioner > /data/nfs_pro/default-test-claim1-pvc-b334c653-bb8b-4e48-8aa1-469f8ea90fb3/index.html
# 写入文件测试
[root@k8s-master01 storageclass]# kubectl get pods -owide
NAME                               READY   STATUS    RESTARTS   AGE     IP              NODE         NOMINATED NODE   READINESS GATES
nfs-provisioner-747db885fd-phwm2   1/1     Running   0          8m20s   10.244.58.201   k8s-node02   <none>           <none>
read-pod                           1/1     Running   0          3m      10.244.85.238   k8s-node01   <none>           <none>
[root@k8s-master01 storageclass]# curl 10.244.85.238
nfs-provisioner
# 访问成功

K8S控制器Statefulset入门到企业实战应用

StatefulSet资源-YAML编写技巧

StatefulSet是为了管理有状态服务的问题而设计的

扩展:

有状态服务?

**StatefulSet是有状态的集合,管理有状态的服务,**它所管理的Pod的名称不能随意变化。数据持久化的目录也是不一样,每一个Pod都有自己独有的数据持久化存储目录。比如MySQL主从、redis集群等。

无状态服务?

**RC、Deployment、DaemonSet都是管理无状态的服务,**它们所管理的Pod的IP、名字,启停顺序等都是随机的。个体对整体无影响,所有pod都是共用一个数据卷的,部署的tomcat就是无状态的服务,tomcat被删除,在启动一个新的tomcat,加入到集群即可,跟tomcat的名字无关。

[root@k8s-master01 ~]# kubectl explain statefulset.
# 查看帮助[root@k8s-master01 ~]# mkdir statefulset
[root@k8s-master01 ~]# cd statefulset/
# 创建工作目录[root@k8s-master01 statefulset]# cat statefulset.yaml
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webclusterIP: Noneselector:app: nginx  
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:replicas: 2selector:matchLabels:app: nginx    serviceName: nginxtemplate: metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- name: webcontainerPort: 80volumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates: - metadata:name: wwwspec:accessModes: ["ReadWriteOnce"]storageClassName: nfsresources:requests:storage: 1Gi
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx created
statefulset.apps/web created
# 创建statefulset以及对应的service[root@k8s-master01 statefulset]# kubectl get pods
NAME                               READY   STATUS    RESTARTS       AGE
nfs-provisioner-747db885fd-phwm2   1/1     Running   4 (105m ago)   18h
web-0                              1/1     Running   0              39s
web-1                              1/1     Running   0              38s
[root@k8s-master01 statefulset]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim1   Bound    pvc-b334c653-bb8b-4e48-8aa1-469f8ea90fb3   1Gi        RWX            nfs            18h
www-web-0     Bound    pvc-54ce83ca-698d-4c32-a0a2-1350f8717941   1Gi        RWO            nfs            88s
www-web-1     Bound    pvc-35c5949e-0227-4d8e-bdbb-02c1ba9ce488   1Gi        RWO            nfs            85s
[root@k8s-master01 statefulset]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pvc-35c5949e-0227-4d8e-bdbb-02c1ba9ce488   1Gi        RWO            Delete           Bound    default/www-web-1     nfs                     88s
pvc-54ce83ca-698d-4c32-a0a2-1350f8717941   1Gi        RWO            Delete           Bound    default/www-web-0     nfs                     91s
pvc-b334c653-bb8b-4e48-8aa1-469f8ea90fb3   1Gi        RWX            Delete           Bound    default/test-claim1   nfs                     18h
# 可以看到已经自动帮你创建了pv以及pvc
[root@k8s-master01 statefulset]# kubectl get pods -owide
NAME                               READY   STATUS    RESTARTS       AGE    IP              NODE         NOMINATED NODE   READINESS GATES
nfs-provisioner-747db885fd-phwm2   1/1     Running   4 (109m ago)   18h    10.244.58.203   k8s-node02   <none>           <none>
web-0                              1/1     Running   0              4m1s   10.244.58.204   k8s-node02   <none>           <none>
web-1                              1/1     Running   0              4m     10.244.85.242   k8s-node01   <none>           <none>
[root@k8s-master01 statefulset]# echo web-test-0 > /data/nfs_pro/default-www-web-0-pvc-54ce83ca-698d-4c32-a0a2-1350f8717941/index.html
[root@k8s-master01 statefulset]# echo web-test-1 > /data/nfs_pro/default-www-web-1-pvc-35c5949e-0227-4d8e-bdbb-02c1ba9ce488/index.html
[root@k8s-master01 statefulset]# curl 10.244.58.204
web-test-0
[root@k8s-master01 statefulset]# curl 10.244.85.242
web-test-1
# 测试成功,pod分别使用不同卷[root@k8s-master01 statefulset]# kubectl run busybox --image docker.io/library/busybox:1.28  --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName:      nginx
Address 1: 10.244.58.204 web-0.nginx.default.svc.cluster.local
Address 2: 10.244.85.242 web-1.nginx.default.svc.cluster.local
/ # exit
pod "busybox" deleted
# 因为ClusterIP设置为了None,所以解析出来是两个pod的地址[root@k8s-master01 statefulset]# kubectl delete -f statefulset.yaml 
service "nginx" deleted
statefulset.apps "web" deleted
# 删除service以及statefulset[root@k8s-master01 statefulset]# cat statefulset.yaml 
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webselector:app: nginx  
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:replicas: 2selector:matchLabels:app: nginx    serviceName: nginxtemplate: metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentports:- name: webcontainerPort: 80volumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates: - metadata:name: wwwspec:accessModes: ["ReadWriteOnce"]storageClassName: nfsresources:requests:storage: 1Gi
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx created
statefulset.apps/web created
# 删除clusterIP: None,也就是给一个ip给service看看会怎么样
[root@k8s-master01 statefulset]# kubectl run busybox --image docker.io/library/busybox:1.28  --image-pull-policy=IfNotPresent --restart=Never --rm -it busybox -- sh
If you don't see a command prompt, try pressing enter.
/ # nslookup nginx
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.localName:      nginx
Address 1: 10.96.165.5 nginx.default.svc.cluster.local
/ # exit
pod "busybox" deleted
[root@k8s-master01 statefulset]# kubectl get svc -owide -l app=nginx
NAME    TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)   AGE   SELECTOR
nginx   ClusterIP   10.96.165.5   <none>        80/TCP    48s   app=nginx
# 可以看到解析出来是service的ip
StatefulSet总结:

1、Statefulset管理的pod,pod名字是有序的,由statefulset的名字-0、1、2这种格式组成

2、创建statefulset资源的时候,必须事先创建好一个service,如果创建的service没有ip,那对这个service做dns解析,会找到它所关联的pod ip,如果创建的service有ip,那对这个service做dns解析,会解析到service本身ip。

3、statefulset管理的pod,删除pod,新创建的pod名字跟删除的pod名字是一样的

4、statefulset具有volumeclaimtemplate这个字段,这个是卷申请模板,会自动创建pv,pvc也会自动生成,跟pv进行绑定,那如果创建的statefulset使用了volumeclaimtemplate这个字段,那创建pod,数据目录是独享的

5、ststefulset创建的pod,是域名的(域名组成:pod-name.svc-name.svc-namespace.svc.cluster.local)

StatefulSet管理pod-扩缩容和更新
[root@k8s-master01 statefulset]# cat statefulset.yaml |grep replicas:replicas: 3
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx unchanged
statefulset.apps/web configured
[root@k8s-master01 statefulset]# kubectl get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          43m
web-1   1/1     Running   0          43m
web-2   0/1     Pending   0          0s
web-2   0/1     Pending   0          0s
web-2   0/1     Pending   0          1s
web-2   0/1     ContainerCreating   0          1s
web-2   0/1     ContainerCreating   0          1s
web-2   1/1     Running             0          2s
# 直接修改yaml文件实现pod扩容[root@k8s-master01 statefulset]# cat statefulset.yaml |grep replicas:replicas: 2
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx unchanged
statefulset.apps/web configured
[root@k8s-master01 statefulset]# kubectl get pods -w -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          44m
web-1   1/1     Running   0          44m
web-2   1/1     Running   0          5s
web-2   1/1     Terminating   0          13s
web-2   1/1     Terminating   0          13s
web-2   0/1     Terminating   0          14s
web-2   0/1     Terminating   0          14s
web-2   0/1     Terminating   0          14s
^C[root@k8s-master01 statefulset]# kubectl get pods -l app=nginx
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          45m
web-1   1/1     Running   0          45m
# 实现pod缩容
更新
[root@k8s-master01 statefulset]# kubectl explain statefulset.spec.updateStrategy.
# 查看帮助[root@k8s-master01 statefulset]# cat statefulset.yaml 
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webselector:app: nginx  
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:replicas: 3updateStrategy:rollingUpdate: partition: 1# 意为只更新序号大于等于1的podmaxUnavailable: 0# 最多不可用pod数为0selector:matchLabels:app: nginx    serviceName: nginxtemplate: metadata:labels:app: nginxspec:containers:- name: nginximage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresentports:- name: webcontainerPort: 80volumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates: - metadata:name: wwwspec:accessModes: ["ReadWriteOnce"]storageClassName: nfsresources:requests:storage: 1Gi
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx unchanged
statefulset.apps/web configured
[root@k8s-master01 statefulset]# kubectl get pods -l app=nginx -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          17s
web-1   1/1     Running   0          15s
web-2   1/1     Running   0          14s
web-2   1/1     Terminating   0          24s
web-2   1/1     Terminating   0          24s
web-2   0/1     Terminating   0          25s
web-2   0/1     Terminating   0          25s
web-2   0/1     Terminating   0          25s
web-2   0/1     Pending       0          0s
web-2   0/1     Pending       0          0s
web-2   0/1     ContainerCreating   0          0s
web-2   0/1     ContainerCreating   0          0s
web-2   1/1     Running             0          1s
web-1   1/1     Terminating         0          27s
web-1   0/1     Terminating         0          28s
web-1   0/1     Terminating         0          28s
web-1   0/1     Terminating         0          28s
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s
web-1   0/1     ContainerCreating   0          0s
web-1   0/1     ContainerCreating   0          0s
web-1   1/1     Running             0          2s
# 先从大的开始删(只测过一次,不确定)

需要注意rollingUpdate下的partition字段,整数类型,
如果是1,就代表只更新序号大于等于1的pod

测试OnDelete类型
[root@k8s-master01 statefulset]# cat statefulset.yaml 
apiVersion: v1
kind: Service
metadata:name: nginxlabels:app: nginx
spec:ports:- port: 80name: webselector:app: nginx  
---
apiVersion: apps/v1
kind: StatefulSet
metadata:name: web
spec:replicas: 3updateStrategy:type: OnDeleteselector:matchLabels:app: nginx    serviceName: nginxtemplate: metadata:labels:app: nginxspec:containers:- name: nginximage: ikubernetes/myapp:v2imagePullPolicy: IfNotPresentports:- name: webcontainerPort: 80volumeMounts:- name: wwwmountPath: /usr/share/nginx/htmlvolumeClaimTemplates: - metadata:name: wwwspec:accessModes: ["ReadWriteOnce"]storageClassName: nfsresources:requests:storage: 1Gi
[root@k8s-master01 statefulset]# kubectl apply -f statefulset.yaml 
service/nginx unchanged
statefulset.apps/web configured
[root@k8s-master01 statefulset]# kubectl get pods -l app=nginx -w
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          2m30s
web-1   1/1     Running   0          2m
web-2   1/1     Running   0          2m2s
# 没有更新
[root@k8s-master01 statefulset]# kubectl delete pod web-0
pod "web-0" deleted
[root@k8s-master01 statefulset]# kubectl delete pod web-1
pod "web-1" deleted
[root@k8s-master01 statefulset]# kubectl delete pod web-2
pod "web-2" deleted
[root@k8s-master01 statefulset]# kubectl get pods -l app=nginx 
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          10s
web-1   1/1     Running   0          8s
web-2   1/1     Running   0          5s
# OnDelete类型必须要手动删除pod才会更新[root@k8s-master01 statefulset]# kubectl delete -f statefulset.yaml 
service "nginx" deleted
statefulset.apps "web" deleted
# 清除环境

K8S控制器DaemonSet入门到企业实战应用

Daemonset控制器基本介绍

DaemonSet概述

DaemonSet控制器能够确保k8s集群所有的节点都运行一个相同的pod副本,当向k8s集群中增加node节点时,这个node节点也会自动创建一个pod副本,当node节点从集群移除,这些pod也会自动删除;删除Daemonset也会删除它们创建的pod

DaemonSet工作原理:如何管理Pod?

daemonset的控制器会监听kuberntes的daemonset对象、pod对象、node对象,这些被监听的对象之变动,就会触发syncLoop循环让kubernetes集群朝着daemonset对象描述的状态进行演进。

Daemonset具有实战应用场景分析

在集群的每个节点上运行存储,比如:glusterd 或 ceph。
在每个节点上运行日志收集组件,比如:flunentd 、 logstash、filebeat等。
在每个节点上运行监控组件,比如:Prometheus、 Node Exporter 、collectd等。

通过YAML文件创建Daemonset资源技巧
[root@k8s-master01 ~]# kubectl explain ds.
# 查看帮助
Daemonset实战: 部署收集日志组件
ctr -n k8s.io images import fluentd_2_5_1.tar.gz
# 所有节点导入镜像[root@k8s-master01 ~]# kubectl describe node k8s-master01 |grep -i taint
Taints:             node-role.kubernetes.io/control-plane:NoSchedule
# 查看master节点污点
[root@k8s-master01 ~]# mkdir daemonset
[root@k8s-master01 ~]# cd daemonset/
# 创建工作目录[root@k8s-master01 daemonset]# cat daemonset.yaml 
apiVersion: apps/v1
kind: DaemonSet
metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:k8s-app: fluentd-logging
spec:selector:matchLabels:name: fluentd-elasticsearchtemplate:metadata:labels:name: fluentd-elasticsearchspec:tolerations:- key: node-role.kubernetes.io/control-planeeffect: NoSchedulecontainers:- name: fluentd-elasticsearchimage: xianchao/fluentd:v2.5.1imagePullPolicy: IfNotPresentresources:requests:cpu: 100mmemory: 200Milimits:cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/logreadOnly: true- name: varlibcontainerdiocontainerdgrpcv1cricontainersmountPath: /var/lib/containerd/io.containerd.grpc.v1.cri/containersreadOnly: truevolumes:- name: varloghostPath:path: /var/log- name: varlibcontainerdiocontainerdgrpcv1cricontainershostPath:path: /var/lib/containerd/io.containerd.grpc.v1.cri/containers# 这个目录自己琢磨了一下,应该存放的是containerd的运行中容器状态
[root@k8s-master01 daemonset]# kubectl apply -f daemonset.yaml 
daemonset.apps/fluentd-elasticsearch created[root@k8s-master01 daemonset]# kubectl get ds -n kube-system -l k8s-app=fluentd-logging
NAME                    DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
fluentd-elasticsearch   3         3         3       3            3           <none>          94s
[root@k8s-master01 daemonset]# kubectl get pods -n kube-system -l name=fluentd-elasticsearch -owide
NAME                          READY   STATUS    RESTARTS   AGE     IP              NODE           NOMINATED NODE   READINESS GATES
fluentd-elasticsearch-482h6   1/1     Running   0          3m18s   10.244.85.255   k8s-node01     <none>           <none>
fluentd-elasticsearch-5hscz   1/1     Running   0          3m17s   10.244.58.217   k8s-node02     <none>           <none>
fluentd-elasticsearch-jjf8w   1/1     Running   0          3m17s   10.244.32.161   k8s-master01   <none>           <none>
# 可以看到已经部署成功
Daemonset管理Pod: 动态更新和回滚
[root@k8s-master01 statefulset]# kubectl explain ds.spec.updateStrategy.rollingUpdate.
# 查看帮助[root@k8s-master01 daemonset]# kubectl set image daemonsets fluentd-elasticsearch fluentd-elasticsearch=ikubernetes/filebeat:5.6.6-alpine -n kube-system
daemonset.apps/fluentd-elasticsearch image updated
# 这个镜像启动pod会有问题,主要是演示daemonset如何在命令行更新pod[root@k8s-master01 daemonset]# kubectl rollout history daemonset fluentd-elasticsearch -n kube-system
daemonset.apps/fluentd-elasticsearch 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>[root@k8s-master01 daemonset]# kubectl -n kube-system rollout undo daemonset fluentd-elasticsearch --to-revision=1
daemonset.apps/fluentd-elasticsearch rolled back
# 回滚
[root@k8s-master01 daemonset]# kubectl get pods -n kube-system -l name=fluentd-elasticsearch -owide
NAME                          READY   STATUS    RESTARTS   AGE   IP              NODE           NOMINATED NODE   READINESS GATES
fluentd-elasticsearch-cm55l   1/1     Running   0          16m   10.244.58.214   k8s-node02     <none>           <none>
fluentd-elasticsearch-lxmd8   1/1     Running   0          13s   10.244.32.164   k8s-master01   <none>           <none>
fluentd-elasticsearch-x5jrc   1/1     Running   0          16m   10.244.85.193   k8s-node01     <none>           <none>
# 状态正常[root@k8s-master01 daemonset]# kubectl delete -f daemonset.yaml 
daemonset.apps "fluentd-elasticsearch" deleted
# 清除环境

K8S配置管理中心ConfigMap实现微服务配置管理

配置管理中心Configmap基本介绍

Configmap是k8s中的资源对象,用于保存非机密性的配置的,数据可以用key/value键值对的形式保存,也可通过文件的形式保存。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. configmap是k8s的资源,相当于配置文件,可以有一个或者多个configmap;
  2. configmap可以做成volume,k8s pod启动后,通过volume挂载到容器内部指定目录;
  3. 容器内部应用按照原有方式读取特定目录上的配置文件;
  4. 在容器看来,配置文件就像是打包在容器内部特定目录,整个过程对应用没有任何侵入.
Configmap具体实战应用场景分析

集群跑着服务,像nginx,tomcat,mysql,突然资源不够用了,需要加机器,加机器的话又要更新配置,一个一个修改很麻烦,这时候就有configmap,可以把配置信息之类的存在configmap,通过volume卷挂载进去

Configmap注入方式有两种: 一种是将configmap作为存储卷,一种是将configmap通过env中configMapKeyRef注入到容器中

使用微服务架构的话,存在多个服务共用配置的情况,如果每个服务中心单独一份配置的话,那么更新配置很麻烦,使用configmap可以友好的进行配置共享

configmap局限性

configmap设计上不是用来保存大量数据的,保存在configmap中的数据不能超过1MiB,如果你需要保存超过此尺寸限制的数据,可以考虑挂载存储卷或者使用独立数据库或文件服务

创建configmap的第一种方案: 指定参数
[root@k8s-master01 ~]# kubectl create cm --help
[root@k8s-master01 ~]# kubectl create cm --help |grep '\-\-from\-literal=\[]' -A1--from-literal=[]:Specify a key and literal value to insert in configmap (i.e. mykey=somevalue)
# 查看帮助[root@k8s-master01 ~]# kubectl create cm tomcat-config --from-literal=tomcat-port=8080 --from-literal=tomcat-server_name=myapp.tomcat.com
configmap/tomcat-config created
[root@k8s-master01 ~]# kubectl describe cm tomcat-config
Name:         tomcat-config
Namespace:    default
Labels:       <none>
Annotations:  <none>Data
====
tomcat-server_name:
----
myapp.tomcat.com
tomcat-port:
----
8080BinaryData
====Events:  <none>
# 创建一个名为tomcat-config的cm
创建configmap的第二种方案: 指定文件
[root@k8s-master01 ~]# kubectl create cm www-nginx --from-file=www=./nginx.conf 
configmap/www-nginx created
[root@k8s-master01 ~]# kubectl describe cm www-nginx
Name:         www-nginx
Namespace:    default
Labels:       <none>
Annotations:  <none>Data
====
www:
# 这里是--from-file后面那个参数定义的
----
server {server_name www.nginx.com;listen 80;root /home/nginx/www/
}BinaryData
====Events:  <none>
[root@k8s-master01 ~]# kubectl describe cm www-nginx-1
Name:         www-nginx-1
Namespace:    default
Labels:       <none>
Annotations:  <none>Data
====
nginx.conf:
# 如果不写的话就是文件名
----
server {server_name www.nginx.com;listen 80;root /home/nginx/www/
}BinaryData
====Events:  <none>
创建configmap的第三种方案: 指定文件夹
[root@k8s-master01 ~]# mkdir configmap
[root@k8s-master01 ~]# cd configmap/
[root@k8s-master01 configmap]# mv ../nginx.conf ./
[root@k8s-master01 configmap]# mkdir test-a
[root@k8s-master01 configmap]# cd test-a/
[root@k8s-master01 test-a]# echo server-id=1 > my-server.cnf 
[root@k8s-master01 test-a]# echo server-id=2 > my-slave.cnf
[root@k8s-master01 test-a]# kubectl create cm mysql-config --from-file=/root/configmap/test-a/
configmap/mysql-config created
# 通过目录创建configmap
[root@k8s-master01 test-a]# kubectl describe cm mysql-config 
Name:         mysql-config
Namespace:    default
Labels:       <none>
Annotations:  <none>Data
====
my-server.cnf:
----
server-id=1my-slave.cnf:
----
server-id=2BinaryData
====Events:  <none>
通过YAML文件创建configmap技巧
[root@k8s-master01 test-a]# cd ..
[root@k8s-master01 configmap]# kubectl explain cm.
# 查看帮助[root@k8s-master01 configmap]# cat mysql-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:name: mysqllabels:app: mysql
data:master.cnf: |[mysqld]log-binlog_bin_trust_function_creators=1lower_case_table_names=1slave.cnf: |[mysqld]super-read-onlylog_bin_trust_function_creators=1
# 对于多行数据|必须要加,这代表多行字符串保留为单个字符串
[root@k8s-master01 configmap]# kubectl apply -f mysql-configmap.yaml 
configmap/mysql created
[root@k8s-master01 configmap]# kubectl describe cm mysql
Name:         mysql
Namespace:    default
Labels:       app=mysql
Annotations:  <none>Data
====
master.cnf:
----
[mysqld]
log-bin
log_bin_trust_function_creators=1
lower_case_table_names=1slave.cnf:
----
[mysqld]
super-read-only
log_bin_trust_function_creators=1BinaryData
====Events:  <none>
[root@k8s-master01 configmap]# kubectl delete -f mysql-configmap.yaml 
configmap "mysql" deleted
# 删除cm

注意:

多行数据必须要加 “|”

使用cm第一种方式: ConfigMapKeyRef
[root@k8s-master01 configmap]# cat mysql-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:name: mysqllabels:app: mysql
data:log: "1"lower: "1"
[root@k8s-master01 configmap]# kubectl apply -f mysql-configmap.yaml 
configmap/mysql created
# 创建cm[root@k8s-master01 configmap]# cat mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: mysql-pod
spec:containers:- name: mysqlimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 3600"]env:- name: log-bin# 指定环境变量名字valueFrom:configMapKeyRef:name: mysql# 指定cm的名字key: log# 指定cm中的key- name: lowervalueFrom:configMapKeyRef:name: mysqlkey: lower
[root@k8s-master01 configmap]# kubectl apply -f mysql-pod.yaml
pod/mysql-pod created[root@k8s-master01 configmap]# kubectl exec -it mysql-pod -c mysql -- /bin/sh
/ # printenv 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=mysql-pod
SHLVL=1
HOME=/root
NGINX_PORT_80_TCP=tcp://10.100.169.159:80
TERM=xterm
lower=1
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_SERVICE_HOST=10.100.169.159
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
NGINX_SERVICE_PORT=80
NGINX_PORT=tcp://10.100.169.159:80
log-bin=1
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
NGINX_SERVICE_PORT_WEB=80
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
NGINX_PORT_80_TCP_ADDR=10.100.169.159
NGINX_PORT_80_TCP_PORT=80
NGINX_PORT_80_TCP_PROTO=tcp
/ # exit
# 查看环境变量[root@k8s-master01 configmap]# kubectl delete -f mysql-pod.yaml 
pod "mysql-pod" deleted
# 清除环境
使用configmap第二种方式: envFrom
[root@k8s-master01 configmap]# cat mysql-pod-envfrom.yaml 
apiVersion: v1
kind: Pod
metadata:name: mysql-pod-envfrom
spec:containers:- name: mysqlimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 3600"]envFrom:- configMapRef: name: mysql
[root@k8s-master01 configmap]# kubectl apply -f mysql-pod-envfrom.yaml 
pod/mysql-pod-envfrom created
[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-envfrom -c mysql -- /bin/sh
/ # printenv 
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=mysql-pod-envfrom
SHLVL=1
HOME=/root
TERM=xterm
lower=1
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
log=1
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
/ # exit
# 查看环境变量[root@k8s-master01 configmap]# kubectl delete -f mysql-pod-envfrom.yaml 
pod "mysql-pod-envfrom" deleted
# 清除环境
使用configmap第三种方式: volume
[root@k8s-master01 configmap]# cat mysql-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:name: mysqllabels:app: mysql
data:log: "1"lower: "1"my.cnf: |[mysqld]Welcome=yuhang
[root@k8s-master01 configmap]# kubectl apply -f mysql-configmap.yaml 
configmap/mysql configured
# 更新cm[root@k8s-master01 configmap]# cat mysql-pod-volume.yaml 
apiVersion: v1
kind: Pod
metadata:name: mysql-pod-volume
spec:containers:- name: mysqlimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 3600"]volumeMounts:- name: mysql-configmountPath: /tmp/configvolumes:- name: mysql-configconfigMap:name: mysql
[root@k8s-master01 configmap]# kubectl apply -f mysql-pod-volume.yaml 
pod/mysql-pod-volume created
# 创建pod[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config/
/tmp/config # ls
log     lower   my.cnf
/tmp/config # cat log
1/tmp/config # cat lower
1/tmp/config # cat my.cnf
[mysqld]
Welcome=yuhang
/tmp/config # exit
# 查看挂载目录下文件内容
Configmap热加载: 自动更新配置
[root@k8s-master01 configmap]# kubectl edit cm mysql
data:log: "2"# 修改log值为2
[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config/
/tmp/config # cat log
2/tmp/config # exit
# 有时候没改过来可能是还在改,过一会再看看[root@k8s-master01 configmap]# kubectl delete -f mysql-pod-volume.yaml 
pod "mysql-pod-volume" deleted
# 清除环境

nfigmap]# kubectl delete -f mysql-pod-envfrom.yaml
pod “mysql-pod-envfrom” deleted

清除环境


#### 使用configmap第三种方式: volume```shell
[root@k8s-master01 configmap]# cat mysql-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:name: mysqllabels:app: mysql
data:log: "1"lower: "1"my.cnf: |[mysqld]Welcome=yuhang
[root@k8s-master01 configmap]# kubectl apply -f mysql-configmap.yaml 
configmap/mysql configured
# 更新cm[root@k8s-master01 configmap]# cat mysql-pod-volume.yaml 
apiVersion: v1
kind: Pod
metadata:name: mysql-pod-volume
spec:containers:- name: mysqlimage: busyboximagePullPolicy: IfNotPresentcommand: ["/bin/sh", "-c", "sleep 3600"]volumeMounts:- name: mysql-configmountPath: /tmp/configvolumes:- name: mysql-configconfigMap:name: mysql
[root@k8s-master01 configmap]# kubectl apply -f mysql-pod-volume.yaml 
pod/mysql-pod-volume created
# 创建pod[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config/
/tmp/config # ls
log     lower   my.cnf
/tmp/config # cat log
1/tmp/config # cat lower
1/tmp/config # cat my.cnf
[mysqld]
Welcome=yuhang
/tmp/config # exit
# 查看挂载目录下文件内容
Configmap热加载: 自动更新配置
[root@k8s-master01 configmap]# kubectl edit cm mysql
data:log: "2"# 修改log值为2
[root@k8s-master01 configmap]# kubectl exec -it mysql-pod-volume -c mysql -- /bin/sh
/ # cd /tmp/config/
/tmp/config # cat log
2/tmp/config # exit
# 有时候没改过来可能是还在改,过一会再看看[root@k8s-master01 configmap]# kubectl delete -f mysql-pod-volume.yaml 
pod "mysql-pod-volume" deleted
# 清除环境

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/142925.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

计算机网络之网络体系结构

计算机网络体系结构 一、常见的计算机体系结构 1.1 OSI标准以及TCP/IP体系结构 OSI标准失败的原因&#xff1a; OSI的专家们缺乏实际经验&#xff0c;他们在完成OSI标准时没有商业驱动力OSI的协议实现起来过分复杂&#xff0c;而且运行效率很低OSI标准的制定周期太长&#x…

css:文本对齐属性vertical-align实现化学元素上标下标的显示

文档 https://developer.mozilla.org/zh-CN/docs/Web/CSS/vertical-align 语法 vertical-align: <value>;可选值&#xff1a; sub&#xff1a;使元素的基线与父元素的下标基线对齐。 super&#xff1a;使元素的基线与父元素的上标基线对齐。 text-top&#xff1a;使…

JAVA 中集合取交集

日常工作 经常需要取两个数据集的交集。对常用的List 和Set集合做了一个测试 public static void main(String[] args) {List<Integer> list1 Lists.newArrayList();List<Integer> list2 Lists.newArrayList();Set<Integer> set3 Sets.newHashSet();Set&l…

基于SSM的药店药品销售系统

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;Vue 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#xff1a;是 目录…

程序员的护城河

程序员的护城河是一个多维度的概念&#xff0c;它包括技术能力的深度、对创新的追求、沟通协作等软实力。这些因素共同构成了程序员在保障系统安全、数据防护以及网络稳定方面所起到的重要作用。 首先&#xff0c;技术能力的深度是程序员的核心竞争力之一。随着科技的不断发展…

车载通信与DDS标准解读系列(1):DDS-RPC

▎RPC & DDS-RPC RPC&#xff1a;Remote Procedure Call&#xff0c;远程过程调用。 远程过程调用是一种进程间通信&#xff0c;它允许计算机程序在另一个地址空间中执行子程序&#xff0c;就好像用别人的东西像用自己的一样&#xff0c;常用于分布式系统。 远程过程调用…

3分钟带你了解前端缓存-HTTP缓存

前情提要 前端缓存分为下面三大类&#xff0c;本文主要讲解HTTP缓存~ 1. HTTP缓存 强缓存协商缓存 2. 浏览器缓存 本地小容量缓存本地大容量缓存 3. 应用程序缓存 HTML5应用程序缓存 缓存作用 减少了冗余的数据传输减少服务器的负担提高了网站的性能加快加载网页速度 …

易基因:综合全基因组DNA甲基化和转录组学分析鉴定调控骨骼肌发育潜在基因 | 研究进展

大家好&#xff0c;这里是专注表观组学十余年&#xff0c;领跑多组学科研服务的易基因。 DNA甲基化是骨骼肌发育中关键的表观遗传调控机制。但胚胎鸭骨骼肌发育中负责DNA甲基化的调控因子仍然未知。 2023年10月23日&#xff0c;南京农业大学动物科技学院于敏莉副教授团队在《…

核心!华为自研系统鸿蒙趋势

鸿蒙系统的推出引起了全球的关注&#xff0c;毕竟这是华为自主研发的操作系统。这个系统有一些特点很独特。首先&#xff0c;它的自主可控性是一大特色。因为是自家研发的&#xff0c;所以更容易适应外界变化。其次&#xff0c;它采用了分布式架构&#xff0c;这样不同设备之间…

GitHub Universe 2023:AI 技术引领软件开发创新浪潮

GitHub 是全球领先的软件开发和协作平台&#xff0c;数百万开发者和企业在此分享、学习和创建卓越的软件。同时 GitHub 处在 AI 技术前沿&#xff0c;通过其先进的 AI 技术增强开发者体验并赋能未来软件开发的使命。在今天的文章中&#xff0c;我们将一起看看在 GitHub 年度大会…

project打开文件时,显示无法识别此文件格式?

环境&#xff1a; Win 10 专业版 project 2021 问题描述&#xff1a; project打开文件时&#xff0c;显示无法识别此文件格式&#xff1f; 解决方案&#xff1a; 1.测试新建文件&#xff0c;打开都是这样&#xff0c;检查文件都不是旧版本创建&#xff08;未解决&#xff…

Linux之输入输出重定向和管道

一、是什么 linux中有三种标准输入输出&#xff0c;分别是STDIN&#xff0c;STDOUT&#xff0c;STDERR&#xff0c;对应的数字是0、1、2&#xff1a; STDIN 是标准输入&#xff0c;默认从键盘读取信息STDOUT 是标准输出&#xff0c;默认将输出结果输出至终端STDERR 是标准错误…

做作业用台灯好还是不用台灯?高口碑护眼台灯分享

相信大家在生活着也遇到过这个问题&#xff0c;就是孩子在写作业时需不需要使用台灯。有些家长可能认为家里室内的亮度已经很足了&#xff0c;没必要使用台灯。 其实这个想法是错误的&#xff0c;孩子在书写作业时是需要使用台灯的&#xff01;室内灯源照到书桌时时远远不够的&…

jupyter lab配置列表清单

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

数据结构上机实验——图的实现(以无向邻接表为例)、图的深度优先搜索(DFS)、图的广度优先搜索(BFS)

文章目录 数据结构上机实验1.要求2.图的实现&#xff08;以无向邻接表为例&#xff09;2.1创建图2.1.1定义图的顶点、边及类定义2.1.2创建无向图和查找2.1.3插入边2.1.4打印函数 2.2图的深度优先搜索&#xff08;DFS&#xff09;2.3图的广度优先搜索&#xff08;BFS&#xff09…

竞赛 题目:垃圾邮件(短信)分类 算法实现 机器学习 深度学习 开题

文章目录 1 前言2 垃圾短信/邮件 分类算法 原理2.1 常用的分类器 - 贝叶斯分类器 3 数据集介绍4 数据预处理5 特征提取6 训练分类器7 综合测试结果8 其他模型方法9 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于机器学习的垃圾邮件分类 该项目…

技术贴 | SQL 执行 - 执行器优化

本期技术贴主要介绍查询执行引擎的优化。查询执行引擎负责将 SQL 优化器生成的执行计划进行解释&#xff0c;通过任务调度执行从存储引擎里面把数据读取出来&#xff0c;计算出结果集&#xff0c;然后返回给客户。 在关系型数据库发展的早期&#xff0c;受制于计算机 IO 能力的…

前端JS解构数组对象

// 3. 对象数组解构const arr [{username: 小明,age: 18,agw:19},{username: 小ha,age: 18,agw:19}]arr.map(item>item.age)//js结构数组对象console.log( arr.map(item>{return {aaa:item.age,bbb:item.username}}))

搜维尔科技:【软件篇】TechViz是一款专为工程设计的专业级3D可视化软件

在沉浸式房间内深入研究您自己的 3D 数据 沉浸式房间是一个交互式虚拟现实空间&#xff0c;其中每个表面&#xff08;墙壁、地板和天花板&#xff09;都充当投影屏幕&#xff0c;创造高度沉浸式的体验。这就像您的 3D 模型有一个窗口&#xff0c;您可以在其中从不同角度走动、…

bclinux aarch64 ceph 14.2.10 文件存储 Ceph File System, 需要部署mds: ceph-deploy mds

创建池 [rootceph-0 ~]# ceph osd pool create cephfs_data 64 pool cephfs_data created [rootceph-0 ~]# ceph osd pool create cephfs_metadata 32 pool cephfs_metadata created cephfs_metadata 64 报错 官方说明&#xff1a; 元数据池通常最多可容纳几 GB 的数据。为…