Pvc持久卷

PVC存储:

存储卷工作原理:

  • 一个pod创建时,同时创建存储卷,根据类型访问定义好的存储类型
  • 存储卷需提前手动创建出来

image-20220729173432444

使用原理:

  • pod中创建存储卷
  • 容器绑定使用同一pod内的存储卷
  • pvc创建申请pv请求
  • 按工作逻辑,划分空间

存储类:

根据各种存储进行分类,如nfs分类为网络存储,硬盘分类为物理存储
存储类是对pv进行自动管理,无需再手动创建pv和pvc绑定,当pod申请pvc时,如果存储类空间满足,会通过存储类创建pv并绑定pvc
存储类只能在创建时设置类的名称和其他参数,创建后不能再更新。可以为不请求绑定任何特定存储类的 PVC 指定默认sc

文档: https://kubernetes.io/docs/concepts/storage/storage-classes/

配置语法:

kubectl explain sc

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
provisioner: 		#制备器(Provisioner),用来决定使用哪个卷插件制 PV。 该字段必须指定,每个不同的插件,参数可能不同
	#example.com/external-nfs,nfs存储插件,由于没有内置nfs插件,需额外部署使用:nfs-ganesha-server-and-external-provisioner插件,文档:https://github.com/kubernetes-sigs/nfs-ganesha-server-and-external-provisioner
	#nfs.csi.k8s.io,nfs-csi驱动提供,github安装:https://github.com/kubernetes-csi/csi-driver-nfs
	#kubernetes.io/gce-pd,GCE PD存储插件
	#kubernetes.io/aws-ebs,aws存储插件
	#kubernetes.io/cinder,openstack
	#kubernetes.io/rbd
	#kubernetes.io/no-provisioner,本地卷不支持动态配置,但可以实现延迟pvc绑定,WaitForFirstConsumer卷绑定模式时才能使用
parameters:		#provisioner可以接受不同的参数
  ---aws
  type: gp2		#硬盘类型,gp2和gp3为通用固态硬盘,默认为gp2,更多了解aws文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/EBSVolumeTypes.html
  	#io1 
    #gp2 
    #sc1 
    #st1
  iopsPerGB: "i/o操作数"	#仅适用于io1卷。每GiB每秒的I/O操作数。 AWS卷插件将此乘以请求卷的大小以计算卷的 IOPS并将其上限为20000 IOPS(AWS 支持的最大值,请参阅 AWS 文档)。字符串类型:"10"
  fsType: 文件系统		#默认ext4,必须是当前系统支持的
  encrypted: 布尔值字符串	#是否进行加密,字符串类型:"true"
  ---nfs---
  server: nfs主机
  path: 共享路径
  readOnly: "true"		#默认false只读挂载
  ---openstack
  availability: nova
  ---ceph-rbd
  monitors: ip:6789,ip2:port 	#Ceph 监视器字符串,多个用","分隔
  adminId: admin	#可在存储池中创建图像的Ceph管理员
  adminSecretName: ceph-admin-secret	#secret名称。此参数是必需的。提供的秘密必须具有类“kubernetes.io/rbd”
  adminSecretNamespace: ceph		#adminSecretName的命名空间。默认为“默认”
  pool: k8s-rbd			#Ceph RBD 池。默认为“rbd”
  userId: k8s-user		#ceph普通用户,客户端挂载使用此
  userSecretName: ceph-user		#secret名称
  userSecretNamespace: default
  fsType: ext4			#文件系统类型,默认ext4
  imageFormat: "2"		#Ceph RBD 镜像格式,“1”或“2”。默认值为“2”
  imageFeatures: "layering"		#rbd启用新特性,参数可选,仅当将imageFormat设置为“2”时才使用。目前仅支持有 layering 。默认为“”,不开启任何功能
reclaimPolicy: 回收策略
	#Retain,保留
	#Delete,删除
allowVolumeExpansion: 布尔值	#true时,允许用户通过编辑相应的 PVC 对象来调整卷的大小,只能增大,不能缩小
mountOptions:	#指定pv选项,挂载选项无效会导致挂载失败
  - debug
volumeBindingMode: 模式 		#控制何时应该进行卷绑定和动态配置。未设置时,默认使用立即配置模式
	#Immediate,表示一旦创建pvc就进行卷绑定和动态配置。对于拓扑受限且无法从集群中的所有节点全局访问的存储后端,PersistentVolumes将在不知道Pod的调度要求的情况下被绑定或配置。这可能会导致不可调度的Pod
	#WaitForFirstConsumer,可解决上面问题,延迟pv的绑定和配置,直到有pod要使用pvc时再创建创建。pv将根据Pod的调度约束指定的拓扑来选择或配置。这些包括但不限于资源要求、节点选择器、pod亲和力和反亲和力以及污点和容忍度
	这些插件支持该模式动态配置:
		AWSElasticBlockStore AWSElasticBlockStore
		GCEPersistentDisk
		AzureDisk
	静态配置(创建时就指定):
		Local
		上面所有
allowedTopologies: 		#WaitForFirstConsumer卷绑定模式时的额外配置,可选项
- matchLabelExpressions:	#如配置标签选择器

