为了持久化保存容器的数据,可以使用 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:

[root@master ~]# kubectl apply -f emptydir.yaml
pod/producer-consumer created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
producer-consumer 2/2 Running 0 8s
[root@master ~]# 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 服务器,输出三个目录:

[root@datanode03 ~]# 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。

[root@master ~]# 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。

[root@master ~]# kubectl apply -f nfs-pvc.yaml
persistentvolumeclaim/pvc001 created
[root@master ~]# kubectl get pvc
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc001 Bound pv001 1Gi RWX 9s
[root@master ~]# 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。

[root@master ~]# kubectl apply -f nfs-pvc-pod.yaml
pod/mypod1 created
[root@master ~]# 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 是否可用:

[root@master ~]# kubectl exec mypod1 touch /mydata/hello

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

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

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

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

  1. (九)Kubernetes 存储卷

    Kubernetes存储卷概述 Pod本身具有生命周期,这就带了一系列的问题,第一,当一个容器损坏之后,kubelet会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态:第二,当很多容器在同一 ...

  2. Kubernetes 学习12 kubernetes 存储卷

    一.概述 1.我们此前讲过根据应用本身是否需要持久存储数据以及某一次请求和之前的请求是否有联系,可以分为四类应用 a.有状态,要存储 b.有状态,无持久存储 c.无状态,要存储 d.无状态,无持久存储 ...

  3. kubernetes 存储卷

    kubernetes 存储卷    数据卷用于实现容器持久化数据,Kubernetes对于数据卷重新定义,提供了丰富强大的功能.在Kubernetes系统中,当Pod重建的时候,数据卷会丢失,Kube ...

  4. kubernetes存储类与PV与PVC关系及实践

    StorageClass & PV & PVC关系图 Volumes是最基础的存储抽象,其支持多种类型,包括本地存储.NFS.FC以及众多的云存储,我们也可以编写自己的存储插件来支持特 ...

  5. Kubernetes 存储系统 Storage 介绍:PV,PVC,SC

    要求:先了解数据docker容器中数据卷的挂载等知识 参考网址: https://www.cnblogs.com/sanduzxcvbnm/p/13176938.html https://www.cn ...

  6. K8s存储卷、pv和pvc的使用

    emptyDIR 临时目录 hostPath :使用主机的路径 网络存储: 传统的设备存储:NAS,SAN 分布式存储:glusterfs,rbd,cephfs 云存储:EBS,Azure,阿里云的 ...

  7. kubernetes 存储volume,pv和pvc的使用

    emptyDIR 临时目录 hostPath :使用主机的路径 网络存储: 传统的设备存储:NAS,SAN 分布式存储:glusterfs,rbd,cephfs 云存储:EBS,Azure,阿里云的 ...

  8. Kubernetes 存储卷详解

    转载自:https://mp.weixin.qq.com/s/Ywx3ju6FP0IShOgI757XYA Volumes 默认情况下容器中的磁盘文件是非持久化的,对于运行在容器中的应用来说面临两个问 ...

  9. Kubernetes学习之路(十六)之存储卷

    目录 一.存储卷的概念和类型 二.emptyDir存储卷演示 三.hostPath存储卷演示 四.nfs共享存储卷演示 五.PVC和PV的概念 六.NFS使用PV和PVC 1.配置nfs存储 2.定义 ...

随机推荐

  1. Python 爬虫js加密破解(三) 百度翻译 sign

    第一步: 模拟抓包分析加密参数 第二步: 找到加密字段 调试出来的sign和抓取得到的数据一致,都是 275626.55195 第三部: 分析js加密方法 第四部:运行js代码: 仅供交流学习使用

  2. centos服务器上git clone下载加速

    最近在服务器上直接git clone github上的仓库,下载速度只有十几KB,简直不要太慢! 网上搜了一些加速的,自己于是写了下面的总结. 1. nslookup命令 如果执行这个命令找不到,请先 ...

  3. 通俗理解word2vec的训练过程

    https://www.leiphone.com/news/201706/eV8j3Nu8SMqGBnQB.html https://blog.csdn.net/dn_mug/article/deta ...

  4. 在linux下crontab不执行原因排查

    一.开启cron日志 #检查是否已经开启 cron sudo service cron status #cron start/running, process 23719 # 重启服务 cron su ...

  5. js正则实现从一段复杂html代码字符串中匹配并处理特定信息

    js正则实现从一段复杂html代码字符串中匹配并处理特定信息 问题: 现在要从一个复杂的html代码字符串(包含各种html标签,数字.中文等信息)中找到某一段特别的信息(被一对“|”包裹着),并对他 ...

  6. (转)python自动化测试之异常及日志

    为了保持自动化测试用例的健壮性,异常的捕获及处理,日志的记录对掌握自动化测试执行情况尤为重要,这里便详细的介绍下在自动化测试中使用到的异常及日志,并介绍其详细的用法. 一.日志 打印日志是很多程序的重 ...

  7. 使用 Word 写作论文时设置格式技巧记录

    这里主要记录使用 Word 2013 版本的 Microsoft office Word 软件进行论文书写时的一些常用的格式设置技巧,以供分享与记录. Word文档页脚添加页码 Word设置多级标题格 ...

  8. 实用Golang库

    框架: 1. Golang轻量级并发服务器框架: zinx / https://www.jianshu.com/p/23d07c0a28e52. 国内谢大牛模仿django制作的重框架: beego3 ...

  9. java中异步调用注意

    Future接口是Java标准API的一部分,在java.util.concurrent包中.Future接口是Java线程Future模式的实现,可以来进行异步计算. 有了Future就可以进行三段 ...

  10. 接口测试-Java代码实现接口请求并封装

    前言:在接口测试和Java开发中对接口请求方法进行封装都非常有必要,无论是在我们接口测试的时候还是在开发自测,以及调用某些第三方接口时,都能为我们调用和调试接口提供便捷: Java实现对http请求的 ...