K8s: 持久化存储之卷, NFS卷

卷 Volume

1 ) 概述

  • 容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题
    • 首先,当容器崩溃时,kubelet 将重新启动容器,容器中的文件将会丢失------因为容器会以干净的状态重建
    • 其次,当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件
  • K8s 抽象出 Volume 对象来解决这两个问题
  • Docker 也有 Volume 的概念,但对它只有少量且松散的管理
  • 在 Docker 中,Volume 是磁盘上或者另外一个容器内的一个目录
  • 直到最近,Docker 才支持对基于本地磁盘的 Volume 的生存期进行管理
  • 虽然 Docker 现在也能提供 Volume 驱动程序,但是目前功能还非常有限
    • 每个容器只允许有一个 Volume 驱动程序,并且无法将参数传递给卷
  • 另一方面,K8s 卷具有明确的生命周期------与包裹它的 Pod 相同
  • 因此,卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留
  • 当然,当一个 Pod 不再存在时,卷也将不再存在, 也许更重要的是
  • K8s 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷
  • 卷的核心是包含一些数据的目录,Pod 中的容器可以访问该目录
  • 特定的卷类型可以决定这个目录如何形成的
  • 并能决定它支持何种介质,以及目录中存放什么内容
  • 使 用 卷 时 , Pod 声 明 中 需 要 提 供 卷 的 类 型 (.spec.volumes 字 段 )
  • 和 卷 挂 载 的 位 置(.spec.containers.volumeMounts 字段)
  • K8s 提供了众多的volume类型,包括emptyDir、hostPath、nfs、glusterfs、cephfs、ceph,

2 ) 关于 emptyDir

  • 当 Pod 指定到某个节点上时,首先创建的是一个 emptyDir 卷
  • 并且只要 Pod 在该节点上运行,卷就一直存在
  • 就像它的名称表示的那样,卷最初是空的
  • 尽管 Pod 中的容器挂载 emptyDir 卷的路径可能相同也可能不同
  • 但是这些容器都可以读写 emptyDir 卷中相同的文件
  • 当 Pod 因为某些原因被从节点上删除时
  • emptyDir 卷中的数据也会永久删除
  • 说明
    • 容器崩溃并不会导致 Pod 被从节点上移除
    • 因此容器崩溃时 emptyDir 卷中的数据是安全的
  • emptyDir 的一些用途
    • 缓存空间,例如基于磁盘的归并排序
    • 为耗时较长的计算任务提供检查点
    • 以便任务能方便地从崩溃前状态恢复执行
    • 在 Web 服务器容器服务数据时,保存内容管理器类型容器获取的文件

3 )关于 hostPath

  • hostPath卷能将主机节点文件系统上的文件或目录挂载到Pod中

  • 虽然这不是大多数Pod需要的

  • 但是它为一些应用程序提供了强大的持久化能力

  • 现在写一个应用 $ vi vol-hostpath.yaml

    yaml 复制代码
    apiVersion: v1
    kind: Pod
    metadata:
      name: hostpath-pod
    spec:
      containers:
      - name: test-container
        image: nginx
        volumeMounts:
        - mountPath: /test-nginx
          name: myhostpath
      volumes:
      - name: myhostpath
        hostPath:
          path: /tmp/nginx
          type: DirectoryOrCreate # 不存在目录则创建
  • $ kubectl apply -f vol-hostpath.yaml

    conf 复制代码
    pod/hostpath-pod created
  • $ kubectl get pod

    conf 复制代码
    NAME           READY   STATUS    RESTARTS   AGE
    hostpath-pod   1/1     Running   0          18m
  • $ kubectl exec -it hostpath-pod -- sh 进入 pod

  • $ ls | grep test

    conf 复制代码
    test-nginx
  • $ cd test-nginx

  • $ touch a.txt

  • $ echo 1 > a.txt

  • 这时候在pod内 /test-nginx/a.txt 中写入了 1

  • 现在,退出 pod, $ exit

  • 查看pod被部署到了哪台node节点上,$ kubectl describe pod hostpath-pod | grep Node

    conf 复制代码
    Node:         node1.k8s/10.211.55.11
    Node-Selectors:              <none>
  • 好,定位到这个node机器上,执行 $ cat /tmp/nginx/a.txt

    conf 复制代码
    1
  • 可以看到,数据是同步的了,当然 hostPath 仍然是有局限的

    • 也就是和work node绑定了,如果应用服务多了,就麻烦了
    • 在一台work node存在,但是在另一台却不存在