注意:如果卷绑定模式使用 WaitForFirstConsumer ,不能在pod定义中使用 nodeName 来指定节点亲和性。会导致调度器将被绕过,PVC 将保持在 pending 状态,应该使用节点选择器来实现类似的功能

apiVersion: v1
kind: Pod
spec:
  nodeSelector:
    kubernetes.io/hostname: kube-01

pvc资源:

pvc是不属于集群资源,只能在namespace中使用

pvc动态空集:

  • pod创建时,指定要用的空间,pvc去存储类中申请空间,存储类根据pod需要的pvc大小自动分配其刚好满足条件的pv(空间)
  • 存储类是一个抽象层,是存储设备的抽象化,把所有存储放在存储类中定义
  • pvc对存储和使用进行了解耦,pvc在pod中定义,pv在pod外用于绑定存储,存储是自己准备,如硬盘、nfs等。访问时pv自动根据pvc的需求创建空间,不在关注存储,只需关注pvc容量(类似lvm,只需关注lvm,不用关注vg)
  • 动态pvc对存储有很高的要求,glusterfs、ceph等支持

pvc与pv的关系:

  • pvc使用一个pv时,pv就处于绑定状态,不能再提供给其他pvc使用
  • 但一个pvc可以为多个pod提供使用

配置语法:

kubectl explain pvc.spec

kind: persistentvolumeclaims
spec:
	accessModes <[]string>		#访问模型,必须能先满足pv的访问模型
	dataSource <Object>
 	resources <Object>		#资源限制,最少使用多少
 		requests:			#需要的最小资源
  	storage: 大小		#数据卷的大小
  selector			#对pv的标签选择器
 		matchExpressions: 	#正则匹配
			matchLabels:			#用于匹配pv的标签
				name: value
				...
  storageClassName <string>		#存储类名称
  volumeMode <string>		#存储卷的模式,允许使用哪些类型的卷
  volumeName <string>		#存储卷名称,精确匹配,允许使用哪些卷

pv资源:

pv的定义与普通存储卷是一样的,包括大部分方法
​pv属于集群资源,可以给所有资源使用,所以不能定义在namespace中

创建方式:

  • 静态,手动创建pv,绑定pvc
  • 动态,通过定义存储类,自动创建pv

pv不同存储支持的访问模型:

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

pv数据回收策略:

  • 保留(Retain),pod删除,数据保留
  • 回收(Recycle),数据清空,保持空闲状态
  • 删除(Delete),pv删除

配置语法:

kubectl explain pv.spec

kind: persistentvolumes
spec:
	accessModes	<[]string>				#pv访问模型
	  	#ReadWriteOnce,简写:RWO,单节点读写
			#ReadOnlyMany,简写:ROX,多节点只读
			#ReadWriteMany,简写:RWX,多节点读写
  		#ReadWriteOncePod,简写:RWOP,单pod读写,仅支持CSI接口和k8s-1.22版本以上
	capacity <map[string]string>	#pv大小
		storage: 大小		
  		#单位Ki、Mi、Gi、Ti、Pi、Ei按1024计算
		  #单位m、k、M、G、T、P、E按1000计算
	persistentVolumeReclaimPolicy: 回收策略			#前提条件是,底层存储支持这些策略:https://kubernetes.io/docs/concepts/storage/persistent-volumes#reclaiming
	  #Retain,手动创建的pv,不再用时默认用此
	  #Delete,动态配置的pv,不再用时默认用此

案例:

例1: 基于nfs,创建pv、pvc

1)安装nfs,配置nfs

yum install -y nfs-utils
mkdir -p /data/nfs
echo '/data/nfs 2.2.0.0/16(rw,no_root_squash)' >> /etc/exports
exportfs -av

2)添加nfs到pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
  labels:
    pv: nfs-pv
spec:
  nfs:
    server: 2.2.2.10
    path: /data/nfs
  accessModes: 
    - ReadWriteMany
    - ReadOnlyMany
  capacity:
    storage: 1Gi

3)创建pvc,pod中挂载pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
  labels:
    pvc: nfs-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 100Mi

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: ngx-dep
spec:
  replicas: 2
  selector:
    matchLabels:
      app: ngx-dep
  template:
    metadata:
      labels:
        app: ngx-dep
    spec:
      volumes:
        - name: web
          persistentVolumeClaim:
            claimName: nfs-pvc
      containers:
        - name: ngx
          image: nginx
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
          volumeMounts:
            - name: web
              mountPath: /usr/share/nginx/html
例2: 基于nfs,用deployment控制器部署zk集群

1)准备nfs

mkdir -p /data/nfs/zk-{1..3}
echo '/data/nfs 2.2.0.0/16(rw,no_root_squash)' > /etc/exports
systemctl enable --now nfs
showmount -e 127.0.0.1

2)创建pv

apiVersion: v1
kind: PersistentVolume
metadata:
  name: zk-pv-1
