Kubernetes基于Volume存储数据

1 Volume介绍

1.1 Volume的作用

  • 容器中的文件在磁盘上是临时存放的,这给容器中运行的特殊应用程序带来一些问题。 首先,当容器崩溃时,kubelet 将重新启动容器,容器中的文件将会丢失——因为容器会以干净的状态重建。 其次,当在一个 Pod 中同时运行多个容器时,常常需要在这些容器之间共享文件。 Kubernetes 抽象出 Volume 对象来解决这两个问题。

1.2 Volume的特点

  • Kubernetes 卷具有明确的生命周期——与包裹它的 Pod 相同。 因此,卷比 Pod 中运行的任何容器的存活期都长,在容器重新启动时数据也会得到保留。 当然,当一个 Pod 不再存在时,卷也将不再存在。 重要的是,Kubernetes 可以支持许多类型的卷,Pod 也能同时使用任意数量的卷。

  • 卷的核心是包含一些数据的目录,Pod 中的容器可以访问该目录。 特定的卷类型可以决定这个目录如何形成,并能决定它支持何种介质,以及目录中存放什么内容。

  • 容器中的进程能看到由它们的 Docker 镜像和卷组成的文件系统视图。 Docker 镜像位于文件系统层次结构的根部,并且任何 Volume 都挂载在镜像内的指定路径上。 卷不能挂载到其他卷,也不能与其他卷有硬链接。 Pod 中的每个容器必须独立地指定每个卷的挂载位置。

1.3 Volume的类型

  • 卷的类型有很多种,具体请见Kubernetes官网说明文档,其中大部分是与云环境相关。本文主要介绍在非云环境中使用得较多的几种卷,主要包括:emptyDir、hostPath、configMap、secret、nfs、persistentVolumeClaim等。

2 Volume使用

2.1 特别说明

2.2 emptyDir

  • 作用说明:emptyDir 的作用是创建一个空卷,并挂载到 Pod中 的容器。Pod 删除则该卷也会被删除,一般用作临时目录、缓存、Pod 中容器之间的数据共享。

  • 实战需求:同一个 Pod 中的两个容器基于 emptyDir 进行数据共享,其中一个容器往 emptyDir 中写数据,另一个容器从 emptyDir 中读数据。

  • 编写yaml:在 Kubernetes 集群的 Master 节点中创建一个名为 empty-dir-pod.yaml 的文件,其内容如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: empty-dir-pod
    spec:
      containers:
      - name: write-shared-data
        image: busybox:latest
        command: ["/bin/sh", "-c", "echo 'hello world' >> /data/shared-data.txt"]
        volumeMounts:
        - name: shared-data
          mountPath: /data
      - name: read-shared-data
        image: busybox:latest
        command: ["/bin/sh", "-c", "cat /data/shared-data.txt"]
        volumeMounts:
        - name: shared-data
          mountPath: /data
      volumes:
      - name: shared-data
        emptyDir: {}
      restartPolicy: Never
    
  • yaml说明:上述yaml文件中创建了一个名称为 empty-dir-pod的Pod,该 Pod 中创建一个名称为 shared-data 的 emptyDir 类型的数据卷,然后使用 busybox:latest 镜像创建了两个容器,且这两个容器都将该数据卷挂载了容器内部的 /data 目录,名称为 write-shared-data 的容器会往 /data/shared-data.txt 文件中写一句 “hello world”,名称为 read-shared-data 的容器会把 /data/shared-data.txt 文件中的内容打印出来。

  • 创建容器:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 容器创建容器,执行结果如下图所示:

    kubectl apply -f empty-dir-pod.yaml
    

    在这里插入图片描述

  • 查看日志:上述容器执行成功之后,即可通过在 Kubernetes 集群的 Master 节点中执行以下命令查看 read-shared-data 容器的执行日志,结果如下图所示,则说明 write-shared-data 成功的将数据写入到了emptyDir 中,而且 read-shared-data 成功的从 emptyDir 中读取到了数据。

    kubectl logs -f empty-dir-pod -c read-shared-data
    

    在这里插入图片描述

