Kubernetes持久卷怎么使用

61次阅读
没有评论

共计 8489 个字符,预计需要花费 22 分钟才能阅读完成。

本篇内容主要讲解“Kubernetes 持久卷怎么使用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让丸趣 TV 小编来带大家学习“Kubernetes 持久卷怎么使用”吧!

Volume 卷

Container 中的文件在磁盘上是临时存放的,这给 Container 中运行的较重要的应用程序带来一些问题:

1. 当容器崩溃时,kubelet 会重新启动容器,但容器会以干净的状态重启,造成文件的丢失。

2.Pod 中运行多个容器时,希望能在多个容器中共享文件。

因此 Kubernetes 使用了卷(Volume)这一抽象概念能够来解决这两个问题。Kubernetes 支持下列类型的卷:

hostpath:将主机节点文件系统上的文件或目录挂载到你的 Pod 中。

emptyDir: 当 Pod 分派到某个 Node 上时,emptyDir 卷会被创建,并且在 Pod 在该节点上运行期间,卷一直存在。就像其名称表示的那样,卷最初是空的。Pod 中的多个容器可以共享 emptyDir 卷中的文件。当 Pod 因为某些原因被从节点上删除时,emptyDir 卷中的数据也会被永久删除。容器崩溃并不会导致 Pod 被从节点上移除,因此容器崩溃期间 emptyDir 卷中的数据是安全的。

Persistent Volume:persistentVolumeClaim 卷用来将持久卷(PersistentVolume)挂载到 Pod 中。持久卷申领(PersistentVolumeClaim)是用户在不知道特定云环境细节的情况下 申领 持久存储(例如 NFS,iSCSI)的一种方法。

Persistent Volume 持久卷

本文主要介绍持久卷的使用。Kubernetes 为了使开发人员能够在请求存储资源时,避免处理存储设施细节,引入了持久卷(PersistentVolume,PV)和 持久卷申领(PersistentVolumeClaim,PVC):

