赞
踩
声明:本文为《Kubernetes权威指南:从Docker到Kubernetes实践全接触(第5版)》的读书笔记
在上一篇博客《k8s教程(Volume篇)-PV详解》,我们了解了持久卷的工作原理,本文继续深入学习PVC。
PVC
作为用户对存储资源的需求申请,主要涉及存储空间请求、访问模式、 PV选择条件和存储类别等信息的设置。
下例声明的PVC具有如下属性:申请8GiB存储空间,访问模式为ReadWriteOnce,PV选择条件为包含release=stable标签并且包含条件为environment In[dev]的标签,存储类别为“slow”(要求在系统中已存在名为slow的StorageClass):
apiVersion: v1 kind: PersistentVolumeclaim metadata: name: myclaim spec: accessModes: - ReadWriteOnce volumeMode: Filesystem resources: requests: storage: 8Gi storageClassName: slow selector: matchLabels: release: "stable" matchExpressions: - {key: environment, operator: In, values: [dev]}
对PVC的关键配置参数说明如下:
资源请求(Resources):描述对存储资源的请求,通过 resources.requests.storage字段设置需要的存储空间大小。
访问模式 (Access Modes):PVC也可以设置访问模式,用于描述用户应用对存储资源的访问权限。其三种访问模式的设置与PV的设置相同。
存储卷模式(Volume Modes):PVC也可以设置存储卷模式,用于描述希望使用的PV存储卷模式,包括文件系统(Filesystem)和块设备 (Block) 。
PVC设置的存储卷模式应该与PV存储卷模式相同,以实现绑定,如果不同,则可能出现不同的绑定结果。在各种组合模式下是否可以绑定的结果如下图所示:
PV的存储卷模式 | PVC的存储卷模式 | 是否可以绑定 |
---|---|---|
未设定 | 未设定 | 可以绑定 |
未设定 | Block | 无法绑定 |
未设定 | FileSystem | 可以绑定 |
Block | 未设定 | 无法绑定 |
Block | Block | 可以绑定 |
Block | FileSystem | 无法绑定 |
FileSystem | FileSystem | 可以绑定 |
FileSystem | Block | 无法绑定 |
FileSystem | 未设定 | 可以绑定 |
PV选择条件 (Selector):通过Label Selector
的设置,可使PVC
对于系统中己存在的各种PV
进行筛选。系统将根据标签选出合适的PV
与该PVC
进行绑定。
对选择条件可以使用matchLabels
和matchExpressions
进行设置,如果两个字段都已设置,则Selector
的逻辑将是两组条件同时满足才能完成匹配。
存储类别(Class):PVC在定义时可以设定需要的后端存储的类别(通过storageClassName字段指定),以减少对后端存储特性的详细信息的依赖。只有设置了该Class
的PV
才能被系统选出,并与该PVC
进行绑定。
PVC
也可以不设置Class
需求,如果storageClassName
字段的值被设置为空 (storageClassName=""
),则表示该PVC
不要求特定的Class
,系统将只选择未设定Class
的PV
与之匹配和绑定。PVC
也可以完全不设置storageClassName
字段, 此时将根据系统是否启用了名为DefaultStorageClass
的admission controller
进行相应的操作。
启用DefaultStorageClass:要求集群管理员己定义默认的StorageClass。
未启用DefaultStorageClass:等效于PVC设置storageClassName的值为空(storageClassName=“),即只能选择未设定Class的PV与之匹配和绑定。
另外,如果PVC设置了Selector,则系统无法使用动态供给模式为其分配PV。
在PVC
创建成功之后,Pod
就可以以存储卷(Volume
)的方式使用PVC
的存储资源了。
PVC受限于命名空间,Pod在使用PVC时必须与PVC处于同一个命名空间。
Kubernetes为Pod挂载PVC的过程如下:系统在Pod所在的命名空间中找到其配置的PVC,然后找到PVC绑定的后端PV,将PV存储挂载到Pod所在Node的目录下,最后将Node的目录挂载到Pod的容器内。
在Pod中使用PVC时,需要在YAML配置中设置PVC类型的Volume,然后在容器中通过volumeMounts.mountPath设置容器内的挂载目录,示例如下:
apiversion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html"
name: mypd
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
如果存储卷模式为块设备(Block),则PVC的配置与默认模式 (Filesystem)略有不同,下面对如何使用裸块设备 (Raw Block Device) 进行说明。
假设使用裸块设备的PV已创建,例如:
apiVersion: V1
kind: PersistentVolume
metadata:
name: block-pv
spec:
capacity:
storage: 10Gi
accessModes:
- ReadwriteOnce
volumeMode: Block
persistentVolumeReclaimPolicy: Retain
fc:
targetWwNs: ["50060e801049cfa1"]
lun: 0
readOnly: false
PVC的YAML配置示例如下:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: block-pvc
spec:
accessModes:
- ReadWriteOnce
volumeMode: Block
resources:
requests:
storage: 10Gi
使用裸块设备PVC的Pod定义如下:
与文件系统模式PVC的用法不同,容器不使用volumeMounts设置挂载目录,而是通过volumeDevices字段设置块设备的路径devicePath
apiVersion: v1 kind: Pod metadata: name: pod-with-block-volume spec: containers: - name: fc-container image: fedora:26 conmand: ["/bin/sh", "-c"] args: ["tail -f /dev/nul1"] volumeDevices: - name: data devicePath: /dev/xvda volumes: - name: data persistentVolumeClaim: claimName: block-pvc
在某些应用场景中,同一个Volume可能会被多个Pod或者一个Pod中的多个容器共享,此时可能存在各应用程序需要使用不同子目录的需求。这可以通过Pod 的volumeMounts定义的subPath字段进行设置。通过对subPath的设置,在容器中将以subPath设置的目录而不是在Volume中提供的默认根目录作为根目录使用。
下面的两个容器共享同一个PVC(及后端PV),但是各自在Volume中可以访问的根目录由subPath进行区分,mysql容器使用Volume中的mysql子目录作为根目录,php容器使用Volume中的html子目录作为根目录:
apiVersion: v1 kind: Pod metadata: name: mysql spec: containers: - name: mysql image: mysql env: name: MY_SQL_ROOT_PASSWORD value: "rootpasswd" volumeMounts: - mountPath: /var/lib/mysql name: site-data subPath: mysql - name: php image: php:7.0-apache volumeMounts: - mountPath: /var/www/html name: site-data suoPath: html volumes: - name: site-data persistentVolumeClain: claimName: site-data-pvc
注意,subPath
中的路径名称不能以“/
”开头,需要用相对路径的形式。
在一些应用场景中,如果希望通过环境变量来设置
subPath
路径,例如使用Pod
名称作为子目录的名称,则可以通过subPathExpr
字段提供支持。subPathExpr
字段用于将Downward API
的环境变量设置为存储卷的子目录。需要注意的是,subPathExpr
字段和subPath
字段是互斥的,不能同时使用。
下面的例子通过Downward API
将Pod
名称设置为环境变量POD_NAME
,然后在挂载存储卷时设置subPathExpr=$ (POD_NAME)
子目录:
apiversion: v1 kind: Pod metadata: name: pod1 spec: containers: - name: container1 env: - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name image: busybox command: ["sh","-c", "while [true];do do echo 'Hello';sleep 10; done | tee -a /logs/hello .txt" ] volumeMounts: - name: workdir1 mountPath: /logs subPathExpr: $ (POD NAME) restartPolicy: Never volumes: - name: workdir1 hostPath: path: /var/log/pods
本文主要讲解了PVC,以及Pod使用PVC,希望能帮助到大家,谢谢大家的阅读,本文完!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。