Kubernetes持久化储存
1、K8s持久化储存介绍
之前接触hostpath、emptyDir的是本地储存,缺陷数据不能做到和其他机器共享
容器内部的的存储在生命周期是短暂的,会随着容器环境的销毁而销毁,具有不稳定性,在k8s里将对容器应用所需的存储资源抽象为存储卷(Volume)概念来解决这些问题。
K8s目前支持的Volume类型包括k8s的内部资源对象类型,开源共享存储类型和公有云存储等。分类如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 configMap:储存配置文件 (配置中心:nacos) Secret:储存加密数据,证书文件 ServiceAccountToken:储存token数据 EmptDir:临时储存(宿主机随机生成一个储存目录) HostPath:宿主机目录 CephFS:开源共享储存系统(现在用的比较多一些) ClusterFS:开源共享储存系统 FastDFS NFS:开源共享储存 (这个是单点,写脚本会卡主) PersishtenVolumeClain:
2、本地储存——EmptyDir类型的挂载方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 1、编写Deployment控制器的资源清单 [root@master01 kubernetes]# vim nginx-emptDir.yml apiVersion: "apps/v1" kind: "Deployment" metadata: name: nginx-dp namespace: default spec: replicas: 1 selector: matchLabels: app: mysql-dp template: metadata: name: nginx-dp-pod namespace: default labels: app: mysql-dp spec: volumes: - name: mysql-emptydir emptyDir: {} containers: - name: mysql-container image: mysql:5.7 imagePullPolicy: IfNotPresent env : - name: MYSQL_ROOT_PASSWORD value: '123' volumeMounts: - name: mysql-emptydir mountPath: /var/lib/mysql 2、运行并查看 [root@master01 kubernetes]# kubectl apply -f nginx-emptDir.yml [root@master01 kubernetes]# kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE nginx-dp-67b5bd5fdc-kvjqh 1/1 Running 0 18s 10.2.3.119 node03 3、node03查看挂载的数据 [root@node03 ~]# docker inspect fb799f13d7e9 [root@node03 ~]# ll /var/lib/kubelet/pods/9be94529-0040-4185-91c8-91b4b271d387/volumes/kubernetes.io~empty-dir/mysql-emptydir -rw-r----- 1 polkitd input 56 Sep 28 11:53 auto.cnf -rw------- 1 polkitd input 1680 Sep 28 11:53 ca-key.pem -rw-r--r-- 1 polkitd input 1112 Sep 28 11:53 ca.pem -rw-r--r-- 1 polkitd input 1112 Sep 28 11:53 client-cert.pem -rw------- 1 polkitd input 1680 Sep 28 11:53 client-key.pem -rw-r----- 1 polkitd input 1318 Sep 28 11:53 ib_buffer_pool -rw-r----- 1 polkitd input 79691776 Sep 28 11:53 ibdata1 -rw-r----- 1 polkitd input 50331648 Sep 28 11:53 ib_logfile0 -rw-r----- 1 polkitd input 50331648 Sep 28 11:53 ib_logfile1 -rw-r----- 1 polkitd input 12582912 Sep 28 11:53 ibtmp1 drwxr-x--- 2 polkitd input 4096 Sep 28 11:53 mysql lrwxrwxrwx 1 polkitd input 27 Sep 28 11:53 mysql.sock -> /var/run/mysqld/mysqld.sock drwxr-x--- 2 polkitd input 8192 Sep 28 11:53 performance_schema -rw------- 1 polkitd input 1680 Sep 28 11:53 private_key.pem -rw-r--r-- 1 polkitd input 452 Sep 28 11:53 public_key.pem -rw-r--r-- 1 polkitd input 1112 Sep 28 11:53 server-cert.pem -rw------- 1 polkitd input 1680 Sep 28 11:53 server-key.pem drwxr-x--- 2 polkitd input 8192 Sep 28 11:53 sys
3、本地储存——hostpath类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 1、编写控制器的资源清单 [root@master01 kubernetes]# vim nginx-hostpath.yml apiVersion: "apps/v1" kind: "Deployment" metadata: name: nginx-dp namespace: default spec: replicas: 1 selector: matchLabels: app: mysql-dp template: metadata: name: nginx-dp-pod namespace: default labels: app: mysql-dp spec: volumes: - name: mysql-emptydir emptyDir: {} - name: mysql-hostpath hostPath: path: /opt/mysql containers: - name: mysql-container image: mysql:5.7 imagePullPolicy: IfNotPresent env : - name: MYSQL_ROOT_PASSWORD value: '123' volumeMounts: - name: mysql-hostpath mountPath: /var/lib/mysql [root@master01 kubernetes]# kubectl apply -f nginx-hostpath.yml
4、共享储存——NFS类型
1、部署NFS
环境准备
主机名
ip
角色
nfs
10.0.0.31 / 172.16.1.31
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 1、NFS服务安装NFS [root@nfs ~]# yum -y install nfs-utils 2、node节点要挂载过去,所有node节点安装nfs [root@node01 ~]# yum -y install nfs-utils [root@node02 ~]# yum -y install nfs-utils [root@node03 ~]# yum -y install nfs-utils 3、修改nfs服务器的配置文件 [root@nfs ~]# vim /etc/exports /data/wp 172.16.1.0/24(rw,sync ,all_squash) 4、创建挂载目录,并授权,启动服务 [root@nfs ~]# mkdir -p /data/wp [root@nfs ~]# chown -R nfsnobody.nfsnobody /data/wp [root@nfs ~]# systemctl start nfs && systemctl enable nfs 5、验证生效 [root@nfs ~]# cat /var/lib/nfs/etab /data/wp 172.16.1.0/24(rw,sync ,wdelay,hide,nocrossmnt,secure,root_squash,all_squash,no_subtree_check,secure_locks,acl,no_pnfs,anonuid=65534,anongid=65534,sec=sys,rw,secure,root_squash,all_squash)
2、master编写wp挂载nfs的资源清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 1、编写wp的Deployment资源清单 [root@master01 kubernetes]# vim wp-dp-v1.yml apiVersion: "apps/v1" kind: "Deployment" metadata: name: wp-dp namespace: default spec: replicas: 2 selector: matchLabels: app: wp template: metadata: name: wp-pod namespace: default labels: app: wp spec: volumes: - name: wp-data hostPath: path: /data/wp - name: wp-nfs nfs: path: /data/wp readOnly: false server: 172.16.1.31 containers: - name: wp-container image: wordpress imagePullPolicy: IfNotPresent env : - name: WORDPRESS_DB_HOST value: 'mysql-svc' - name: WORDPRESS_DB_USER value: 'wp_user' - name: WORDPRESS_DB_PASSWORD value: '123' - name: WORDPRESS_DB_NAME value: 'wp_db' volumeMounts: - name: wp-nfs mountPath: /var/www/html/ [root@master01 kubernetes]# kubectl apply -f wp-dp-v1.yml 2、编写wp的Service资源 [root@master01 kubernetes]# vim wp-svc.yml apiVersion: v1 kind: Service metadata: name: wordpress-svc namespace: default spec: selector: app: wp ports: - name: http port: 80 protocol: TCP targetPort: 80 nodePort: 30002 type : NodePort [root@master01 kubernetes]# kubectl apply -f wp-svc.yml [root@master01 kubernetes]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) wordpress-svc NodePort 10.1.84.160 <none> 80:30002/TCP 3、编写mysql的Deployment资源 [root@master01 kubernetes]# vim mysql-dp.yml apiVersion: "apps/v1" kind: "Deployment" metadata: name: mysql-dp namespace: default spec: replicas: 1 selector: matchLabels: app: mysql-dp template: metadata: name: mysql-pod namespace: default labels: app: mysql-dp spec: volumes: - name: mysql-emptydir emptyDir: {} - name: mysql-hostpath hostPath: path: /opt/mysql containers: - name: mysql-container image: mysql:5.7.44 imagePullPolicy: IfNotPresent env : - name: MYSQL_ROOT_PASSWORD value: "123" - name: MYSQL_DATABASE value: "wp_db" - name: MYSQL_USER value: "wp_user" - name: MYSQL_PASSWORD value: "123" volumeMounts: - name: mysql-hostpath mountPath: /var/lib/mysql [root@master01 kubernetes]# kubectl apply -f mysql-dp.yml 4、编写mysql的Service资源 [root@master01 kubernetes]# vim mysql-svc.yml apiVersion: v1 kind: Service metadata: name: mysql-svc namespace: default spec: selector: app: mysql-dp ports: - name: mysql port: 3306 protocol: TCP targetPort: 3306 type : ClusterIP [root@master01 kubernetes]# kubectl apply -f mysql-svc.yml [root@master01 kubernetes]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mysql-svc ClusterIP 10.1.47.161 <none> 3306/TCP 52s wordpress-svc NodePort 10.1.84.160 <none> 80:30002/TCP 15h 3、到nfs验证是否挂载成功 [root@nfs ~]# ll /data/wp/ -rw-r--r-- 1 nfsnobody nfsnobody 405 Feb 6 2020 index.php -rw-r--r-- 1 nfsnobody nfsnobody 19915 Jan 1 2024 ... -rw-r--r-- 1 nfsnobody nfsnobody 3246 Mar 2 2024 xmlrpc.php 4、浏览器访问 k8s集群中随便一个节点都可以访问,上面说过,和kube-proxy有关 10.0.0.200:30002
发布文章上传图片
nfs机器里面查看图片是否上传到挂载目录
1 2 3 4 5 6 7 [root@nfs ~]# ll /data/wp/wp-content/uploads/2024/09/ total 512 -rw-r--r-- 1 nfsnobody nfsnobody 74163 Sep 28 14:21 12-1024x758.jpg -rw-r--r-- 1 nfsnobody nfsnobody 6000 Sep 28 14:21 12-150x150.jpg -rw-r--r-- 1 nfsnobody nfsnobody 13125 Sep 28 14:21 12-300x222.jpg -rw-r--r-- 1 nfsnobody nfsnobody 50103 Sep 28 14:21 12-768x568.jpg -rw-r--r-- 1 nfsnobody nfsnobody 367277 Sep 28 14:21 12.jpg
5、PV和PVC的介绍
PV是对底层网络共享存储的抽象,将共享存储定义为一种“资源”
PV由管理员创建和配置
PVC则是用户对存储资源的一个“申请”就像Pod消费Node的资源一样,
PVC能够"消费"PV资源PVC可以申请特定的存储空间和访问模式
1 2 3 4 5 6 7 就目前而言,挂载那台NFS主机磁盘有多大,就能储存多大,对占用没有做限制, PV,可以理解为nfs储存,一共20G,PV就是划分磁盘空间的东西,给储存资源划分空间,划分2G一块,3G一块... PVC,这个储存是一个大的园区,开发商把园区开发成房子,PVC就是购买别墅的人,想要多大,就申请多大(申请PV划分的资源空间), PV划分储存,PVC绑定PV,pod使用指定的PVC
pv和PVC的生命周期
PV和PVC需要注意的地方
1 2 3 4 5 6 在PV的整个生命周期中,可能会处于4种不同的阶段: Avaliable(可用):表示可用状态,还未被任何PVC绑定 Bound(被绑定的):表示PV已经被PVC绑定 Released(已释放):PVC被删除,但是资源还未被集群重新声明,被释放了,里面还有数据在,需要把数据删除或者备份,再把这个pv删除,重启起来,就会变成Avaliable状态 Failed(失败):表示该PV的自动回收失败
PVC绑定PV的条件如下:
创建PVC之后,k8s就会去查找满足我们声明要求的PV比如storageClassName,accessModes以及容是这些是否满足要求,如果满足要求就将PV和PVC绑定在一起。
1 2 3 1、storageClassName 2、accessModes 3、size
需要注意的是目前PV和PVC之间是一对一绑定的关系,也就是说一个PV只能被一个PVC绑定。 >
6、PV、PVC的资源清单
PV资源关键参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 capacity: PV存储的容量 capacity: 5Gi accessModes: 访问模式,k8s支持的访问模式如下 ------------------------------------------------------ ReadWriteOnce(RWO): 读写权限,并且只能被单个Node挂载 ReadOnlyMany(ROX): 只读权限,允许被多个Node挂载 ReadWriteMany(RWX): 读写权限,允许被多个Node挂载 ------------------------------------------------------ persistentVolumeReclaimPolicy: 资源回收策略,pvc删之后数据是否回收的策略 ------------------------------------------------------ Retain: 保留数据,需要手工处理 Recycle: 简单清除文件的操作(例如运行rm -rf /dada/* 命令),如果删除pvc,pv的资源就会被删除释放掉 Delete: 如果把PVC删了,PV也会被一起删除,数据也会被清掉(很少用) 目前只有NFS和HostPath两种类型的PV支持Recycle策略。 ------------------------------------------------------ storageClassName: 存储类别 具有特定类别的PV只能与请求了该类别的PVC绑定。未指定类型的PV则只能对与不请求任何类别的PVC绑定。
编写PV资源清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 1 mib =1024 kib 1 gib = 1024 mib 1、编写PV资源清单,划分5G [root@master01 kubernetes]# vim pv01.yml apiVersion: "v1" kind: "PersistentVolume" metadata: name: pv01 spec: capacity: storage: 5Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: pv01-nfs nfs: path: /data/wp1 server: 172.16.1.31 2、编写PV资源清单,划分3G [root@master01 kubernetes]# vim pv02.yml apiVersion: "v1" kind: "PersistentVolume" metadata: name: pv02 spec: capacity: storage: 4Gi accessModes: - ReadOnlyMany persistentVolumeReclaimPolicy: Recycle storageClassName: pv02-nfs nfs: path: /data/wp2 server: 172.16.1.31 3、编写PV资源清单,划分5G [root@master01 kubernetes]# vim pv03.yml apiVersion: "v1" kind: "PersistentVolume" metadata: name: pv03 spec: capacity: storage: 3Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Recycle storageClassName: pv03-nfs nfs: path: /data/wp3 server: 172.16.1.31 4、运行 [root@master01 kubernetes]# kubectl apply -f pv01.yml [root@master01 kubernetes]# kubectl apply -f pv02.yml [root@master01 kubernetes]# kubectl apply -f pv03.yml [root@master01 kubernetes]# kubectl get pv NAME CAPACITY(#pvc绑定的条件) ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGEC pv01 5Gi RWO Recycle Available pv01-nfs pv02 4Gi ROX Recycle Available pv02-nfs pv03 3Gi RWX Recycle Available pv03-nfs
编写PVC资源清单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 1、编写PVC资源清单 [root@master01 kubernetes]# vim pvc01.yml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc01 spec: accessModes: - ReadWriteOnce resources: requests: storage: 4Gi storageClassName: pv01-nfs 2、运行 [root@master01 kubernetes]# kubectl apply -f pvc01.yml 3、查看PVC已经绑定了pv01 [root@master01 kubernetes]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc01 Bound pv01 5Gi RWO pv01-nfs 4m5s 4、pv已经显示被绑定 [root@master01 kubernetes]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLA pv01 5Gi RWO Recycle Bound default/pvc01 pv01-nfs pv02 4Gi ROX Recycle Available pv02-nfs pv03 3Gi RWX Recycle Available pv03-nfs
7、Pod关联PVC
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 1、创建wordpress-Deployment资源 [root@master01 kubernetes]# vim wp-dp-v2.yml apiVersion: "apps/v1" kind: "Deployment" metadata: name: wp-dp namespace: default spec: replicas: 2 selector: matchLabels: app: wp template: metadata: name: wp-pod namespace: default labels: app: wp spec: volumes: - name: wp-pvc persistentVolumeClaim: claimName: pvc01 containers: - name: wp-container image: wordpress imagePullPolicy: IfNotPresent env : - name: WORDPRESS_DB_HOST value: 'mysql-svc' - name: WORDPRESS_DB_USER value: 'wp_user' - name: WORDPRESS_DB_PASSWORD value: '123' - name: WORDPRESS_DB_NAME value: 'wp_db' volumeMounts: - name: wp-pvc mountPath: /var/www/html/ 2、运行 [root@master01 kubernetes]# kubectl apply -f wp-dp-v2.yml 3、到nfs机器查看挂载成功 [root@nfs ~]# ll /data/wp1/ -rw-r--r-- 1 nfsnobody nfsnobody 405 Feb 6 2020 index.php -rw-r--r-- 1 nfsnobody nfsnobody 19915 Jan 1 2024 license.txt ...