关于 Kubernetes中Volume的一些笔记(一)

举报
山河已无恙 发表于 2021/12/01 23:30:52 2021/12/01
【摘要】 男女情事,谁先动心谁吃亏,越吃亏越难忘,到最后,到底是喜欢对方呢,还是喜欢自己,都搞不清楚了,答案偏偏在对方身上,所以才说,由爱故生忧。--------《剑来》

写在前面


  • 学习K8s,刚把这一块学完,整理笔记,理论很少,偏实战,适合温习
  • 博文内容涉及:
    • 常见nfs,hostPath,emptyDir数据卷类型
    • PV+PVC的创建
    • 持久性存储动态卷供应

男女情事,谁先动心谁吃亏,越吃亏越难忘,到最后,到底是喜欢对方呢,还是喜欢自己,都搞不清楚了,答案偏偏在对方身上,所以才说,由爱故生忧。--------《剑来》


数据卷(Volume)管理

Volume是Pod中能够被多个容器访问的共享目录。Kuberetes的Volume概念、用途和目的与Docker的Volume比较类似,但两者不能等价

Volume (存储卷)
Kubernetes中的Volume定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下;
Kubernetes中的Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时, Volume中的数据也不会丢失。
Kubernetes支持多种类型的Volume,例如GlusterFS, Ceph等先进的分布式文件系统

Volume的使用也比较简单,在大多数情况下,我们先在Pod上声明一个Volume,然后在容器里引用该VolumeMount到容器里的某个目录上。举例来说,我们要给之前的Tomcat Pod增加一个名字为datavolVolume,并且Mount到容器的/mydata-data目录上,则只要对Pod的定义文件做如下修正即可(注意黑体字部分):

template:
  metadata:
    labels:
      app: app-demo
      tier: frontend
  spec:
    volumes:
      - name: datavol
        emptyDir: {}
    containers:
    - name: tomcat-demo
      image: tomcat
      volumeMounts:
        - mountPath: /myddata-data
          name: datavol
      imagePullPolicy: IfNotPresent

除了可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到网络存储中, Kubernetes的Volume还扩展出了一种非常有实用价值的功能,即容器配置文件集中化定义与管理,这是通过ConfigMap这个新的资源对象来实现的.

Kubernetes提供了非常丰富的Volume类型

学习环境准备

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$mkdir k8s-volume-create;cd k8s-volume-create
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl get ns
NAME                   STATUS   AGE
default                Active   49d
kube-node-lease        Active   49d
kube-public            Active   49d
kube-system            Active   49d
liruilong              Active   49d
liruilong-pod-create   Active   41d
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl  create ns liruilong-volume-create
namespace/liruilong-volume-create created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl config set-context $(kubectl config current-context) --namespace=liruilong-volume-create
Context "context1" modified.
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl config get-contexts
CURRENT   NAME       CLUSTER    AUTHINFO            NAMESPACE
          cluster1                                  default
*         context1   cluster1   kubernetes-admin1   liruilong-volume-create
          context2                                  kube-system

emptyDir

一个emptyDir Volume是在Pod分配到Node时创建的从它的名称就可以看出,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为这是 Kubernetes自动分配的一个目录,而且这个目录实际是挂载中物理机内存中的的,当Pod从Node上移除时, emptyDir中的数据也会被永久删除

emptyDir的一些用途如下:

emptyDir的一些用途
临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留。
长时间任务的中间过程CheckPoint的临时保存目录。
一个容器需要从另一个容器中获取数据的目录(多容器共享目录)

创建一个Pod,声明volume卷

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podvolume
  name: podvolume
spec:
  volumes:
  - name: volume1
    emptyDir: {}
  - name: volume2
    emptyDir: {}
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh','-c','sleep 5000']
    resources: {}
    name: podvolume1
    volumeMounts:
    - mountPath: /liruilong
      name: volume1
  - image: busybox
    imagePullPolicy: IfNotPresent
    name: podvolume2
    volumeMounts:
    - mountPath: /liruilong
      name: volume2
    command: ['sh','-c','sleep 5000']
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

创建pod,查看运行状态

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl apply  -f pod_volume.yaml
pod/podvolume configured
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl get pods -o wide
NAME        READY   STATUS             RESTARTS         AGE   IP             NODE                         NOMINATED NODE   READINESS GATES
podvolume   0/2     CrashLoopBackOff   164 (117s ago)   37h   10.244.70.14   vms83.liruilongs.github.io   <none>           <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$

查看pod的数据卷类型

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl describe  pod podvolume | grep -A2 Volumes
Volumes:
  volume1:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)

