Kubernetes(k3s)进阶学习(四) -- 持久化存储

Pod 的生命周期是短暂的,会频繁被销毁和创建。由于沙盒机制,旧Pod 被销毁后,会伴随容器里的所有资源都被清空。在服务运行过程,或多或少有需要持久化存储的资源(图片、多媒体、文档),我们都肯定不希望看到Pod没了这些资源也跟着被销毁。
另外同性质的Pod,资源之间应该允许共享,而不是被当独作为服务来远程访问。

Volume使用

Volume的生命周期独立于容器,它是一个目录,Volume会被mount到Pod,Pod中的所有容器都可以访问这个Volume,和Docker Volume类似。
Volume支持的类型:emptyDir、hostPath、AWS Elastic Block Store、NFS、Ceph等。

emptyDir(临时存储卷)

emptyDir属于Pod内的临时挂载的目录。 当Volume 选择类型为emptyDir时,它的特性只是一个临时挂载的目录,Pod删除后,该目录也会在node节点上被删除;但是如果容器崩溃或者Kubenetes 重启,该目录仍然存在,通过Pod 关联的容器均能访问该目录。

1)创建示例应用
#本地终端,进入server节点容器的命令
multipass shell server

#进入容器后,先创建文件:volume-test.yml
sudo vi volume-test.yml

#volume-test.yml 的内容

apiVersion: v1
kind: Pod
metadata:
  name: shared-pod
spec:
  containers:
  - image: busybox
    name: write-container
    volumeMounts:
    - mountPath: /write_directory   
      name: shared-volume
    args:
    - /bin/sh       
    - -c
    - echo "hello K3s" >/write_directory/test; sleep 120000

  - image: busybox
    name: read-container
    volumeMounts:
    - mountPath: /read_directory
      name: shared-volume
    args:
    - /bin/sh 
    - -c
    - cat /read_directory/test; sleep 120000

  volumes:
  - name: shared-volume
    emptyDir: {}

2)示例讲解

\color{red}{注:}所有的示例均在Multipass内执行。
上述代码,首先声明一个叫shared-volume 的volume。同时为了方便下面对pod 的目录共享的验证,示例在Pod 内创建了两个容器,均通过volumeMounts 指向shared-volume 的shared_directory目录。
容器:write-container 负责在shared_directory 目录写入test文件(内容:hello K3s),read-container 则在启动后,读取/shared_directory 的test 文件。

2)示例验证
#先通过kubectl 引入volume-test.yml 文件
ubuntu@server:~/$ sudo kubectl apply -f volume-test.yml 
pod/shared-pod created

#验证pod 是否成功创建
ubuntu@server:~/$ sudo kubectl get pod

NAME                                   READY   STATUS                   RESTARTS      AGE
shared-pod                             2/2     Running                  0             37s

#验证 read-container 容器读取结果
ubuntu@server:~/demo-volume$ sudo kubectl logs shared-pod read-container
#验证成功
hello K3s

上述显示容器read-container成功读到了write-container容器写入的数据,验证了两个容器共享emptyDir Volume,其效果相当于执行了docker run -v /write_directory 和/docker run -v /read_directory。

HostPath(节点存储卷)

hostPath类型的存储卷是指将工作节点上某个文件系统的目录或文件挂载于Pod中的一种存储卷,它独立于Pod资源的生命周期,因而具有持久性。但由于这样的特征增加了了Pod与工作节点的耦合,在实际的场景应用中都不会选择此项。作为分布式的应用部署,更应该把持久化的目标独立于工作节点之外。
HostPath 与emptyDir 的使用方法相似,同时网上的资料也较多,这里就不再做示例演示。

PV & PVC

使用外部存储作为资源持久化目标是最理想方案,如果kubenetes部署在阿里云、AWS、Azure等公有云上,可以直接使用云盘作为Volume。 同样我们也可以创建NFS(网络文件系统),使用PV把NFS引入到Pod去。

①NFS for PV

