部署k8s(15):持久化存储方案

一、ConfigMap

1、概念

		ConfigMap的功能在k8s1.2版本中引入的,许多应用程序会从配置文件,命令行参数或环境变量中读取配置信息。ConfigMap API会给我们提供了向容器中注入配置信息的机制,ConigMap可以被用来保存单个属性,也可以用来保存整个配置文件或者JSON二进制的对象

2、ConfigMap的创建

		1)使用文件夹创建(--from-file:键的名字是文件的名字,值是文件的内容)
			[root@k8s-master1 configmap]# cat web01
				enemies=alices
				lives=3
				enemies.cheat.level=nogoodrotten
			[root@k8s-master1 configmap]# cat web02
				color.good=purple
				color.bad=yellow
				allow.textmode=true
			[root@k8s-master1 configmap]# ls
				web01  web02
			[root@k8s-master1 ~]# kubectl create configmap web-config --from-file=/root/configmap/
			[root@k8s-master1 ~]# kubectl get cm
				NAME         DATA   AGE
				web-config   2      92s
			[root@k8s-master1 ~]# kubectl describe cm web-config
				Name:         web-config
				Namespace:    default
				Labels:       <none>
				Annotations:  <none>

				Data
				====
				web01:
				----
				enemies=alices
				lives=3
				enemies.cheat.level=nogoodrotten

				web02:
				----
				color.good=purple
				color.bad=yellow
				allow.textmode=true

				Events:  <none>
			[root@k8s-master1 ~]# kubectl get cm web-config -o yaml
				apiVersion: v1
				data:
				  web01: |
				    enemies=alices
				    lives=3
				    enemies.cheat.level=nogoodrotten
				  web02: |
				    color.good=purple
				    color.bad=yellow
				    allow.textmode=true
				kind: ConfigMap
				metadata:
				  creationTimestamp: "2020-05-06T17:51:56Z"
				  name: web-config
				  namespace: default
				  resourceVersion: "76065"
				  selfLink: /api/v1/namespaces/default/configmaps/web-config
				  uid: 8c047a9f-f31a-4ef6-bed9-45807872902e
		2)使用文件创建 
			[root@k8s-master1 ~]# kubectl create configmap web01-config --from-file=/root/configmap/web01
			[root@k8s-master1 ~]# kubectl describe cm web01-config 
				Name:         web01-config
				Namespace:    default
				Labels:       <none>
				Annotations:  <none>

				Data
				====
				web01:
				----
				enemies=alices
				lives=3
				enemies.cheat.level=nogoodrotten

				Events:  <none>
			[root@k8s-master1 ~]# kubectl get cm web01-config -o yaml
				apiVersion: v1
				data:
				  web01: |
				    enemies=alices
				    lives=3
				    enemies.cheat.level=nogoodrotten
				kind: ConfigMap
				metadata:
				  creationTimestamp: "2020-05-06T17:55:44Z"
				  name: web01-config
				  namespace: default
				  resourceVersion: "76400"
				  selfLink: /api/v1/namespaces/default/configmaps/web01-config
				  uid: ad405e87-f153-4209-bd11-7eafec4c8ec4
		3)使用字面值创建
			[root@k8s-master1 ~]# kubectl create configmap mysql-config --from-literal=mysql.how=chaoyue --from-literal=mysql.type=mysql-mmm
			[root@k8s-master1 ~]# kubectl describe cm mysql-config
				Name:         mysql-config
				Namespace:    default
				Labels:       <none>
				Annotations:  <none>

				Data
				====
				mysql.how:
				----
				chaoyue
				mysql.type:
				----
				mysql-mmm
				Events:  <none>
			[root@k8s-master1 ~]# kubectl get cm mysql-config -o yaml
				apiVersion: v1
				data:
				  mysql.how: chaoyue
				  mysql.type: mysql-mmm
				kind: ConfigMap
				metadata:
				  creationTimestamp: "2020-05-06T18:01:58Z"
				  name: mysql-config
				  namespace: default
				  resourceVersion: "76949"
				  selfLink: /api/v1/namespaces/default/configmaps/mysql-config
				  uid: 3c85f0b3-0500-4192-a3fa-3f199e674b56