NFS 卷

1 )概述

  • Network File System 简称 NFS
  • 很多应用需要在集群内部有一个统一的地方在存储文件,比如图片,日志等等
  • 而使用 hostPath 方式并不灵活,因为你需要指定 host 的地址
  • 如果在node1上上传的,在node2上就找不到了,所以,hostPath不适合一般传统业务场景
  • 我们需要,文件存储后,让所有应该都能访问到,而且要兼顾管理的便捷性
  • NFS 是一个成熟的技术,NFS 在大规模使用下会有性能问题
  • 如果文件量存储较大,建议还是用对象存储
  • 如果上传文件不多,也不大,可以推荐使用NFS
  • 可见,NFS解决了hostPath的问题
  • 一般,在 master 节点上装nfs服务专门管理文件存储
  • 在node1或node2上挂nfs服务器,写文件时,会写入 master 节点上

2 ) 安装 nfs 服务

  • 在 Master 和 所有Worker Node 安装 nfs 服务

    • $ yum install -y nfs-utils rpcbind centos 8 可以用 yum, centos 9已经使用dnf来
    • $ sudo dnf install nfs-utils rpcbind centos 9 安装
    • 注意,在centos9 上使用 yum 安装可能会出问题
    • 下面就使用 dnf 和 centos 9 作为安装的环境
  • 在 Master 节点配置 $ vi /etc/exports 修改配置

    conf 复制代码
    /nfsdata *(rw,sync,no_root_squash)
  • 在 Master 节点 $ sudo exportfs -ra 修改了/etc/exports,需要重新激活配置

    conf 复制代码
    sudo exportfs -ra
  • 在 Master 节点启动 NFS 服务和 rpcbind,并设置它们在系统启动时自动运行

    sh 复制代码
    sudo systemctl start rpcbind
    sudo systemctl start nfs-server
    sudo systemctl enable rpcbind
    sudo systemctl enable nfs-server
  • 在 Master节点检查 NFS 服务和 rpcbind 是否运行正常

    sh 复制代码
    sudo systemctl status rpcbind
    sudo systemctl status nfs-server
    • 检查Active的状态为: active
  • 在 Master 节点查看挂载效果 $ showmount -e master

    conf 复制代码
    Export list for master:
    /nfsdata *
    • 目前这样即为挂载/nfsdata成功