持久卷(PersistentVolume,PV 是集群中的一块存储,可以由管理员事先供应,或者 使用存储类(Storage Class)来动态供应。持久卷是集群资源,就像节点也是集群资源一样。PV 持久卷和普通的 Volume 一样,也是使用 卷插件来实现的,只是它们拥有独立于任何使用 PV 的 Pod 的生命周期。此 API 对象中记述了存储的实现细节,无论其背后是 NFS、iSCSI 还是特定于云平台的存储系统。

持久卷申领(PersistentVolumeClaim,PVC 表达的是用户对存储的请求。概念上与 Pod 类似。Pod 会耗用节点资源,而 PVC 申领会耗用 PV 资源。Pod 可以请求特定数量的资源(CPU 和内存);同样 PVC 申领也可以请求特定的大小和访问模式(例如,可以要求 PV 卷能够以 ReadWriteOnce、ReadOnlyMany 或 ReadWriteMany 模式之一来挂载)。

创建 PV 有两种方式:

静态供应:一种是集群管理员通过手动方式静态创建应用所需要的 PV。

动态供应:

方式一:用户手动创建 PVC 并由 Provisioner 组件动态创建对应的 PV。

方式二:在创建 Pod 的时候使用 volumeClaimTemplates 声明。

PV 回收策略

保留(Retain)保留策略允许手动回收资源,当删除 PVC 的时候,PV 仍然存在,变为 Realease 状态,需要用户手动通过以下步骤回收卷(只有 hostPath 和 nfs 支持 Retain 回收策略):

1. 删除 PV。

2. 手动清理存储的数据资源。

回收(Resycle)该策略已废弃,推荐使用 dynamic provisioning,回收策略会在 volume 上执行基本擦除(rm -rf /thevolume/*),可被再次声明使用。

删除(Delete)

当发生删除操作的时候,会从 Kubernetes 集群中删除 PV 对象,并执行外部存储资源的删除操作(根据不同的 provisioner 定义的删除逻辑不同,有的是重命名而不是删除)。

动态配置的卷继承其 StorageClass 的回收策略,默认为 Delete,即当用户删除 PVC 的时候,会自动执行 PV 的删除策略。

访问模式

访问模式有:

ReadWriteOnce — 卷可以被一个节点以读写方式挂载;

ReadOnlyMany — 卷可以被多个节点以只读方式挂载;

ReadWriteMany — 卷可以被多个节点以读写方式挂载。

在命令行接口(CLI)中,访问模式也使用以下缩写形式:

RWO — ReadWriteOnce

ROX — ReadOnlyMany

RWX — ReadWriteMany

每个卷只能同一时刻只能以一种访问模式挂载,即使该卷能够支持 多种访问模式。例如,一个 GCEPersistentDisk 卷可以被某节点以 ReadWriteOnce 模式挂载,或者被多个节点以 ReadOnlyMany 模式挂载,但不可以同时以两种模式挂载。

卷绑定模式

volumeBindingMode 字段控制了 PVC 和 PV 在什么时候进行绑定。

Immediate:表示一旦创建了 PVC 也就完成了卷绑定和动态制备。对于由于拓扑限制而非集群所有节点可达的存储后端,PV 会在不知道 Pod 调度要求的情况下绑定或者制备。

WaitForFirstConsumer:该模式将延迟 PV 的绑定和制备,直到使用该 PVC 的 Pod 被创建。PV 会根据 Pod 调度约束指定的拓扑来选择或制备,包括但不限于 资源需求、节点筛选器、pod 亲和性和互斥性、以及污点和容忍度。

静态供应

静态供应需要管理员手动创建 PV,然后创建 PVC 绑定 PV,最后创建 Pod 声明使用 PVC。

创建 PV

apiVersion: v1
kind: PersistentVolume
metadata:
 name: task-pv-volume
 labels:
 type: local
spec:
 storageClassName: manual # 静态供应,名字可以任意取
 capacity:
 storage: 10Gi
 accessModes:
 - ReadWriteOnce
 hostPath:
 path:  /mnt/data  # 在创建 pod 的节点上会新建该目录 

创建 PVC

fapiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: task-pv-claim
spec:
 storageClassName: manual #storageClassName 要和 PV 中的一致
 accessModes:
 - ReadWriteOnce #accessMode 要和 PV 中的一致
 resources:
 requests:
 storage: 3Gi # 申请 3G 容量,申请就近原则,如果有一个 10G 的和一个 20G 的 PV 满足要求,那么使用 10G 的 PV

创建 Pod 挂载 PV

apiVersion: v1
kind: Pod
metadata:
 name: task-pv-pod
spec:
 volumes:
 - name: task-pv-storage
 persistentVolumeClaim:
 claimName: task-pv-claim # 使用的 PVC 的名字
 containers:
 - name: task-pv-container
 image: nginx
 ports:
 - containerPort: 80
 name:  http-server 
 volumeMounts:
 - mountPath:  /usr/share/nginx/html  # 容器中挂载的目录
 name: task-pv-storage

在宿主机上的目录创建一个文件:

root@worker01:~# cd /mnt/data/
root@worker01:/mnt/data# echo  volume nginx    index.html

尝试访问 Pod 的服务,可以看到 nginx 的 index.html 文件已经被修改:

root@master01:~/yaml/volume# kubectl get pod -o wide 
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
task-pv-pod 1/1 Running 0 11m 192.168.5.17 worker01  none   none 
root@master01:~/yaml/volume# curl 192.168.5.17
volume nginx

删除要按照 Pod– PVC– PV 的顺序删除,如果先删除了 PVC 会等 Pod 删除掉,才会删除 PVC,如果先删除了 PV,会等 pod 和 PVC 删除了才会删除 PV。

动态供应

动态卷供应允许按需创建存储卷。如果没有动态供应,集群管理员必须手动地联系他们的云或存储提供商来创建新的存储卷,然后在 Kubernetes 集群创建 PersistentVolume 对象来表示这些卷。动态供应功能消除了集群管理员预先配置存储的需要。相反,它在用户请求时自动供应存储。

安装 NFS 安装 NFS 服务端

root@master01:/# apt-get -y install nfs-kernel-server 
root@master01:/# systemctl enable nfs-kernel-server.service   systemctl restart nfs-kernel-server.service

安装 NFS 客户端

在 worker 节点安装 NFS 客户端:

root@worker01:~# apt-get -y install nfs-common

配置存储插件配置 RBAC

apiVersion: v1
kind: ServiceAccount
metadata:
 name: nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: nfs-client-provisioner-runner
rules:
 - apiGroups: [ ]
 resources: [persistentvolumes]
 verbs: [get ,  list ,  watch ,  create ,  delete]
 - apiGroups: [ ]
 resources: [persistentvolumeclaims]
 verbs: [get ,  list ,  watch ,  update]
 - apiGroups: [storage.k8s.io]
 resources: [storageclasses]
 verbs: [get ,  list ,  watch]
 - apiGroups: [ ]
 resources: [events]
 verbs: [create ,  update ,  patch]
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: run-nfs-client-provisioner
subjects:
 - kind: ServiceAccount
 name: nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
roleRef:
 kind: ClusterRole
 name: nfs-client-provisioner-runner
 apiGroup: rbac.authorization.k8s.io
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: leader-locking-nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
rules:
 - apiGroups: [ ]
 resources: [endpoints]
 verbs: [get ,  list ,  watch ,  create ,  update ,  patch]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
 name: leader-locking-nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
subjects:
 - kind: ServiceAccount
 name: nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
roleRef:
 kind: Role
 name: leader-locking-nfs-client-provisioner
 apiGroup: rbac.authorization.k8s.io

部署存储插件

动态卷供应的实现基于 storage.k8s.io API 组中的 StorageClass API 对象。集群管理员可以根据需要定义多个 StorageClass 对象,每个对象指定一个存储插件(又名 provisioner),存储插件以 Pod 的形式存在于 Kubernetes 集群中:

apiVersion: apps/v1
kind: Deployment
metadata:
 name: nfs-client-provisioner
 labels:
 app: nfs-client-provisioner
 # replace with namespace where provisioner is deployed
 namespace: default
spec:
 replicas: 1
 strategy:
 type: Recreate
 selector:
 matchLabels:
 app: nfs-client-provisioner
 template:
 metadata:
 labels:
 app: nfs-client-provisioner
 spec:
 serviceAccountName: nfs-client-provisioner
 containers:
 - name: nfs-client-provisioner
 image: quay.io/external_storage/nfs-client-provisioner:latest
 volumeMounts:
 - name: nfs-client-root
 mountPath: /persistentvolumes
 env:
 #  指定标识插件的值
 - name: PROVISIONER_NAME
 value: fuseim.pri/ifs # 匹配 StorageClass 的 provisioner
 - name: NFS_SERVER
 value: 10.0.1.31 #NFS 服务器的 ip 地址
 - name: NFS_PATH
 value: /storage #NFS 服务器的路径
 volumes:
 - name: nfs-client-root
 nfs:
 server: 10.0.1.31 #NFS 服务器的 ip 地址
 path: /storage #NFS 服务器的路径 

方式一:创建 PVC 自动申请 PV 配置 StorageClass

StorageClass 声明存储插件,用于自动创建 PV,provisioner 参数和存储插件的标识对应上才能动态供应卷:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
 name: managed-nfs-storage
provisioner: fuseim.pri/ifs # 要匹配 nfs deployment env PROVISIONER_NAME 的值,默认不支持 nfs 存储需要添加插件标识
parameters:
 archiveOnDelete:  false

创建 PVC

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: nginx-pv-storage
spec:
 accessModes:
 - ReadWriteMany
 storageClassName: managed-nfs-storage
 resources:
 requests:
 storage: 1Gi

查看创建的 PVC 和 PV,可以看到我们只创建了 PVC,PV 是存储插件自动配置的

root@master01:~/yaml/storageClass# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nginx-pv-storage Bound pvc-e52ac960-182a-4065-a6e8-6957f5c93b8a 1Gi RWX managed-nfs-storage 3s
root@master01:~/yaml/storageClass# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-e52ac960-182a-4065-a6e8-6957f5c93b8a 1Gi RWX Delete Bound default/nginx-test managed-nfs-storage 11s

Pod 使用 PVC 申请 Volume:

apiVersion: v1
kind: Pod
metadata:
 name: nginx-pv-pod
spec:
 volumes:
 - name: nginx-pv-storage
 persistentVolumeClaim:
 claimName: nginx-test
 containers:
 - name: nginx-pv-container
 image: nginx
 ports:
 - containerPort: 80
 name:  nginx-server 
 volumeMounts:
 - mountPath:  /usr/share/nginx/html 
 name: nginx-pv-storage

方式二:volumeClaimTemplates

除了上面创建 PVC 自动创建 PV,然后 Pod 再声明使用 PVC 的方式以外,还有一个更简便的方法,就是使用 volumeClaimTemplates 直接指定 StorageClass 和 申请存储的大小,动态创建 PVC 和 PV:

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
 ports:
 - containerPort: 80
 name: web
 volumeMounts:
 - name: nginx-disk-ssd
 mountPath: /data
 volumeClaimTemplates:
 - metadata:
 name: nginx-disk-ssd
 spec:
 accessModes: [  ReadWriteOnce  ]
 storageClassName:  managed-nfs-storage  #storageClass 的名字
 resources:
 requests:
 storage: 10Gi

到此,相信大家对“Kubernetes 持久卷怎么使用”有了更深的了解,不妨来实际操作一番吧!这里是丸趣 TV 网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计8489字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)