3、Pod中使用创建的ConfigMap

		1)使用ConfigMap代替环境变量
			[root@k8s-master1 configmap]# vim ./env-nginx.yaml (导入配置的两种方法,- name: MYSQL_HOW:必须使用下划线)
				apiVersion: v1
				kind: Pod
				metadata:
				  name: nginx
				spec:
				  containers:
				    - name: nginx
				      image: nginx:v1
				      imagePullPolicy: IfNotPresent
				      command: [ "bin/sh","-c","env"]
				      env:
				        - name: MYSQL_HOW
				          valueFrom:
				            configMapKeyRef:
				              name: mysql-config
				              key: mysql.how
				        - name: MYSQL_TYPE
				          valueFrom:
				            configMapKeyRef:
				              name: mysql-config
				              key: mysql.type
				      envFrom:
				        - configMapRef:
				            name: web-config
				  restartPolicy: Never
			[root@k8s-master1 ~]# kubectl log nginx
				log is DEPRECATED and will be removed in a future version. Use logs instead.
				web01=enemies=alices
				lives=3
				enemies.cheat.level=nogoodrotten

				web02=color.good=purple
				color.bad=yellow
				allow.textmode=true

				MYSQL_HOW=chaoyue
				MYSQL_TYPE=mysql-mmm
		2)用ConfigMap设置命令行参数
			[root@k8s-master1 ~]# vim configmap/env-nginx.yaml 
				apiVersion: v1
				kind: Pod
				metadata:
				  name: nginx
				spec:
				  containers:
				    - name: nginx
				      image: nginx:v1
				      imagePullPolicy: IfNotPresent
				      command: [ "bin/sh","-c","echo $(MYSQL_HOW) $(MYSQL_TYPE)"]
				      env:
				        - name: MYSQL_HOW
				          valueFrom:
				            configMapKeyRef:
				              name: mysql-config
				              key: mysql.how
				        - name: MYSQL_TYPE
				          valueFrom:
				            configMapKeyRef:
				              name: mysql-config
				              key: mysql.type
				  restartPolicy: Never
			[root@k8s-master1 ~]# kubectl log nginx
				log is DEPRECATED and will be removed in a future version. Use logs instead.
				chaoyue mysql-mmm
		3)使用数据卷插件使用ConfigMap
			[root@k8s-master1 ~]# vim configmap/env-nginx.yaml 
				apiVersion: v1
				kind: Pod
				metadata:
				  name: nginx
				spec:
				  containers:
				    - name: nginx
				      image: nginx:v1
				      imagePullPolicy: IfNotPresent
				      command: [ "bin/sh","-c","ls /etc/config/"]
				      volumeMounts:
				      - name: web-volume
				        mountPath: /etc/config
				  volumes:
				  - name: web-volume
				    configMap:
				      name: web-config
				  restartPolicy: Never
			[root@k8s-master1 ~]# kubectl create -f configmap/env-nginx.yaml 
				pod/nginx created
			[root@k8s-master1 ~]# kubectl log nginx
				log is DEPRECATED and will be removed in a future version. Use logs instead.
				web01
				web02