2.3 hostPath

  • 作用说明:hostPath 的作用是把 Node 节点上的文件或者目录挂载到 Pod中 的容器。由于 Pod 在重新生成时,可能会更换 Node 节点,从而导致原先的 hostPath 无法使用。

  • 实战需求:Pod中 的容器访问宿主机(即 Node 节点)中的文件。

  • 编写yaml:在 Kubernetes 集群的 Master 节点中创建一个名为 host-path-pod.yaml 的文件,其内容如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: host-path-pod
    spec:
      containers:
      - name: read-host-data
        image: busybox:latest
        command: ["/bin/sh", "-c", "cat /etc/docker/daemon.json"]
        volumeMounts:
        - name: host-data
          mountPath: /etc
      volumes:
      - name: host-data
        hostPath:
          path: /etc
          type: Directory
      restartPolicy: Never
    
  • yaml说明:上述yaml文件中创建了一个名称为 host-path-pod 的 Pod,该 Pod 中创建一个名称为 host-data 的 hostPath 类型的数据卷,该数据卷映射到 Node 节点的 /etc 目录,然后使用 busybox:latest 镜像创建了一个名称为 read-host-data 的容器,该容器将该数据卷挂载了容器内部的 /etc 目录,并且会把 /etc/docker/daemon.json 文件中的内容打印出来。

  • 创建容器:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 容器创建容器,执行结果如下图所示:

    kubectl apply -f host-path-pod.yaml
    

    在这里插入图片描述

  • 查看日志:上述容器执行成功之后,即可通过在 Kubernetes 集群的 Master 节点中执行以下命令查看 read-host-data 容器的执行日志,结果如下图所示,则说明 read-host-data 成功从 hostPath 中读取到了数据。

    kubectl logs -f host-path-pod
    

    在这里插入图片描述

2.4 configMap

  • 作用说明:configMap 的作用是存储应用程序配置,例如配置文件,或配置项等,并通过环境变量或挂载的方式传给 Pod 中的容器使用,由于 configMap 对于存储的配置信息的安全性较低,因此,不建议把密码、OAuth Token 等敏感信息保存在 configMap 中。
  • 详情链接:configMap 的详细应用请见 Kubernetes基于ConfigMap实现配置分离

2.5 secret

2.6 nfs

  • 作用说明:Kubernetes 除了可以使用 emptyDir、hostPath、configMap、secret 等类型的数据卷把数据存储在 Kubernetes 集群内部的的节点可 Pod 中,还可以使用 nfs 等类型的数据卷把数据存储在远程的 NFS 服务器中。

  • 特别说明:本小节中使用的 NFS 服务器的搭建过程请见下面的第3节。

  • 实战需求:Pod 中的容器将运行日志保存到 NFS 服务器中。

  • 编写yaml:在 Kubernetes 集群的 Master 节点中创建一个名为 nfs-pod.yaml 的文件,其内容如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nfs-pod
    spec:
      containers:
      - name: write-nfs-data
        image: busybox:latest
        command: ["/bin/sh", "-c", "echo 'hello world' >> /mnt/nfs/logs/log.txt"]
        volumeMounts:
        - name: nfs-data
          mountPath: "/mnt/nfs/logs"
      volumes:
      - name: nfs-data
        nfs:
          path: /mnt/nfs
          server: nfs.k8s.com
      restartPolicy: Never
    
  • yaml说明:上述 yaml 文件中创建了一个名称为 nfs-pod 的 Pod,该 Pod 中创建一个名称为 nfs-data 的 nfs 类型的数据卷,该数据卷映射到了域名为 nfs.k8s.com 的 NFS 服务器的 /mnt/nfs 目录,然后使用 busybox:latest 镜像创建了一个名称为 write-nfs-data 的容器,该容器将该数据卷挂载了容器内部的 /mnt/nfs/logs 目录,并模拟把容器的运行日志保存到容器内部的 /mnt/nfs/logs/log.txt 文件中,即保存到了 NFS 服务器中的 /mnt/nfs 目录中。

  • 创建容器:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 容器创建容器,执行结果如下图所示:

    kubectl apply -f nfs-pod.yaml
    

    在这里插入图片描述

  • 查看日志:上述容器执行成功之后,即可通过在 NFS 服务器中的 Shell 命令行客户端中执行以下命令查看 write-nfs-data 容器是否把运行日志保存到了 NFS 服务器的 /mnt/nfs 目录下,结果如下图所示,则说明 write-nfs-data 成功把运行日志保存到了 nfs 类型的数据卷中了。

    ll /mnt/nfs
    
    cat /mnt/nfs/log.txt
    

