Kubernetes 存储卷管理 PV&PVC(十)

为了持久化保存容器的数据,可以使用 Kubernetes Volume。

Volume 的生命周期独立于容器,Pod 中的容器可能被销毁和重建,但 Volume 会被保留。

本质上,Kubernetes Volume 是一个目录,这一点与 Docker Volume 类似。当 Volume 被 mount 到 Pod,Pod 中的所有容器都可以访问这个 Volume。Kubernetes Volume 也支持多种 backend 类型,包括 emptyDir、hostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、Ceph 等,完整列表可参考 https://kubernetes.io/docs/concepts/storage/volumes/#types-of-volumes

一、emptyDir

emptyDir 是最基础的 Volume 类型。正如其名字所示,一个 emptyDir Volume 是 Host 上的一个空目录。

emptyDir Volume 对于容器来说是持久的,对于 Pod 则不是。当 Pod 从节点删除时,Volume 的内容也会被删除。但如果只是容器被销毁而 Pod 还在,则 Volume 不受影响。

也就是说:emptyDir Volume 的生命周期与 Pod 一致。

Pod 中的所有容器都可以共享 Volume,它们可以指定各自的 mount 路径。下面通过例子来实践 emptyDir,配置文件如下:

apiVersion: v1
kind: Pod
metadata:
  name: producer-consumer
spec:
  containers:
  - name: producer
    image: busybox
    volumeMounts:
    - name: shared-volume
      mountPath: /producer_dir
    args:
    - /bin/sh
    - -c
    - echo "hello world" > /producer_dir/hello; sleep 30000
  - name: consumer
    image: busybox
    volumeMounts:
    - name: shared-volume
      mountPath: /consumer_dir
    args:
    - /bin/sh
    - -c
    - cat /consumer_dir/hello; sleep 30000
  volumes:
  - name: shared-volume
    emptyDir: {}

这里我们模拟了一个 producer-consumer 场景。Pod 有两个容器 producer和 consumer,它们共享一个 Volume。producer 负责往 Volume 中写数据,consumer 则是从 Volume 读取数据。

  • 文件最底部 volumes 定义了一个 emptyDir 类型的 Volume shared-volume。
  • producer 容器将 shared-volume mount 到 /producer_dir 目录。
  • producer 通过 echo 将数据写到文件 hello 里。
  • consumer 容器将 shared-volume mount 到 /consumer_dir 目录。
  • consumer 通过 cat 从文件 hello 读数据。

执行如下命令创建 Pod:

[[email protected] ~]# kubectl apply -f emptydir.yaml
pod/producer-consumer created
[[email protected] ~]# kubectl get pods
NAME                READY   STATUS    RESTARTS   AGE
producer-consumer   2/2     Running   0          8s
[[email protected] ~]# kubectl logs producer-consumer consumer
hello world

kubectl logs 显示容器 consumer 成功读到了 producer 写入的数据,验证了两个容器共享 emptyDir Volume。

emptyDir 是 Host 上创建的临时目录,其优点是能够方便地为 Pod 中的容器提供共享存储,不需要额外的配置。但它不具备持久性,如果 Pod 不存在了,emptyDir 也就没有了。根据这个特性,emptyDir 特别适合 Pod 中的容器需要临时共享存储空间的场景,比如前面的生产者消费者用例。

二、hostPath

hostPath Volume 的作用是将 Docker Host 文件系统中已经存在的目录 mount 给 Pod 的容器。大部分应用都不会使用 hostPath Volume,因为这实际上增加了 Pod 与节点的耦合,限制了 Pod 的使用。不过那些需要访问 Kubernetes 或 Docker 内部数据(配置文件和二进制库)的应用则需要使用 hostPath。

下面的例子,我们把主机上的目录/data/pod/v1挂载到 Pod 上容器的/usr/share/nginx/html/

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostPath
spec:
  containers:
  - name: mytest
    image: wangzan18/mytest:v1
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    hostPath:
      path: /data/pod/v1
      type: DirectoryOrCreate

如果 Pod 被销毁了,hostPath 对应的目录也还会被保留,从这点看,hostPath 的持久性比 emptyDir 强。不过一旦 Host 崩溃,hostPath 也就没法访问了。

三、PV & PVC

Volume 提供了非常好的数据持久化方案,不过在可管理性上还有不足。

拿前面 AWS EBS 的例子来说,要使用 Volume,Pod 必须事先知道如下信息:

  • 当前 Volume 来自 AWS EBS。
  • EBS Volume 已经提前创建,并且知道确切的 volume-id。

Pod 通常是由应用的开发人员维护,而 Volume 则通常是由存储系统的管理员维护。开发人员要获得上面的信息:

  • 要么询问管理员。
  • 要么自己就是管理员。