通过docker命令来查看对应的宿主机容器

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "docker ps | grep podvolume"
192.168.26.83 | CHANGED | rc=0 >>
bbb287afc518   cabb9f684f8b                                          "sh -c 'sleep 5000'"     12 minutes ago   Up 12 minutes             k8s_podvolume2_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0
dcbf5c63263f   cabb9f684f8b                                          "sh -c 'sleep 5000'"     12 minutes ago   Up 12 minutes             k8s_podvolume1_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0
5bb9ee2ed134   registry.aliyuncs.com/google_containers/pause:3.4.1   "/pause"                 12 minutes ago   Up 12 minutes             k8s_POD_podvolume_liruilong-volume-create_76b518f6-9575-4412-b161-f590ab3c3135_0
┌──[root@vms81.liruilongs.github.io]-[~/ansible]

通过inspect查看映射的宿主机信息

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "docker inspect dcbf5c63263f | grep -A5 Mounts"
192.168.26.83 | CHANGED | rc=0 >>
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/76b518f6-9575-4412-b161-f590ab3c3135/volumes/kubernetes.io~empty-dir/volume1",
                "Destination": "/liruilong",
                "Mode": "",
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "docker inspect bbb287afc518 | grep -A5 Mounts"
192.168.26.83 | CHANGED | rc=0 >>
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/76b518f6-9575-4412-b161-f590ab3c3135/volumes/kubernetes.io~empty-dir/volume2",
                "Destination": "/liruilong",
                "Mode": "",
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

pod内多容器数据卷共享

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$sed 's/podvolume/podvolumes/' pod_volume.yaml >pod_volumes.yaml
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$vim pod_volumes.yaml

编写pod_volumes.yaml文件

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podvolumes
  name: podvolumes
spec:
  volumes:
  - name: volume1
    emptyDir: {}
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh','-c','sleep 5000']
    resources: {}
    name: podvolumes1
    volumeMounts:
    - mountPath: /liruilong
      name: volume1
  - image: busybox
    imagePullPolicy: IfNotPresent
    name: podvolumes2
    volumeMounts:
    - mountPath: /liruilong
      name: volume1
    command: ['sh','-c','sleep 5000']
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

新建的文件夹中两个pod中同时存在

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl apply  -f pod_volumes.yaml
pod/podvolumes created
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl exec -it podvolumes -c podvolumes1 -- sh
/ # mkdir -p /liruilong/$(date +"%Y%m%d%H%M%S");cd /liruilong/;ls
20211127080726
/liruilong #
/liruilong # exit
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl exec -it podvolumes -c podvolumes2 -- sh
/ # cd /liruilong/;ls
20211127080726
/liruilong #

设置数据卷的读写权限

pod_volume_r.yaml:设置数据卷pod1只读

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podvolume
  name: podvolume
spec:
  volumes:
  - name: volume1
    emptyDir: {}
  - name: volume2
    emptyDir: {}
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh','-c','sleep 5000']
    resources: {}
    name: podvolume1
    volumeMounts:
    - mountPath: /liruilong
      name: volume1
      readOnly: true # 设置数据卷pod1只读
  - image: busybox
    imagePullPolicy: IfNotPresent
    name: podvolume2
    volumeMounts:
    - mountPath: /liruilong
      name: volume2
    command: ['sh','-c','sleep 5000']
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl exec  -it podvolume -c podvolume1 -- sh
/ # cd liruilong/;touch lrl.txt
touch: lrl.txt: Read-only file system
/liruilong #
/liruilong # exit
command terminated with exit code 1
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl exec  -it podvolume -c podvolume2 -- sh
/ # cd liruilong/;touch lrl.txt
/liruilong # ls
lrl.txt
/liruilong #

hostPath

hostPath为在Pod上挂载宿主机上的文件或目录,它通常可以用于以下几方面。

hostPath的应用
容器应用程序生成的日志文件需要永久保存时,可以使用宿主机的高速文件系统进行存储。
需要访问宿主机上Docker引擎内部数据结构的容器应用时,可以通过定义hostPath为宿主机/var/lib/docker目录,使容器内部应用可以直接访问Docker的文件系统。

在使用这种类型的Volume时,需要注意以下几点。

在不同的Node上具有相同配置的Pod可能会因为宿主机上的目录和文件不同而导致对Volume上目录和文件的访问结果不一致。

如果使用了资源配额管理,则Kubernetes无法将hostPath在宿主机上使用的资源纳入管理cgroup。在下面的例子中使用宿主机的/data目录定义了一个hostPath类型的Volume:

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podvolumehostpath
  name: podvolumehostpath