在这里插入图片描述

2.7 persistentVolumeClaim

  • 作用说明:Kubernetes 可以使用 PersistentVolumeClaim 持久卷声明类型的数据卷来保存数据,这种类型的数据卷只是一个数据卷声明,而并没有指定数据卷的具体实现方式,从而实现了数据卷的实现和使用解耦的目的。PersistentVolumeClaim 类型的数据卷的实现形式有很多种,具体请见 Kubernates官方说明文档

  • 使用说明:需要先创建 PersistentVolume 持化卷(表示具体的存储资源),然后再创建 PersistentVolumeClaim 持久卷声明(与具体的 PersistentVolume 持久卷绑定),最后再在 Pod 挂载 PersistentVolumeClaim 类型的持久卷并进行使用。

  • 特别说明:本小节中使用的 NFS 服务器的搭建过程请见下面的第3节。

  • 实战需求:Pod 中的容器通过持久化卷将运行日志保存在 NFS 服务器中。

2.7.1 创建persistentVolume

  • 创建yaml:在 Kubernetes 集群的 Master 节点中创建一个名为 nfs-pv.yaml 的文件,其内容如下所示:

    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: nfs-pv
    spec:
      capacity:
        storage: 1Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      persistentVolumeReclaimPolicy: Recycle
      storageClassName: slow
      nfs:
        path: /mnt/nfs
        server: nfs.k8s.com
    
  • yaml说明:上述 yaml 文件中创建了一个名称为 nfs-pv 的持久卷,该持久卷映射到了域名为 nfs.k8s.com 的 NFS 服务器的 /mnt/nfs 目录,并且容量大小为 1G、卷模式为 Filesystem、访问模式为 ReadWriteMany、回收策略为 Recycle。

  • 创建持久卷:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 创建持久卷,执行结果如下图所示:

    kubectl apply -f nfs-pv.yaml
    

    在这里插入图片描述

  • 查看持久卷:在 Kubernetes 集群的 Master 节点中执行以下命令即可查看创建成功的持久卷,此时该持久卷应该是 Available 的状态,结果如下图所示:

    kubectl get pv
    

    在这里插入图片描述

2.7.2 创建persistentVolumeClaim

  • 创建yaml:在 Kubernetes 集群的 Master 节点中创建一个名为 nfs-pvc.yaml 的文件,其内容如下所示:

    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: nfs-pvc
    spec:
      resources:
        requests:
          storage: 1Gi
      volumeMode: Filesystem
      accessModes:
        - ReadWriteMany
      storageClassName: slow
    
  • yaml说明:上述 yaml 文件中创建了一个名称为 nfs-pvc 的持化卷声明,该持化卷声明请求容量大小为 1G、卷模式为 Filesystem、访问模式为 ReadWriteMany 的持久卷,如果 Kubernetes 集群中在满足该条件且状态为 Available 的持久卷,则该持久卷声明会绑定到满足条件的持久卷,如果没有,则不会绑定。

  • 创建持久卷声明:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 创建持久卷声明,执行结果如下图所示:

    kubectl apply -f nfs-pvc.yaml
    

    在这里插入图片描述

  • 查看持久卷声明:在 Kubernetes 集群的 Master 节点中执行以下命令即可查看创建成功的持久卷声明,此时该持久卷声明的状态为 Bound,说明该持久卷已经绑定到了具体的持久卷上了,结果如下图所示:

    kubectl get pvc
    

    在这里插入图片描述

  • 查看持久卷:在 Kubernetes 集群的 Master 节点中执行以下命令再次查看持久卷,此时在2.7.2节中创建的持久卷的状态为 Bound,说明该持久卷已经绑定到了某一持久卷声明上了,结果如下图所示:

    kubectl get pv
    

    在这里插入图片描述