这样就带来一个管理上的问题:应用开发人员和系统管理员的职责耦合在一起了。如果系统规模较小或者对于开发环境这样的情况还可以接受。但当集群规模变大,特别是对于生成环境,考虑到效率和安全性,这就成了必须要解决的问题。

Kubernetes 给出的解决方案是 PersistentVolumePersistentVolumeClaim

PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。

PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。

有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。

Kubernetes 支持多种类型的 PersistentVolume,比如 AWS EBS、Ceph、NFS 等,完整列表请参考 https://kubernetes.io/docs/concepts/storage/persistent-volumes/#types-of-persistent-volumes

下节我们用 NFS 来体会 PersistentVolume 的使用方法。

1、NFS PersistentVolume

作为准备工作,我们已经在 node3 节点上搭建了一个 NFS 服务器,输出三个目录:

[[email protected] ~]# showmount -e localhost
Export list for localhost:
/data/volumes/pv003 192.168.1.0/24
/data/volumes/pv002 192.168.1.0/24
/data/volumes/pv001 192.168.1.0/24

下面创建PV,配置文件 nfs-pv.yaml 如下:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 1Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /data/volumes/pv001
    server: 192.168.1.203
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteMany
  nfs:
    path: /data/volumes/pv002
    server: 192.168.1.203
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
spec:
  capacity:
    storage: 10Gi
  accessModes:
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Recycle
  nfs:
    path: /data/volumes/pv003
    server: 192.168.1.203

accessModes 指定访问模式为 ReadWriteOnce,支持的访问模式有:

  • ReadWriteOnce – PV 能以 read-write 模式 mount 到单个节点。
  • ReadOnlyMany – PV 能以 read-only 模式 mount 到多个节点。
  • ReadWriteMany – PV 能以 read-write 模式 mount 到多个节点。