spec:
  volumes:
  - name: volumes1
    hostPath:
      path: /data
  containers:
  - image: busybox
    name: podvolumehostpath
    command: ['sh','-c','sleep 5000']
    resources: {}
    volumeMounts:
    - mountPath: /liruilong
      name: volumes1
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl apply  -f PodVolumeHostPath.yaml
pod/podvolumehostpath created

宿主机创建一个文件

┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$kubectl  get pod -o wide
NAME                READY   STATUS    RESTARTS   AGE     IP            NODE                         NOMINATED NODE   READINESS GATES
podvolumehostpath   1/1     Running   0          5m44s   10.244.70.9   vms83.liruilongs.github.io   <none>           <none>
┌──[root@vms81.liruilongs.github.io]-[~/ansible/k8s-volume-create]
└─$cd ..
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "cd /data;touch liruilong"
192.168.26.83 | CHANGED | rc=0 >>

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible 192.168.26.83 -m shell -a "cd /data;ls"
192.168.26.83 | CHANGED | rc=0 >>
liruilong
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

pod容器内同样存在

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$kubectl exec -it podvolumehostpath -- sh
/ # ls
bin        dev        etc        home       liruilong  proc       root       sys        tmp        usr        var
/ # cd liruilong/;ls
liruilong
/liruilong #

NFS

不管是emptyDir还是hostPath,数据都是存放到宿主机,但是如某个pod出现了问题,通过控制器重启时,会通过调度生产一个新的Pod,如果调度的节点不是原来的节点,那么数据就会丢失。这里的话,使用网路存储就很方便。

部署一个NFSServer

使用NFS网络文件系统提供的共享目录存储数据时,我们需要在系统中部署一个NFSServer

┌──[root@vms81.liruilongs.github.io]-[~]
└─$yum -y install nfs-utils.x86_64
┌──[root@vms81.liruilongs.github.io]-[~]
└─$systemctl enable nfs-server.service  --now
┌──[root@vms81.liruilongs.github.io]-[~]
└─$mkdir -p /liruilong
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$cd /liruilong/;echo `date` > liruilong.txt
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$cd /liruilong/;cat  liruilong.txt
20211127日 星期六 21:57:10 CST
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$cat /etc/exports
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$echo "/liruilong *(rw,sync,no_root_squash)" > /etc/exports
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$exportfs -arv
exporting *:/liruilong
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$showmount -e
Export list for vms81.liruilongs.github.io:
/liruilong *
┌──[root@vms81.liruilongs.github.io]-[/liruilong]
└─$

然后我们需要在所有的工作节点安装nfs-utils,然后挂载

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "yum -y install nfs-utils"
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "systemctl enable nfs-server.service  --now"

nfs共享文件测试

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "showmount -e vms81.liruilongs.github.io"
192.168.26.83 | CHANGED | rc=0 >>
Export list for vms81.liruilongs.github.io:
/liruilong *
192.168.26.82 | CHANGED | rc=0 >>
Export list for vms81.liruilongs.github.io:
/liruilong *
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$

挂载测试

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node  -m shell -a "mount  vms81.liruilongs.github.io:/liruilong /mnt"

192.168.26.82 | CHANGED | rc=0 >>

192.168.26.83 | CHANGED | rc=0 >>

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "cd /mnt/;ls"
192.168.26.83 | CHANGED | rc=0 >>
liruilong.txt
192.168.26.82 | CHANGED | rc=0 >>
liruilong.txt
┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node -m shell -a "df -h | grep  liruilong"
192.168.26.82 | CHANGED | rc=0 >>
vms81.liruilongs.github.io:/liruilong  150G  8.3G  142G    6% /mnt
192.168.26.83 | CHANGED | rc=0 >>
vms81.liruilongs.github.io:/liruilong  150G  8.3G  142G    6% /mnt

取消挂载

┌──[root@vms81.liruilongs.github.io]-[~/ansible]
└─$ansible node  -m shell -a "umount /mnt"

使用nfs数据卷pod资源yaml文件

podvolumenfs.yaml

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: podvolumehostpath
  name: podvolumehostpath
spec:
  volumes:
  - name: volumes1
    nfs:
      server: vms81.liruilongs.github.io
      path: /liruilong
  containers:
  - image: busybox
    name: podvolumehostpath
    command: ['sh','-c','sleep 5000']
    resources: {}
    volumeMounts:
    - mountPath: /liruilong
      name: volumes1
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。