环境:
系统 | 华为openEulerOS(CentOS7) |
k8s版本 | 1.17.3 |
master | 192.168.1.244 |
node1 | 192.168.1.245 |
介绍:
在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是Pod级别的,可以用来实现Pod中容器的文件共享。
部署:
安装nfs
两台节点都需要操作:
yum install -y nfs-utils rpcbind systemctl start nfs systemctl start rpcbind
master节点配置nfs
[root@master ~]#vim /etc/exports /data/iserver-map 192.168.1.0/24(rw,no_root_squash,sync) /data/iserver-webapps 192.168.1.0/24(rw,no_root_squash,sync) /data/iserver-license 192.168.1.0/24(rw,no_root_squash,sync) /data/gisserver-license 192.168.1.0/24(rw,no_root_squash,sync) /data/gisserver-webapps 192.168.1.0/24(rw,no_root_squash,sync)
注释:
/data #代表共享出来的目录
192.168.1.0/24 #允许192.168.1.0/24的网络访问此共享。
rw #表示权限 读写
sync #表示同步写入
no_root_squash #表示客户机以root访问时赋予本地root权限
在master节点上创建一个共享目录
[root@master ~]# mkdir /data/
这里/data 目录需求比较大,可以添加磁盘,相关命令:
fdisk /dev/sdd mkfs.ext4 /dev/sdd1 mount /dev/sdd1 /data
给data目录所有权限
chmod 777 /data
启动nfs服务
[root@master ~]#systemctl start nfs [root@master ~]#systemctl start rpcbind [root@k8s-node1 ~]# systemctl restart nfs [root@k8s-node1 ~]# systemctl restart rpcbind
节点查看nfs
[root@k8s-node1 ~]# showmount 192.168.1.244 -e Export list for 192.168.1.244: /data/gisserver-webapps 192.168.1.0/24 /data/gisserver-license 192.168.1.0/24 /data/iserver-license 192.168.1.0/24 /data/iserver-webapps 192.168.1.0/24 /data/iserver-map 192.168.1.0/24
在master上创建pv、pvc、namespace、svc、deployment yaml文件
mkdir /dwz/iserver -p
vim namespeace-vrgv.yaml apiVersion: v1 kind: Namespace metadata: name: vrgv #namespace名称为vrgv labels: name: vrgv #namespace标签为vrgv
vim iserver-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: iserver namespace: vrgv spec: replicas: 1 selector: matchLabels: app: iserver template: metadata: labels: app: iserver spec: nodeSelector: node1: iserver hostname: vrgv hostAliases: - ip: 192.168.1.226 #这个ip是创建出psql的svc的ip地址 hostnames: - "vrgvtech.com" #必须是vrgvtech.com # initcontainers: # - name: meijie # image: iserver:20200827-1 # command: ['sleep 10'] # imagePullPolicy: Never restartPolicy: Always containers: - name: iserver image: k8s-vrgvgis-standard:20200923 #填写iserver服务的镜像 imagePullPolicy: Never #只从本地获取镜像 command: ["/bin/sh","-c","/app/dwz.sh"] # livenessProbe: # httpGet: # port: 8090 #探测8090端口 # path: /iserver #探测8090端口下的/portal/index.html网页能否正常打开(根据返回码) # initialDelaySeconds: 100 #容器启动后第一次执行探测是需要等待多少秒 # periodSeconds: 2 #执行探测的频率。默认是10秒,最小1秒。 # livenessProbe: # exec: # command: # - /usr/bin/sed # - -i # - '"s+ServerActive=vrgv+ServerActive=vrgv123_$ZBX_HOST_TAG+" /etc/zabbix/zabbix_agentd.conf' # initialDelaySeconds: 1 #容器启动后第一次执行探测是需要等待多少秒 # periodSeconds: 2 #执行探测的频率。默认是10秒,最小1秒。 securityContext: privileged: true #容器内部拥有root权限 ports: - name: iserver8090 containerPort: 8090 ports: - name: agent10050 containerPort: 10050 volumeMounts: - name: pv-iserver-map #自定义名称,需要与下面的volumes.name 一致 mountPath: /app/map - name: pv-iserver-webapps #自定义名称,需要与下面的volumes.name 一致 mountPath: /app/iserver/webapps - name: pv-iserver-license #自定义名称,需要与下面的volumes.name 一致 mountPath: /opt/SuperMap/License env: #注入容器内的环境变量 - name: ZBX_HOST_TAG value: "123456" - name: ServerActive value: "zabbixproxy.ops:10051,zabbixproxytls.ops:10051" volumes: - name: pv-iserver-map #自定义名称 persistentVolumeClaim: claimName: nfs-iserver-map #pvc名字 - name: pv-iserver-webapps #自定义名称 persistentVolumeClaim: claimName: nfs-iserver-webapps #pvc名字 - name: pv-iserver-license #自定义名称 persistentVolumeClaim: claimName: nfs-iserver-license #pvc名字
[root@k8s-master iserver]# cat pv-iserver-map.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-iserver-map namespace: vrgv # labels: # type: vrgv #与下面pvc中的selector.matchLabels.type一致才能关联成功 spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: pv-iserver-map nfs: path: "/data/iserver-map" #挂载目录 server: 192.168.1.244 #共享主机IP readOnly: false [root@k8s-master iserver]# cat pv-iserver-license.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-iserver-license namespace: vrgv # labels: # type: vrgv #与下面pvc中的selector.matchLabels.type一致才能关联成功 spec: capacity: storage: 10Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: pv-iserver-license nfs: path: "/data/iserver-license" server: 192.168.1.244 #共享主机IP readOnly: false [root@k8s-master iserver]# cat pv-iserver-webapps.yaml apiVersion: v1 kind: PersistentVolume metadata: name: pv-iserver-webapps namespace: vrgv # labels: # type: vrgv #与下面pvc中的selector.matchLabels.type一致才能关联成功 spec: capacity: storage: 20Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Retain storageClassName: pv-iserver-webapps nfs: path: "/data/iserver-webapps" server: 192.168.1.244 #共享主机IP readOnly: false
[root@k8s-master iserver]# cat pvc-iserver-map.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfs-iserver-map namespace: vrgv spec: accessModes: - ReadWriteMany #读写权限,允许被多个node挂载 resources: requests: storage: 1Gi storageClassName: pv-iserver-map # selector: # matchLabels: # type: "vrgv" [root@k8s-master iserver]# cat pvc-iserver-license.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfs-iserver-license namespace: vrgv spec: accessModes: - ReadWriteMany #读写权限,允许被多个node挂载 resources: requests: storage: 1Gi storageClassName: pv-iserver-license # selector: # matchLabels: # type: "vrgv" [root@k8s-master iserver]# cat pvc-iserver-webapps.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: nfs-iserver-webapps namespace: vrgv spec: accessModes: - ReadWriteMany #读写权限,允许被多个node挂载 resources: requests: storage: 10Gi storageClassName: pv-iserver-webapps # selector: # matchLabels: # type: "vrgv"
[root@k8s-master iserver]# cat iserver-svc.yaml apiVersion: v1 kind: Service metadata: name: iserver namespace: vrgv spec: type: NodePort ports: - name: iserver nodePort: 30010 #端口可自定义 port: 8090 protocol: TCP selector: app: iserver sessionAffinity: ClientIP
创建各资源
[root@k8s-master iserver]# kubectl create -f iserver-deployment.yaml [root@k8s-master iserver]# kubectl create -f iserver-svc.yaml [root@k8s-master iserver]# kubectl create -f pv-iserver-map.yaml [root@k8s-master iserver]# kubectl create -f pv-iserver-license.yaml [root@k8s-master iserver]# kubectl create -f pv-iserver-webapps.yaml [root@k8s-master iserver]# kubectl create -f pvc-iserver-map.yaml [root@k8s-master iserver]# kubectl create -f pvc-iserver-license.yaml [root@k8s-master iserver]# kubectl create -f pvc-iserver-webapps.yaml [root@k8s-master iserver]# kubectl create -f namespeace-vrgv.yaml
注释:
ReadWriteOnce 读写权限,并且只能被单个Node挂载
ReadOnlyMany 只读权限,允许被多个Node挂载
ReadWriteMany 读写权限,允许被多个Node挂载
Retain 管理员回收:kubectl delete pv pv-name 创建:kubectl apply -f pv-name.yaml ;Retain策略 在删除pvc后PV变为Released不可用状态, 若想重新被使用,需要管理员删除pv,重新创建pv,删除pv并不会删除存储的资源,只是删除pv对象而已;若想保留数据,请使用该Retain,
Recycle策略 – 删除pvc自动清除PV中的数据,效果相当于执行 rm -rf /thevolume/*. 删除pvc时.pv的状态由Bound变为Available.此时可重新被pvc申请绑定
Delete – 删除存储上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等,NFS不支持delete策略
storageClassName :在pvc的请求存储大小和访问权限与创建的pv一致的情况下 根据storageClassName进行与pv绑定。常用在pvc需要和特定pv进行绑定的情况下。举例:当有创建多个pv设置存储的大小和访问权限一致时,且pv,pvc没有配置storageClassName时,pvc会根据存储大小和访问权限去随机匹配。如果配置了storageClassName会根据这三个条件进行匹配。当然也可以用其他方法实现pvc与特定pv的绑定如标签.
pv是没有namespace的概念,也就没有租户的概念,但 pvc 有租户的概念,当需要在某个 namespace 下使用 pvc 时,需要指定该 pvc 所属 namespace
查看pv状态
[root@k8s-master iserver]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-iserver-license 10Gi RWX Retain Bound vrgv/nfs-iserver-license pv-iserver-license 12h pv-iserver-map 10Gi RWX Retain Bound vrgv/nfs-iserver-map pv-iserver-map 12h pv-iserver-webapps 20Gi RWX Retain Bound vrgv/nfs-iserver-webapps pv-iserver-webapps 12h
注释:STATUS可能存在一下4个阶段之一
Available 可用状态,还未与某个PVC绑定
Bound 已与某个PVC绑定
Released 绑定得PVC已经删除,资源已释放,但没有被集群回收
Failed 自动资源回收失败
查看pod状态
[root@k8s-master iserver]# kubectl get pod -n vrgv NAME READY STATUS RESTARTS AGE iserver-74b6497d98-kxdbw 1/1 Running 0 44m
如状态是running,说明pvc挂载没有异常,已经实现持久化存储
需要注意的是:同步数据初始化时只能从外部映射到内部,通过判断脚本可实现在初始化之后,判断是否需要内部映射到外部