4、ConfigMap的热更新

		[root@k8s-master1 ~]# vim configmap/env-nginx.yaml 
			apiVersion: v1
			kind: Pod
			metadata:
			  name: nginx
			spec:
			  containers:
			    - name: nginx
			      image: nginx:v1
			      imagePullPolicy: IfNotPresent
			      volumeMounts:
			      - name: web-volume
			        mountPath: /etc/config
			  volumes:
			  - name: web-volume
			    configMap:
			      name: web-config
	 	[root@k8s-master1 ~]# kubectl edit configmap web-config(aa=aa,bb=bb这两个实现添加的)
			# Please edit the object below. Lines beginning with a '#' will be ignored,
			# and an empty file will abort the edit. If an error occurs while saving this file will be
			# reopened with the relevant failures.
			#
			apiVersion: v1
			data:
			  web01: |
			    enemies=alices
			    lives=3
			    enemies.cheat.level=nogoodrotten
			    aa=aa
			    bb=bb
			  web02: |
			    color.good=purple
			    color.bad=yellow
			    allow.textmode=true
			kind: ConfigMap
			metadata:
			  creationTimestamp: "2020-05-06T17:51:56Z"
			  name: web-config
			  namespace: default
			  resourceVersion: "88310"
			  selfLink: /api/v1/namespaces/default/configmaps/web-config
			  uid: 8c047a9f-f31a-4ef6-bed9-45807872902e
		[root@k8s-master1 ~]# kubectl exec nginx  -- cat /etc/config/web01
			enemies=alices
			lives=3
			enemies.cheat.level=nogoodrotten
			aa=aa
			bb=bb

二、Secret

1、secret存在的意义

		Secret存在意义Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中.Secret可以以Volume或者环境变量的方式使用Secret有三种类型:
			1/)Service Account:用来访问Kubernetes API, 由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中
			2)Opaque:base64编码格式的Secret,用来存储密码、密钥等
			3)kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息

2、Service Account

		[root@k8s-master1 ~]# kubectl run nginx --image nginx
		[root@k8s-master1 ~]# kubectl get pod
			NAME                    READY   STATUS    RESTARTS   AGE
			nginx-55fc968d9-d7bp9   1/1     Running   0          4s
			[root@k8s-master1 ~]# kubectl exec nginx-55fc968d9-d7bp9 -- ls /run/secrets/kubernetes.io/serviceaccount
			ca.crt
			namespace
			token

3、Opaque Secret

		1)加密
			[root@k8s-master1 ~]# echo -n "admin" | base64
				YWRtaW4=
			[root@k8s-master1 ~]# echo -n "pwd@123" | base64
				cHdkQDEyMw==
		2)解密
			[root@k8s-master1 ~]# echo -n "cHdkQDEyMw==" | base64 -d
				pwd@123
		3)创建secrets
			[root@k8s-master1 ~]# vim secrets.yaml
				apiVersion: v1
				kind: Secret
				metadata:
				  name: mysecret
				type: Opaque
				data:
				  password: cHdkQDEyMw==
				  username: YWRtaW4=
			[root@k8s-master1 ~]# kubectl create -f secrets.yaml 
			[root@k8s-master1 ~]# kubectl get secrets
				NAME                  TYPE                                  DATA   AGE
				default-token-44kbr   kubernetes.io/service-account-token   3      18d
				mysecret              Opaque                                2      14s
		4)使用方法
			#将secret挂载到volume中
			[root@k8s-master1 ~]# vim nginx.yaml 
				apiVersion: v1
				kind: Pod
				metadata:
				  labels:
				    app: nginx
				  name: nginx
				spec:
				  volumes:
				  - name: secrets
				    secret:
				      secretName: mysecret
				  containers:
				  - image: nginx
				    imagePullPolicy: IfNotPresent
				    name: nginx01
				    volumeMounts:
				    - name: secrets
				      mountPath: '/test'
				      readOnly: true
			[root@k8s-master1 ~]# kubectl create -f nginx.yaml 
			[root@k8s-master1 ~]# kubectl exec nginx -- cat /test/password
				pwd@123
			[root@k8s-master1 ~]# kubectl exec nginx -- cat /test/username
				admin
			#将Secret导出到环境变量中
			[root@k8s-master1 ~]# vim nginx.yaml
				apiVersion: apps/v1
				kind: Deployment
				metadata:
				  name: nginx-deployment
				spec:
				  replicas: 2
				  selector:
				    matchLabels:
				      app: nginxs
				  template:
				    metadata:
				      labels:
				        app: nginxs
				    spec:
				      containers:
				        - name: nginx-1
				          image: nginx
				          imagePullPolicy: IfNotPresent
				          ports:
				           - containerPort: 80
				          env:
				           - name: NGINX_USER
				             valueFrom:
				               secretKeyRef:
				                 name: mysecret
				                 key: username
				           - name: NGINX_PASSWORD
				             valueFrom:
				               secretKeyRef:
				                 name: mysecret
				                 key: password
			[root@k8s-master1 ~]# kubectl apply -f nginx.yaml
			[root@k8s-master1 ~]# kubectl get secret
				NAME                  TYPE                                  DATA   AGE
				default-token-44kbr   kubernetes.io/service-account-token   3      19d
				mysecret              Opaque                                2      6m7s
			[root@k8s-master1 ~]# kubectl get pod
				NAME                                READY   STATUS    RESTARTS   AGE
				nginx-deployment-649bd7d545-hr6hb   1/1     Running   0          5m52s
				nginx-deployment-649bd7d545-wbsll   1/1     Running   0          5m52s
			[root@k8s-master1 ~]# kubectl exec -it nginx-deployment-649bd7d545-hr6hb /bin/bash(只能进入容器中查看)
			root@nginx-deployment-649bd7d545-hr6hb:/# echo $NGINX_USER    
				admin
			root@nginx-deployment-649bd7d545-hr6hb:/# echo $NGINX_PASSWORD
				pwd@123