2.7.3 使用persistentVolumeClaim

  • 创建yaml:上述成功创建了持久卷和持久卷声明,且持久卷和持久卷声明成功绑定在一起了,则可以在 Pod 挂载持久卷声明,并使用持久卷了。在 Kubernetes 集群 Master 节点中创建一个名为 nfs-pvc-pod.yaml 的文件,其具体内容如下所示:

    apiVersion: v1
    kind: Pod
    metadata:
      name: nfs-pvc-pod
    spec:
      containers:
      - name: write-nfs-pvc-data
        image: busybox:latest
        command: ["/bin/sh", "-c", "echo 'hello world' >> /mnt/nfs/logs/pvc-log.txt"]
        volumeMounts:
        - name: nfs-pvc-data
          mountPath: /mnt/nfs/logs
      volumes:
      - name: nfs-pvc-data
        persistentVolumeClaim:
          claimName: nfs-pvc
      restartPolicy: Never
    
  • yaml说明:上述 yaml 文件中创建了一个名称为 nfs-pvc-pod 的 Pod,并将名称为 nfs-pvc 且类型为 persistentVolumeClaim 的持久卷声明挂载到了该 Pod 的 /mnt/nfs/logs 目录,并模拟把容器的运行日志保存到容器内部的 /mnt/nfs/logs/pvc-log.txt 文件中,即保存到了 NFS 服务器中。

  • 创建容器:在 Kubernetes 集群的 Master 节点中执行以下命令即可使用上述 yaml 容器创建容器,执行结果如下图所示:

    kubectl apply -f nfs-pvc-pod.yaml
    

    在这里插入图片描述

  • 查看日志:上述容器执行成功之后,即可通过在 NFS 服务器中的 Shell 命令行客户端中执行以下命令查看 nfs-pvc-data 容器是否把运行日志保存到了 NFS 服务器的 /mnt/nfs 目录下,结果如下图所示,则说明 nfs-pvc-data 成功把运行日志保存到了 nfs 类型的数据卷中了。

    ll /mnt/nfs
    
    cat /mnt/nfs/pvc-log.txt
    

    在这里插入图片描述

2.7.4 persistentVolume的补充说明

  • 访问模式:PersistentVolume 有三种访问模式,分别是 ReadWriteOnce(持久卷可以被一个节点以读写方式挂载)、ReadWriteMany(持久卷可以被多个节点以读写方式挂载)、ReadOnlyMany(持久卷可以被多个节点以只读方式挂载)。

  • 回收策略:当用户不再使用 PersistentVolume 时,可以将 PersistentVoumeClaim 对象删除,从而允许 PersistentVolume 资源被回收再利用。PersistentVolume 对象的回收策略告诉集群,当其被从 PersistentVoumeClaim 中释放时如何处理该持久卷。 持久卷的回收策略有三种,分别是 Retained(保留)、Recycled(回收)或 Deleted(删除)。

  • 卷模式:针对 PersistentVolume 持久卷,Kuberneretes 支持两种卷模式:Filesystem(文件系统) 和 Block(块)。 默认的卷模式是 Filesystem,如果volumeMode 属性设置为 Filesystem ,则持久卷会被 Pod 挂载到某个目录。

3 Kubernetes使用NFS服务

3.1 环境说明

3.2 NFS服务端搭建

  • 安装软件:搭建 NFS 服务器,需要安装 nfs-utils 和 rpcbind 软件,由于 CentOS 7.6 已经安装了 rpcbind,所以只需要安装 nfs-utils 即可。在要安装 NFS 服务端的主机上(本文是在K8S集群中的k8s-harbor节点中安装)执行以下 Shell 命令即可安装 NFS 服务端。

    yum install -y nfs-utils
    
  • 创建目录:安装完成之后,需要创建一个目录,用作 NFS 共享目录,并且需要给该目录设置权限,执行 Shell 命令如下所示:

    mkdir /mnt/nfs
    
    chmod -R a+w  /mnt/nfs
    
  • 修改配置:NFS 服务端安装成功之后,需要在 NFS 的配置文件 /etc/exports 中指定允许来自哪些 IP 地址的主机访问 NFS 服务,由于本文中的 Kubernetes 集群所有节点都在 192.168.1.0/24 网段中,所以需要在 /etc/exports 文件中添加以下内容。

    /mnt/nfs/ 192.168.1.0/24(rw,sync,no_root_squash)
    
  • 启动服务:执行以下 Shell 命令启动 nfs-server 服务。

    systemctl start nfs-server.service
    
  • 配置生效:执行以下 Shell 命令使用上述配置生效。

    exportfs -r
    
  • 检查配置:执行以下命令检查上述配置是否生效,执行命令后,会显示出已生效的配置,结果截图如下所示。

    exportfs
    

    在这里插入图片描述

  • 开机启动:执行以下 Shell 命令使 nfs-server 服务开机自动启动。

    systemctl enable nfs-server.service
    
  • 特别说明:在使用 NFS 客户端连接 NFS 服务端的时候可能会报错 clnt_create: RPC: Port mapper failure - Unable to receive: errno 113 (No route to host) ,这是因为 NFS 服务端防火墙的问题,可以关闭防火墙来解决(生产环境不推荐这样解决)。

    systemctl stop firewalld
    