spec:
  capacity:
    storage: 2Gi
  accessModes: 
    - ReadWriteOnce
  nfs:
    path: /data/nfs/zk-1
    server: 2.2.2.30

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: zk-pv-2
spec:
  capacity:
    storage: 2Gi
  accessModes: 
    - ReadWriteOnce
  nfs:
    path: /data/nfs/zk-2
    server: 2.2.2.30

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: zk-pv-3
spec:
  capacity:
    storage: 2Gi
  accessModes: 
    - ReadWriteOnce
  nfs:
    path: /data/nfs/zk-3
    server: 2.2.2.30

3)创建pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zk-pvc-1
spec:
  volumeName: zk-pv-1
  accessModes: 
    - ReadWriteOnce
  resources: 
    requests:
      storage: 2Gi

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zk-pvc-2
spec:
  volumeName: zk-pv-2
  accessModes: 
    - ReadWriteOnce
  resources: 
    requests:
      storage: 2Gi

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: zk-pvc-3
spec:
  volumeName: zk-pv-3
  accessModes: 
    - ReadWriteOnce
  resources: 
    requests:
      storage: 2Gi

4)创建svc

apiVersion: v1
kind: Service
metadata:
  name: zk-svc-1
spec:
  selector:
    app: zk
    server-id: "1"
  type: NodePort
  ports:
    - name: client
      port: 2181
      nodePort: 31000
    - name: followers
      port: 2888
      nodePort: 31001
    - name: election
      port: 3888
      nodePort: 31002
    - name: admin
      port: 8080
      nodePort: 31003
---
apiVersion: v1
kind: Service
metadata:
  name: zk-svc-2
spec:
  selector:
    app: zk
    server-id: "2"
  type: NodePort
  ports:
    - name: client
      port: 2181
      nodePort: 32000
    - name: followers
      port: 2888
      nodePort: 32001
    - name: election
      port: 3888
      nodePort: 32002
    - name: admin
      port: 8080
      nodePort: 32003
---
apiVersion: v1
kind: Service
metadata:
  name: zk-svc-3
spec:
  selector:
    app: zk
    server-id: "3"
  type: NodePort
  ports:
    - name: client
      port: 2181
      nodePort: 33000
    - name: followers
      port: 2888
      nodePort: 33001
    - name: election
      port: 3888
      nodePort: 33002
    - name: admin
      port: 8080
      nodePort: 33003

5)使用deploy控制器创建zk集群

apiVersion: apps/v1
kind: Deployment
metadata:
  name: zk-1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zk
  template:
    metadata:
      labels:
        app: zk
        server-id: "1"
    spec:
      volumes:
        - name: wal
          emptyDir:
            medium: Memory
        - name: zk-pvc-data
          persistentVolumeClaim:
            claimName: zk-pvc-1
      containers:
        - name: zk
          image: zookeeper:3.4.14
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 2181
            - containerPort: 2888
            - containerPort: 3888
            - containerPort: 8080
          env:
            - name: ZOO_MY_ID
              value: "1"
            - name: ZOO_SERVERS
              value: "server.1=0.0.0.0:2888:3888 server.2=zk-svc-2:2888:3888 server.3=zk-svc-3:2888:3888"
            - name: JVMFLAGS
              value: "-Xmx300M"
          volumeMounts:
            - name: zk-pvc-data
              mountPath: /data

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: zk-2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zk
  template:
    metadata:
      labels:
        app: zk
        server-id: "2"
    spec:
      volumes:
        - name: wal
          emptyDir:
            medium: Memory
        - name: zk-pvc-data
          persistentVolumeClaim:
            claimName: zk-pvc-2
      containers:
        - name: zk
          image: zookeeper:3.4.14
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 2181
            - containerPort: 2888
            - containerPort: 3888
            - containerPort: 8080
          env:
            - name: ZOO_MY_ID
              value: "2"
            - name: ZOO_SERVERS
              value: "server.1=zk-svc-1:2888:3888 server.2=0.0.0.0:2888:3888 server.3=zk-svc-3:2888:3888"
            - name: JVMFLAGS
              value: "-Xmx300M"
          volumeMounts:
            - name: zk-pvc-data
              mountPath: /data

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: zk-3
spec:
  replicas: 1
  selector:
    matchLabels:
      app: zk
  template:
    metadata:
      labels:
        app: zk
        server-id: "3"
    spec:
      volumes:
        - name: wal
          emptyDir:
            medium: Memory
        - name: zk-pvc-data
          persistentVolumeClaim:
            claimName: zk-pvc-3
      containers:
        - name: zk
          image: zookeeper:3.4.14
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 2181
            - containerPort: 2888
            - containerPort: 3888
            - containerPort: 8080
          env:
            - name: ZOO_MY_ID
              value: "3"
            - name: ZOO_SERVERS
              value: "server.1=zk-svc-1:2888:3888 server.2=zk-svc-2:2888:3888 server.3=0.0.0.0:2888:3888"
            - name: JVMFLAGS
              value: "-Xmx300M"
          volumeMounts:
            - name: zk-pvc-data
              mountPath: /data
posted @ 2022-09-02 15:57  suyanhj  阅读(130)  评论(0)    收藏  举报