4、kubernetes.io/dockerconfigjson

		[root@k8s-master1 ~]# kubectl create secret docker-registry harbor --docker-server=hub.benet.com --docker-username=admin --docker-password=Harbor12345 --docker-email=admin@example.com
		[root@k8s-master1 ~]# kubectl get secret
			NAME                  TYPE                                  DATA   AGE
			default-token-44kbr   kubernetes.io/service-account-token   3      19d
			harbor                kubernetes.io/dockerconfigjson        1      65s
		[root@k8s-master1 ~]# vim secrets.yaml 
			apiVersion: v1
			kind: Pod
			metadata:
			  name: tomcat
			spec:
			  containers:
			   - name: tomcat
			     image: hub.benet.com/xitong/tomcat:7.1
			  imagePullSecrets:
			   - name: harbor
		[root@k8s-master1 ~]# kubectl create -f secrets.yaml
		[root@k8s-master1 ~]# kubectl get pod
			NAME     READY   STATUS              RESTARTS   AGE
			tomcat   0/1     ContainerCreating   0          23s
		[root@k8s-master1 ~]# kubectl get pod
			NAME     READY   STATUS    RESTARTS   AGE
			tomcat   1/1     Running   0          31s

三、Volume

1、介绍

		容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题,首先,当容器崩渍时,kubelet会重启它,但是容器中的文件将丢失――容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes中的volume抽象就很好的解决了这些问题

2、背景

		Kubernetes中的卷有明确的寿命――与封装它的Pod相同,所以,卷的生命比Pod中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当Pod不再存在时,卷也将不复存在。也许更重要的是,Kubernetes支持多种类型的卷,Pod可以同时使用任意数量的卷	

3、emptyDir

		当Pod被分配给节点时, 首先创建emptyDir卷,并且只要该Pod在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod中的容器可以读取和写入emptyDir卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除Pod时,emptyDir中的数据将被永久删除
		emptyDir的使用方式:
			暂存空间,例如用于基于磁盘的合并排序
			用作长时间计算崩溃恢复时的检查点
			Web服务器容器提供数据时, 保存内容管理器容器提取的文件
		1)配置方式
			[root@k8s-master1 ~]# vim emrydir.yaml 
				apiVersion: v1
				kind: Pod
				metadata:
				  name: test-pod
				spec:
				  containers:
				  - image: nginx
				    imagePullPolicy: IfNotPresent
				    name: nginx
				    volumeMounts:
				    - mountPath: /cache
				      name: cache-volume
				  - image: hub.benet.com/xitong/tomcat:7.1
				    imagePullPolicy: IfNotPresent
				    name: tomcat
				    volumeMounts:
				    - mountPath: /cache
				      name: cache-volume
				  volumes:
				  - name: cache-volume
				    emptyDir: {}
			[root@k8s-master1 ~]# kubectl create -f emrydir.yaml 
			[root@k8s-master1 ~]# kubectl get pod
				NAME       READY   STATUS    RESTARTS   AGE
				test-pod   2/2     Running   0          3s
			[root@k8s-master1 ~]# kubectl exec -it test-pod -c nginx /bin/bash(进入nginx容器)
			root@test-pod:/cache# date > test.txt(在nginx容器写入数据)
			[root@k8s-master1 ~]# kubectl exec -it test-pod -c tomcat /bin/bash(进入tomcat容器)
			[root@test-pod cache]# cat test.txt (在tomcat容器中查看写入的数据)
				Fri May  8 19:42:23 UTC 2020
			[root@test-pod cache]# date >> test.txt (在toncat中追加数据)
			root@test-pod:/cache# cat test.txt (在nginx中查看数据)
				Fri May  8 19:42:23 UTC 2020
				Sat May  9 03:43:23 CST 2020