3.3 NFS客户端搭建

  • 添置域名映射:由于本文中的 Kubernetes 集群中的节点无法解析域名 nfs.k8s.com,所以需要在 Kubernetes 集群中所有的 Worker 节点的域名解析文件 /etc/hosts 中添加以下内容(192.168.1.18 为本文中的 NFS 服务器的 IP 地址)。

    192.168.1.18 nfs.k8s.com
    
  • 安装软件:这里安装 NFS 客户端,是为了检查 NFS 服务端的服务是否可以正常访问,因此,只需要安装 nfs-utils 软件,而不需要启动 nfs 服务。在 Kubernetes 集群中的某一 Worker 节点中执行以下 Shell 命令即可安装 nfs-utils 软件。

    yum install -y nfs-utils
    
  • 查看服务状态:nfs-utils 软件安装成功之后,即可执行以下 Shell 命令检查 NFS 服务是否可以正常访问,结果如下图所示则表示可以正常访问,如果 NFS 服务可以正常访问,则 Kubernetes 集群中就可以通过本文的 2.6 节和 2.6 节中介绍的两种方式使用 NFS 服务存储数据了。如果还需要主机中通过 nfs-client 客户端访问 nfs-server 服务端了,则需要继续完成后面的步骤。

    showmount -e nfs.k8s.com
    

    在这里插入图片描述

  • 创建目录:在 nfs-client 客户端中创建一个目录,用于挂载 NFS 服务端的共享目录。

    mkdir /mnt/nfs
    
  • 挂载目录:在 nfs-client 客户端中执行以下 Shell 命令挂载 NFS 共享目录。

    mount -t nfs nfs.k8s.com:/mnt/nfs /mnt/nfs
    
  • 开机自动挂载:如果希望 nfs-client 客户端所在的主机在启动后自动挂载 NFS 共享目录,则可以在 nfs-client 客户端所在的主机中的配置文件 /etc/fstab 中加入以下内容。

    nfs.k8s.com:/mnt/nfs /mnt/nfs nfs defaults,_netdev 0 0
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第一章介绍docker的前世今生,了 解docker的实现原理,以Django项目为例,教大家如何编写最佳的Dockerfile实现构业务镜像的制作。通过本章的学习,大家会知道docker的概念及基本操作,并学会构建自己的业务镜像,并通过抓包的方式掌握Docker最常用的bridge网络模式的通信。第二章本章学习kubernetes的架构及工作流程,重点介绍如本章学习kubernetes的架构及工作流程,重点介绍如断的滚动更新,通过服务发现来实现集群内部的服务间访问,并通过ingress- -nginx实现外部使用域名访问集群内部的服务。同时介绍基于EFK如何搭建Kubernetes集群的日志收集系统。学完本章,我们的Django demo项目已经可以运行在k8s集群中,同时我们可以使用域名进行服务的访问。第三章本章基于k8s集群部署gitlab、sonarQube、 Jenkins等工具,并把上述工具集成到Jenkins中,以Django项目为例,通过多分支流水线及Jenkinsfle实现项目代码提交到不同的仓库分支,实现自动代码扫描、单元测试、docker容器构建、k8s服务的自动部署。第四章由于公司内部项目众多,大量的项目使用同一套流程做CICD,那么势必会存在大量的重复代码,因此本章主要通过使用groovy实现Jenkins的sharedL ibrary的开发,以提取项目在CICD实践过程中的公共逻辑,提供一系列的流程的接口供公司内各项目调用,开发完成后,还是以Django的demo项目为例,进行Jenkinsfle的改造,最后仅需通过简单的Jenkinsfle的配置,即可优雅的完成CICD流程的整个过程,此方式已在大型企业内部落地应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值