3 ) 在 node 节点 运行服务

  • $ vi nfs-demo1.yaml 编写yaml文件进行测试

    yaml 复制代码
    apiVersion: v1
    kind: Pod
    metadata:
      name: nfs-pd
    spec:
      containers:
      - name: test-container
        image: nginx
        volumeMounts: # 上面的容器内挂载目录为
        - mountPath: /usr/share/nginx/html
          name: test-volume
      volumes: # 物理机
      - name: test-volume
        nfs:
          server: master.k8s # 这里配置的是 master 节点的 hostname
          path: /nfsdata
  • $ kubectl get po -w 监控 nfs pod 的状态

    conf 复制代码
    NAME           READY   STATUS    RESTARTS       AGE
    nfs-pd         1/1     Running   0              36s
  • $ kubectl exec -it nfs-pd -- sh 进入pod

  • $ mount 执行 mount 看容器起来后,挂载哪些卷,这里是全部的

    conf 复制代码
    overlay on / type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/TGJN2AK5DUCHXGQSXLTICMH6CV:/var/lib/docker/overlay2/l/4EYRGAW5MFRGLIJKCOJFKWNRDT:/var/lib/docker/overlay2/l/Y5QO2NJ6REXYEVRYLCHKIWZOLG:/var/lib/docker/overlay2/l/T5HUWMG4LKHET6APDBVJ25QIPE:/var/lib/docker/overlay2/l/PCJEGNJOYLSPYYP5TJBFNNAPF6:/var/lib/docker/overlay2/l/4EUOTLMHJJFA2AXOALXRHNAIOA:/var/lib/docker/overlay2/l/7WCTJFFWY4TZNAN3GM4JWTIBSV:/var/lib/docker/overlay2/l/UI7F22MIRB2NZSHHGF6U6IJU2U,upperdir=/var/lib/docker/overlay2/f3010a94dda626c9b3f8249c61f03b3e6caf6557b1193d7f9979308f7bf8d4e5/diff,workdir=/var/lib/docker/overlay2/f3010a94dda626c9b3f8249c61f03b3e6caf6557b1193d7f9979308f7bf8d4e5/work)
    proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
    tmpfs on /dev type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
    devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=666)
    sysfs on /sys type sysfs (ro,nosuid,nodev,noexec,relatime)
    cgroup on /sys/fs/cgroup type cgroup2 (ro,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)
    mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
    shm on /dev/shm type tmpfs (rw,nosuid,nodev,noexec,relatime,size=65536k,inode64)
    /dev/mapper/cs-root on /dev/termination-log type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /etc/resolv.conf type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /etc/hostname type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    /dev/mapper/cs-root on /etc/hosts type xfs (rw,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota)
    master.k8s:/nfsdata on /usr/share/nginx/html type nfs4 (rw,relatime,vers=4.2,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.211.55.12,local_lock=none,addr=10.211.55.13)
    tmpfs on /run/secrets/kubernetes.io/serviceaccount type tmpfs (ro,relatime,size=1704516k,inode64)
    proc on /proc/asound type proc (ro,nosuid,nodev,noexec,relatime)
    proc on /proc/bus type proc (ro,nosuid,nodev,noexec,relatime)
    proc on /proc/fs type proc (ro,nosuid,nodev,noexec,relatime)
    proc on /proc/irq type proc (ro,nosuid,nodev,noexec,relatime)
    proc on /proc/sys type proc (ro,nosuid,nodev,noexec,relatime)
    proc on /proc/sysrq-trigger type proc (ro,nosuid,nodev,noexec,relatime)
    tmpfs on /proc/acpi type tmpfs (ro,relatime,inode64)
    tmpfs on /proc/kcore type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
    tmpfs on /proc/keys type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
    tmpfs on /proc/timer_list type tmpfs (rw,nosuid,size=65536k,mode=755,inode64)
    tmpfs on /proc/scsi type tmpfs (ro,relatime,inode64)
    tmpfs on /sys/firmware type tmpfs (ro,relatime,inode64)
  • $ mount | grep nfs 查看 nfs 挂载效果

    conf 复制代码
    master.k8s:/nfsdata on /usr/share/nginx/html type nfs4 (rw,relatime,vers=4.2,rsize=262144,wsize=262144,namlen=255,hard,proto=tcp,timeo=600,retrans=2,sec=sys,clientaddr=10.211.55.12,local_lock=none,addr=10.211.55.13)
  • 在 node 节点上创建文件并写入数据

    • $ cd /usr/share/nginx/html

    • $ touch x.txt

    • $ echo nfs > x.txt

    • $ cat x.txt

      conf 复制代码
      nfs

4 )回到 master 节点上检查

  • 现在回到 master.k8s 这个 master 节点上查看

    • $ cat /nfsdata/x.txt

      conf 复制代码
      nfs
  • 现在,可以看到,nfs 服务正常工作了

5 ) 总结

  • 文件共享,静态资源共享, 图片上传,...
  • 一切需要统一存储的地方,都适合 nfs
相关推荐
陌上阳光11 小时前
docker搭建ray集群
docker·容器·ray
这就是佬们吗11 小时前
初识 docker [上]
java·开发语言·笔记·docker·容器
FJW02081412 小时前
负载均衡集群HAproxy
linux·服务器·云原生·负载均衡
BigBigHang12 小时前
【docker】DM8达梦数据库的docker-compose以及一些启动踩坑
数据库·docker·容器
云道轩12 小时前
使用Docker在Rocky Linux 9.5上在线部署LangFlow
linux·人工智能·docker·容器·langflow
伟大的大威12 小时前
Docker 部署 Supabase并连接
运维·docker·容器
杰克逊的日记13 小时前
k8s的csi对接GPFS
云原生·容器·kubernetes·存储·gpfs
岚天start13 小时前
云服务器以域名形式访问机房Kubernetes集群服务之解决方案
nginx·docker·kubernetes·kubesphere·解决方案·云服务器·机房
容器魔方17 小时前
「中科类脑」正式加入 Karmada 用户组!携手社区共建多集群生态
云原生·容器·云计算
终端行者17 小时前
k8s之ingress定义https访问方式
容器·https·kubernetes