4、hostPath

		1)hostPath:卷将主机节点的文件系统中的文件或目录挂载到集群中
		2)host Path的用途如下:
			*运行需要访问Docker内部的容器; 使用/var/lib/docker的hostPath
			*在容器中运行cAdvisor; 使用/dev/cgroups的host Path
			*允许pod指定给定的host Path是否应该在pod运行之前存在, 是否应该创建, 以及它应该以什么形式存在
		除了所需的path属性之外, 用户还可以为host Path卷指定type
			值						行为
			 						空字符串(默认) 用于向后兼容, 这意味着在挂载hostPath卷之前不会执行任何检查。
			DirectoryOrCreate 		如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为0755, 与Kube let具有相同的组和所有权。
			Directory 				给定的路径下必须存在目录
			FileOrCreate			如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设FileOrCreate置为0644, 与Kube let具有相同的组和所有权。
			File 					给定的路径下必须存在文件
			Socket 					给定的路径下必须存在UNIX套接字
			CharDevice 				给定的路径下必须存在字符设备
			BlockDevice 			给定的路径下必须存在块设备
		使用这种卷类型是请注意,因为
			*由于每个节点上的文件都不同, 具有相同配置(例如从podTemplate创建的) 的pod在不同节点上的行为可能会有所不同
			*当Kubernetes按照计划添加资源感知调度时, 将无法考虑hostPath使用的资源
			*在底层主机上创建的文件或者目录只能由root写入,您需要在特权容器以root身份运行进程,或者修改主机上的文件权限以便写入hostpath卷
		3)用法(最好是指定pod在哪台node节点节点中运行)
			[root@k8s-node1 /]# mkdir data
			[root@k8s-master1 ~]# vim hostpath.yaml 
				apiVersion: v1
				kind: Pod
				metadata:
				  name: test-pod
				spec:
				  containers:
				  - image: nginx
				    imagePullPolicy: IfNotPresent
				    name: nginx
				    volumeMounts:
				    - mountPath: /cache
				      name: cache-volume
				  volumes:
				  - name: cache-volume
				    hostPath:
				      path: /data
				      type: Directory
			[root@k8s-master1 ~]# kubectl create -f hostpath.yaml 
			[root@k8s-master1 ~]# kubectl  get pod
				NAME       READY   STATUS    RESTARTS   AGE
				test-pod   1/1     Running   0          4s
			[root@k8s-node1 /]# echo "test" > data/1.txt
			[root@k8s-master1 ~]# kubectl exec -it test-pod -- cat /cache/1.txt
				test

四、pv卷(以NFS为例)