先准备NFS网络盘,NFS服务具体部署请参照:https://www.jianshu.com/p/a5d5d9afa1eb

在此,笔者已经准备好NFS服务器:\color{red}{192.168.64.12},可分享目录路径:\color{red}{/nfsdata/share}

②部署示例应用
#本地终端,进入server节点容器的命令
multipass shell server

#进入容器后,先创建文件:nfs-pv.yml
sudo vi nfs-pv.yml

#nfs-pv.yml 的内容

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
spec:
  capacity:
    storage: 1Gi    #指定PV的容量为1GB
  accessModes:
    - ReadWriteOnce  #表示PV能为read-write模式mount到单个节点,ReadOnlyMany表示只读,mount到多个节点,ReadWriteMany表示读写可以mount到多节点
  persistentVolumeReclaimPolicy: Recycle  #PV的回收策略,清除PV中的数据,Retain表示管理员手工回收
  storageClassName: nfs-storage    #指定PV的class为nfs-storage,相当于为PV设置了一个分类,PVC可以指定class申请相应的PV
  nfs:
    path: /nfsdata/share    #指定PV在NFS服务器上对应的目录
    server: 192.168.64.12

引用PV,并且验证。

#引入
ubuntu@server:~$ sudo kubectl apply -f nfs-pv.yml 
#输出成功结果
persistentvolume/nfs-pv created

#验证
ubuntu@server:~$ sudo kubectl get pv -o wide

#输出结果
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
nfs-pv   1Gi        RWO            Recycle          Available           nfs-storage                     36s   Filesystem

创建PVC


sudo vi nfs-pvc.yml

#nfs-pvc.yml 的内容

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pv
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  storageClassName: nfs-storage      #与之前PV的storageClassName 一致

引用PVC,并且验证。

#引入
ubuntu@server:~$ sudo kubectl apply -f nfs-pvc.yml 
#输出成功结果
persistentvolumeclaim/nfs-pvc created

#验证
ubuntu@server:~$ sudo kubectl get pvc -o wide

#输出结果
NAME     STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
nfs-pv   Bound    nfs-pv   1Gi        RWO            nfs-storage    38s   Filesystem

那么,可以创建新的Pod 进行验证了。

③在Pod 中使用PVC
sudo vi nfs-pod.yml

#nfs-pod.yml 的内容

apiVersion: v1
kind: Pod
metadata:
  name: pv-pod
spec:
  containers:
    - name: pv-pod
      image: busybox
      args:
      - /bin/sh
      - -c
      - sleep 180000
      volumeMounts:
      - mountPath: "/pod_data"
        name: nfs-storage
  volumes:
    - name: nfs-storage
      persistentVolumeClaim:
        claimName: nfs-pv

最后测试验证

#引入
ubuntu@server:~$ sudo kubectl apply -f nfs-pod.yml
#输出结果
pod/pv-pod created

[root@k8s-node1 nfs-pv]# sudo kubectl get pod -o wide

#输出结果
NAME                                   READY   STATUS                   RESTARTS      AGE     IP           NODE     NOMINATED NODE   READINESS GATES
pv-pod                                 0/1     Running                  0             34s     <none>       <none>   <none>           <none>


#类似docker exec 的执行操作,直接进入pod 的sh
ubuntu@server:~$ sudo kubectl exec -it pv-pod /bin/sh

#在容器中,执行如下命令
/ # cat /pod_data/text.txt

#输出结果
Hello NFS!

#在部署NFS网络文件系统一章
#地址:https://www.jianshu.com/p/a5d5d9afa1eb
#笔者已在NFS服务器:192.168.64.12 的目录/nfsdata/share创建了text.txt文件。

不需要使用PV时,可用删除PVC回收PV

ubuntu@server:~$# kubectl delete pvc pv-pod 
persistentvolumeclaim "pv-pod" deleted

因PV的回收策略设置为Recycle,所以数据会被清除,如想保存数据,可以将策略设置为Retain。
本章结束!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容