k8s数据管理(八)--技术流ken

 

volume

 

咱们常常会说:容器和 Pod 是短暂的。
其含义是它们的生命周期可能很短,会被频繁地销毁和建立。容器销毁时,保存在容器内部文件系统中的数据都会被清除。docker

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

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-volumesapp

Volume 提供了对各类 backend 的抽象,容器在使用 Volume 读写数据的时候不须要关心数据究竟是存放在本地节点的文件系统中呢仍是云硬盘上。对它来讲,全部类型的 Volume 都只是一个目录。ide

 

emptyDir

 

emptyDir 是最基础的 Volume 类型。一个 emptyDir Volume 是 Host 上的一个空目录。spa

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

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

Pod 中的全部容器均可以共享 Volume,它们能够指定各自的 mount 路径。server

 

下面经过例子来实践 emptyDir对象

第一步:配置文件以下:

这里咱们模拟了一个 producer-consumer 场景。Pod 有两个容器 producerconsumer,它们共享一个 Volumeproducer 负责往 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@ken ~]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
producer-consumer   2/2     Running   0          2m1s
[root@ken ~]# kubectl logs producer-consumer consumer
hello world

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

 

由于 emptyDir 是 Docker Host 文件系统里的目录,其效果至关于执行了 docker run -v /producer_dir 和 docker run -v /consumer_dir。

 

第三步:经过 docker inspect 查看容器的详细配置信息,咱们发现两个容器都 mount 了同一个目录:

这里 /var/lib/kubelet/pods/4dcc0366-245f-11e9-9172-000c292d5bb8/volumes/kubernetes.io~empty-dir/shared-volume 就是 emptyDir Host 上的真正路径。

 

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

 

hostpath

 

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

 

好比 kube-apiserver 和 kube-controller-manager 就是这样的应用,经过

 

kubectl edit --namespace=kube-system pod kube-apiserver-k8s-master

查看 kube-apiserver Pod 的配置,下面是 Volume 的相关部分:

这里定义了三个 hostPath volume k8s、certs 和 pki,分别对应 Host 目录 /etc/kubernetes、/etc/ssl/certs 和 /etc/pki。

 

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

 

PV & PVC 

 

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 PV

 

第一步:需在 k8s-master 节点上搭建了一个 NFS 服务器,目录为 /nfsdata

要更改目录属主,不然没有写入权限: chown -R nfsnobody.nfsnobody /nfsdata

[root@ken ~]# showmount -e
Export list for ken:
/nfsdata *

 

第二步:建立一个 PV mypv1,配置文件 nfs-pv1.yml 以下:

[root@ken ~]# cat nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1   #须要建立pv1目录,不然pod起不来
    server: 172.20.10.2

 

① capacity 指定 PV 的容量为 1G。

② 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 等。

④ storageClassName 指定 PV 的 class 为 nfs。至关于为 PV 设置了一个分类,PVC 能够指定 class 申请相应 class 的 PV。

⑤ 指定 PV 在 NFS 服务器上对应的目录。

 

第三步:建立 mypv1:

[root@ken ~]# kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 created

 

第四步:查看pv

[root@ken ~]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Available           nfs                     48s

STATUS 为 Available,表示 mypv1 就绪,能够被 PVC 申请。

 

第五步:接下来建立 PVC mypvc1,配置文件 nfs-pvc1.yml 以下:

注意:

1. storageClassName须要与上面定义的pv保持一致!

2. 各个节点都须要下载nfs-utils          

PVC 就很简单了,只须要指定 PV 的容量,访问模式和 class。

[root@ken ~]# kubectl apply -f nfs-pvc1.yml
persistentvolumeclaim/mypvc1 created

 

第六步:查看pvc

[root@ken ~]# kubectl get pvc
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc1   Bound    mypv1    1Gi        RWO            nfs            112s
[root@ken ~]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Recycle          Bound    default/mypvc1   nfs                     6m5s

从 kubectl get pvc 和 kubectl get pv 的输出能够看到 mypvc1 已经 Bound mypv1,申请成功。

 

第七步:接下来就能够在 Pod 中使用存储了,Pod 配置文件 pod1.yml 以下:

与使用普通 Volume 的格式相似,在 volumes 中经过 persistentVolumeClaim 指定使用 mypvc1 申请的 Volume

 

第八步:建立 mypod1:

[root@ken ~]# kubectl apply -f pod1.yml
pod/mypod1 created

[root@ken ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mypod1 1/1 Running 0 51s 10.244.1.59 host1 <none> <none>

 

第九步:验证 PV 是否可用:

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

[root@ken ~]# ls /nfsdata/pv1/
hello

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

 

回收PV

 

当 PV 再也不须要时,可经过删除 PVC 回收。

 

当 PVC mypvc1 被删除后,Kubernetes 启动了一个新 Pod recycler-for-mypv1,这个 Pod 的做用就是清除 PV mypv1 的数据。此时 mypv1 的状态为 Released,表示已经解除了与 mypvc1 Bound,正在清除数据,不过此时还不可用。

 

当数据清除完毕,mypv1 的状态从新变为 Available,此时则能够被新的 PVC 申请。

 

由于 PV 的回收策略设置为 Recycle,因此数据会被清除,但这可能不是咱们想要的结果。若是咱们但愿保留数据,能够将策略设置为 Retain。

第一步:将策略设置为 Retain。

[root@ken ~]# cat nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: nfs
  nfs:
    path: /nfsdata/pv1
    server: 172.20.10.2

 

第二步:经过 kubectl apply 更新 PV:

root@ken ~]# kubectl apply -f nfs-pv1.yml
persistentvolume/mypv1 configured
[root@ken ~]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
mypv1   1Gi        RWO            Retain           Available                        nfs                     65m

回收策略已经变为 Retain

 

另外使用retain虽然删除pod后的数据获得了保留,但其 PV 状态会一直处于 Released,不能被其余 PVC 申请。为了从新使用存储资源,能够删除并从新建立 PV。删除操做只是删除了 PV 对象,存储空间中的数据并不会被删除。

相关文章
相关标签/搜索