1、概念

		1)PersistenVolume(PV)
			是由管理员设置的存储,它是集群的一部分。就像节点是集群中的资源一样,Pv也是集群中的资源。PV是Volume之类的卷插件,但是具有独特于使用PV的pod的生命周期,此API对象包含存储实现的细节,即NFS、ISCSI或者是云提供商的存储系统
		2)PersistentVolumeClaim(PVC)
			使用户存储的请求。它与pod相似。pod消耗节点资源,PVC消耗PV资源。pod可以请求特定级别的资源(cpu和内存)。声明可以请求特定的大小和访问模式(例如:可以以读/写一次或只读多次模式挂载)
		3)静态PV
			集群管理员创建一些PV。它们带有可供群集用户使用的实际存储的细节。他们存在于K8S API中,可用于消费
		4)动态PV
			*当管理员创建的静态pv都不匹配用户的PVC时,集群可能会尝试动态的为PVC创建卷。此配置基于storageclasses:PVC必须请求【存储类】,并且管理员必须创建并配置该类才能进行动态创建。声明该类为"",可以有效的禁用其动态配置
			*要启用基于存储级别的动态存储配置,集群管理员需要启用API server上的DefaultStorageClass[准入控制器],例如,通过确保DefaultStorageClass位于API Server组件的--admission-control标志,使用逗号分隔的有序值列表中,可以完成此操作
		5)绑定
			master中的控制环路监听新的PVC,寻找匹配的pv(如果可能),并将它们绑定在一起,如果为新的PVC动态调度PV,则该环路始终将该PV绑定到PVC。否则,用户总会得到他们所请求的存储,但是容量可能超过要求的数量,一旦PV和PVC绑定后,PVC绑定时排他性的,不管他们时如何绑定的。PVC跟PV绑定时一对一的映射

2、持久化卷声明的保护

		PVC保护的目的是确保由pod正在使用的PVC不会从系统中移除,因为如果被移除的话可能会导致数据丢失
		当启动pvc保护alpha功能时,如果用户删除了一个pod正在使用的PVC,则该PVC不会被立即删除。PVC的删除将被推迟,直到PVC不在被任何pod使用

3、持久化卷的类型

		Persistent Volume类型以插件形式实现。Kubernetes目前支持以下插件类型:
			GCEPersistent Disk AWSEIasticBlockStore AzureFile AzureDisk FC(FibreChannel)
			Flex Volume Flocker NFS iSCSI RBD(Ceph Block Device) CephFS
			Cinder(Open Stack block storage) Glusterfs VsphereVolume Quobyte Volumes
			HostPath  VMware Photon Portworx Volumes ScalelO Volumes StorageOS

4、PV访问模式

		Persistentvolume可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个PV的访问模式都将被设置为该卷支持的特定模式。例如,NFS可以支持多个读/写客户端,但特定的NFS PV可能以只读方式导出到服务器上。每个PV都有一套自己的用来描述特定功能的访问模式
			ReadWriteOnce(RWO)——该卷可以被单个节点以读/写模式挂载
			ReadOnlyMany(ROX)——该卷可以被多个节点以只读模式挂载
			ReadWriteMany(RWX)——该卷可以被多个节点以读/写模式挂载在命令行中,

5、回收策略

		Retain(保留) ——手动回收
		Recycle(回收) ——基本擦除(rm -f/the valume/”)
		Delete(删除) ——关联的存储资产(例如AWSEBS、GCEPD、AzureDisk和OpenStack Cinder卷)将被删除
		当前, 只有NFS和HostPath支持回收策略。AWS EBS、GCE PD、Azure Disk和Cinder卷支持删除策略

6、状态

		卷可以处于以下的某种状态:
			Available(可用)——块空闲资源还没有被任何声明绑定
			Bound(已绑定) ——卷已经被声明定
			Released(已释放) ——声明被副除, 但是资源还未被集群重新声明
			Failed(失败) ——该卷的自动回收失败命令行会显示绑定到PV的PVC的名称