persistentVolumeReclaimPolicy 指定当 PV 的回收策略为 Recycle,支持的策略有:

  • Retain – 需要管理员手工回收。
  • Recycle – 清除 PV 中的数据,效果相当于执行 rm -rf /thevolume/*
  • Delete – 删除 Storage Provider 上的对应存储资源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

创建我们刚刚做好的PV。

[[email protected] ~]# kubectl apply -f nfs-pv.yaml
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWX            Retain           Available                                   6s
pv002   5Gi        RWX            Retain           Available                                   6s
pv003   10Gi       RWX            Recycle          Available                                   6s

2、创建 PVC

创建配置文件nfs-pvc.yaml,修改内容如下:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc001
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

创建 PVC。

[[email protected] ~]# kubectl apply -f nfs-pvc.yaml
persistentvolumeclaim/pvc001 created
[[email protected] ~]# kubectl get pvc
[[email protected] ~]# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
pvc001   Bound    pv001    1Gi        RWX                           9s
[[email protected] ~]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM            STORAGECLASS   REASON   AGE
pv001   1Gi        RWX            Retain           Bound       default/pvc001                           2m7s
pv002   5Gi        RWX            Retain           Available                                            2m7s
pv003   10Gi       RWX            Recycle          Available                                            2m7s

3、创建 Pod 进行挂载

创建 pod 配置文件nfs-pvc-pod.yaml,内容如下:

apiVersion: v1
kind: Pod
metadata:
  name: mypod1
spec:
  containers:
  - name: mypod1
    image: busybox
    args:
    - /bin/sh
    - -c
    - sleep 30000
    volumeMounts:
    - name: mydata
      mountPath: "/mydata"
  volumes:
  - name: mydata
    persistentVolumeClaim:
      claimName: pvc001

创建pod。

[[email protected] ~]# kubectl apply -f nfs-pvc-pod.yaml
pod/mypod1 created
[[email protected] ~]# kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
mypod1   1/1     Running   0          17m   10.244.1.16   node01   <none>           <none>

验证 PV 是否可用:

[[email protected] ~]# kubectl exec mypod1 touch /mydata/hello

然后在node3服务器上面查看。

[[email protected] pv001]# ll
-rw-r--r-- 1 root root 0 12月 13 19:39 hello

可见,在 Pod 中创建的文件 /mydata/hello 确实已经保存到了 NFS 服务器目录 /data/volumes/pv001 中。

原文地址:http://blog.51cto.com/wzlinux/2330159

时间: 2024-10-03 09:12:42

Kubernetes 存储卷管理 PV&PVC(十)的相关文章

Kubernetes 学习12 kubernetes 存储卷

一.概述 1.我们此前讲过根据应用本身是否需要持久存储数据以及某一次请求和之前的请求是否有联系,可以分为四类应用 a.有状态,要存储 b.有状态,无持久存储 c.无状态,要存储 d.无状态,无持久存储 其中,大多数和数据存储服务相关的应用和有状态应用几乎都是需要持久存储数据的.在docker中说过,容器有生命周期,为了使容器将来终结以后可以把其删除,甚至是编排到其它节点上去运行,意味着我们数据不能放在容器本地,不能放在容器自己的名称空间中.注意这是两套逻辑,以k8s为例,pod运行时应该是运行在

逻辑卷管理PV/VG/LV RAID

  如何搭建 & 扩容 LVM PV就是硬盘分区 VG是硬盘分区的集合 LV是VG的部分空间 [[email protected] dev]# pvcreate /dev/sdd1 /dev/sdd4 /dev/sdd5 /dev/sdd6 /dev/sdd7 WARNING: ext4 signature detected on /dev/sdd1 at offset 1080. Wipe it? [y/n] y Wiping ext4 signature on /dev/sdd1. Phys

Kubernetes之(十二)存储卷

目录 Kubernetes之(十二)存储卷 简介 emptyDir存储卷 hostPath存储卷 nfs共享存储卷 PV和PVC NFS使用PV和PVC 配置NFS存储 定义PV 定义PVC 查看验证 测试访问 StorageClass Kubernetes之(十二)存储卷 简介 为了保证数据的持久性,必须保证数据在外部存储在docker容器中,为了实现数据的持久性存储,在宿主机和容器内做映射,可以保证在容器的生命周期结束,数据依旧可以实现持久性存储.但是在k8s中,由于pod分布在各个不同的节

Kubernetes之存储卷

存储卷概述 容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题.首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失--容器以干净的状态(镜像最初的状态)重新启动.其次,在 Pod 中同时运行多个容器时,这些容器之间通常需要共享文件.Kubernetes 中的 Volume 抽象就很好的解决了这些问题.在原docker环境中也有存储卷的概念,但docker环境的存储卷调度在宿主机上的目录,当docker重新创建的时候存储卷还会挂载统一宿主机上,但我们

kubernetes pv pvc configmap secret 使用

pv pvc使用 1.概述,我们可以这样来组织我们的存储,在pod中我们只需要定义一个存储卷并且定义的时候我只需要说明我需要多大的存储卷就行了,这个存储卷叫pvc类型的存储卷,而pvc类型的存储卷必须与当前名称空间中的pvc建立直接绑定关系,而pvc必须与pv建立绑定关系,而pv应该是真正某个存储设备上的存储空间,所以pv和pvc是k8s系统之上的抽象的但也算是标准的资源,pvc是一种资源,pv也是一种资源,他的创建方式和我们此前创建其它资源方式是一样的,但是用户需要怎么做呢?存储工程师把每个存

Serverless Kubernetes全面升级2.0架构:支持多命名空间、RBAC、CRD、PV/PVC等功能

Serverless Kubernetes概述: 阿里云Serverless Kubernetes容器服务最新开放香港.新加坡.悉尼区域,同时全面开放2.0架构,帮助用户更加便捷.轻松地步入“以应用为中心”的全新架构.通过Serverless Kubernetes,用户50秒内可从零启动500应用容器,而无需关心底层服务器资源. Serverless Kubernetes 2.0新架构 Serverless Kubernetes 2.0对后台架构进行了彻底升级,从之前的基于Namespace的多

kubernetes存储之GlusterFS

目录 1.glusterfs概述 1.1.glusterfs简介 1.2.glusterfs特点 1.3.glusterfs卷的模式 2.heketi概述 3.部署heketi+glusterfs 3.1.准备工作 3.2.创建glusterfs集群 3.3.创建heketi服务 3.4.创建gfs集群 4.创建storageclass 6.分析k8s通过heketi创建pv及pvc的过程 7.测试数据 8.测试deployment 1.glusterfs概述 1.1.glusterfs简介 g

从零开始入门 K8s | Kubernetes 存储架构及插件使用

本文整理自<CNCF x Alibaba 云原生技术公开课>第 21 讲. 导读:容器存储是 Kubernetes 系统中提供数据持久化的基础组件,是实现有状态服务的重要保证.Kubernetes 默认提供了主流的存储卷接入方案(In-Tree),同时也提供了插件机制(Out-Of-Tree),允许其他类型的存储服务接入 Kubernetes 系统服务.本文将从 Kubernetes 存储架构.存储插件原理.实现等方面进行讲解,希望大家有所收获. 一.Kubernetes 存储体系架构 引例:

k8s存储卷

1.emptyDir存储卷 apiVersion: v1 kind: Pod metadata: name: cunchujuan spec: containers: - name: myapp #定义第一容器用于显示index.html文件内容 image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent volumeMounts: #调用存储卷 - name: html #使用存储卷的名称要和下面定义的一样 mountPath: /usr