7、持久化演示

		1)安装NFS服务器(先启动rpcbind)
			[root@lb1 ~]# yum -y install nfs-utils rpcbind
			[root@lb1 /]# mkdir -p /data/nfs{1..4}
			[root@lb1 /]# vim /etc/exports
				/data/nfs1      *( rw,no_root_squash)
				/data/nfs2      *( rw,no_root_squash)
				/data/nfs3      *( rw,no_root_squash)
				/data/nfs4      *( rw,no_root_squash)
			[root@lb1 /]# systemctl start rpcbind nfs
			[root@lb1 /]# systemctl enable rpcbind nfs	
		2)编辑pv
			[root@k8s-master1 ~]# vim pv.yaml 
				apiVersion: v1
				kind: PersistentVolume
				metadata:
				  name: nfs01
				spec:
				  capacity:
				    storage: 10Gi
				  accessModes:
				    - ReadWriteOnce
				  persistentVolumeReclaimPolicy: Retain
				  storageClassName: nfs
				  nfs:
				    path: /data/nfs1
				    server: 192.168.100.50
				---
				apiVersion: v1
				kind: PersistentVolume
				metadata:
				  name: nfs02
				spec:
				  capacity:
				    storage: 5Gi
				  accessModes:
				    - ReadWriteOnce
				  persistentVolumeReclaimPolicy: Retain
				  storageClassName: nfs
				  nfs:
				    path: /data/nfs2
				    server: 192.168.100.50
				---
				apiVersion: v1
				kind: PersistentVolume
				metadata:
				  name: nfs03
				spec:
				  capacity:
				    storage: 3Gi
				  accessModes:
				    - ReadWriteOnce
				  persistentVolumeReclaimPolicy: Retain
				  storageClassName: nfs
				  nfs:
				    path: /data/nfs3
				    server: 192.168.100.50
				---
				apiVersion: v1
				kind: PersistentVolume
				metadata:
				  name: nfs04
				spec:
				  capacity:
				    storage: 1Gi
				  accessModes:
				    - ReadWriteOnce
				  persistentVolumeReclaimPolicy: Retain
				  storageClassName: nfs
				  nfs:
				    path: /data/nfs4
				    server: 192.168.100.50

			[root@k8s-master1 ~]# kubectl create -f pv.yaml 
			[root@k8s-master1 ~]# kubectl get pv
				NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
				nfs01   10Gi       RWO            Retain           Available           nfs                     9s
				nfs02   10Gi       RWO            Retain           Available           nfs                     9s
				nfs03   3Gi        RWO            Retain           Available           nfs                     9s
				nfs04   1Gi        RWO            Retain           Available           nfs                     9s
		3)编辑pvc
			[root@k8s-master1 ~]# vim pvc.yaml 
				apiVersion: v1
				kind: Service
				metadata:
				  name: nginx
				  labels:
				    app: nginx
				spec:
				  ports:
				    - port: 80
				      name: web
				  clusterIP: None
				  selector:
				      app: nginx
				---
				apiVersion: apps/v1
				kind: StatefulSet
				metadata:
				  name: web
				spec:
				  selector:
				    matchLabels:
				      app: nginx
				  serviceName: "nginx"
				  replicas: 2
				  template:
				    metadata:
				      labels:
				        app: nginx
				    spec:
				      containers:
				       - name: nginx
				         image: nginx
				         imagePullPolicy: IfNotPresent 
				         ports:
				          - containerPort: 80
				            name: web
				         volumeMounts:
				          - name: www
				            mountPath: /usr/share/nginx/html
				  volumeClaimTemplates:
				   - metadata:
				       name: www
				     spec:
				       accessModes: ["ReadWriteOnce"]
				       storageClassName: "nfs"
				       resources:
				         requests:
				           storage: 1.5Gi   
			[root@k8s-master1 ~]# kubectl create -f pvc.yaml 
			[root@k8s-master1 ~]# kubectl get pv
				NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE
				nfs01   10Gi       RWO            Retain           Available                       nfs                     25s
				nfs02   5Gi        RWO            Retain           Bound       default/www-web-1   nfs                     25s
				nfs03   3Gi        RWO            Retain           Bound       default/www-web-0   nfs                     25s
				nfs04   1Gi        RWO            Retain           Available                       nfs                     25s
			[root@k8s-master1 ~]# kubectl get pvc
				NAME        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
				www-web-0   Bound    nfs03    3Gi        RWO            nfs            51m
				www-web-1   Bound    nfs02    5Gi        RWO            nfs            49m
			[root@k8s-master1 ~]# kubectl get pod
				NAME       READY   STATUS              RESTARTS   AGE
				web-0      1/1     Running             0          2m7s
				web-1      1/1     Running             0          8s
			[root@k8s-master1 ~]# kubectl exec -it web-0 /bin/bash
			root@web-0:/# df -Th
				Filesystem                Type     Size  Used Avail Use% Mounted on
				192.168.100.50:/data/nfs3 nfs4      78G  1.5G   77G   2% /usr/share/nginx/html

8、pv的手动回收

		[root@k8s-master1 /]# kubectl  get pv
			NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS        CLAIM               STORAGECLASS   REASON   AGE
			nfs01   10Gi       RWO            Retain           Bound         default/www-web-2   nfs                     10d
			nfs02   5Gi        RWO            Retain           Terminating   default/www-web-1   nfs                     10d
			nfs03   3Gi        RWO            Retain           Terminating   default/www-web-0   nfs                     10d
			nfs04   1Gi        RWO            Retain           Available                         nfs                     10d
		[root@k8s-master1 /]# kubectl  get pvc
			NAME        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
			www-web-0   Bound    nfs03    3Gi        RWO            nfs            10d
			www-web-1   Bound    nfs02    5Gi        RWO            nfs            10d
			www-web-2   Bound    nfs01    10Gi       RWO            nfs            9d
		#接触绑定
		[root@k8s-master1 /]# kubectl  delete pvc www-web-0 
			persistentvolumeclaim "www-web-0" deleted
			[root@k8s-master1 /]# kubectl  get pv
			NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM               STORAGECLASS   REASON   AGE
			nfs01   10Gi       RWO            Retain           Released    default/www-web-2   nfs                     10d
			nfs04   1Gi        RWO            Retain           Available           			   nfs                     10d

		#手动回收
			[root@k8s-master1 /]# kubectl  edit pv nfs01			
			  claimRef:
			    apiVersion: v1
			    kind: PersistentVolumeClaim
			    name: www-web-2
			    namespace: default
			    resourceVersion: "76291"
			    uid: 2bd939eb-91fa-4456-98c3-1375753d69f7
			[root@k8s-master1 /]# kubectl  get pv
				NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
				nfs01   10Gi       RWO            Retain           Available           nfs                     10d
				nfs04   1Gi        RWO            Retain           Available           nfs                     10d

五、关于statefulset

	1、匹配pod-name(网络标识)的模式为:$(statefulset名称)-$(序号),比如上面的示例web-0,web-1
	2、statefulset:为每个pod副本创建一个dns域名,这个域名的格式为:$(podname).(headless servername),也意味着服务之间通过pod域名来通信而非pod ip,因为当pod所在Node发生故障时,pod会被漂移到其他的Node上,pod ip会发生改变,但pod域名不会有改变
	3、statefulset使用headless服务来控制pod的域名,这个域名的FQDN为:$(service name).$(namespace).svc.cluster.local,其中,‘cluster.local’指的是集群的域名
	4、根据volumeClainTemplates,为每个pod创建一个PVC,PvC的命名规则匹配模式:(columeClaimTemplates.name)-(pod_name),比如上面的volumeMounts.name=www,podname=web-[0-1],因为创建出来的PVC是www-web-0,www-web-1
	5、删除pod不会删除其PVC,手动删除PVC将自动释放PV
	6、statefulset的启停规则
		1)有序部署:部署statefulset时,如果有对个pod副本,它们会被顺序的创建(从0到N-1),并且在下一个pod运行之前,所有的pod必须都是Running和Read状态。
		2)有序删除:当pod被删除时,它们被终止的顺序是从N-1到0
		3)有序扩展:当pod执行扩展操作时,与部署一样,它前面的pod必须处于Running和Read状态
	7、statefulset
		1)稳定的持久化存储,即pod重新调度后还是能访问到相同的持久化数据,基于PVC来实现
		2)稳定的网络标识,即pod重新调度后其podname和hostname不变
		3)有序部署,有序扩展,基于init containers来实现
		4)有序收缩

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

H . C . Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值