Kubernetes(K8S)系列-卷(Volume)

393 阅读4分钟

概念

Kubernets的卷是Pod的一个组成部分,就像容器一样在Pod的规范中定义的。它们不是独立的Kubernetes对象,不能单独的创建和删除。可以在Pod中的所有容器中使用卷,但是前提必须将它挂载在每个需要访问它的容器中的文件系统中(可以是文件系统中的任意位置)。

卷的应用

例如一个带有三个容器的Pod,分别是:

  • 一个运行web服务器的容器,html位于/var/htdocs,日志存储于/var/logs中。
  • 一个运行nginx代理服务器的容器,将它们存放在/var/html中。
  • 一个运行日志处理服务的容器,处理/var/logs中的日志。 每一个容器都有明确的用途,但是如果容器间的数据无法共通,没有共享的存储磁盘的情况下,单独使用这三个容器创建对应的Pod就毫无意义了。 因此我们可以创建两个卷,并在这三个容器的适当路径上挂载它们。Linux允许在文件树中的任意位置挂载文件系统,通过相同的卷挂载到两个相同的文件中进行操作。这样容器之间就可以共享数据,对相同的文件进行操作。

首先创建一个名为publicHtml的卷,挂载在web服务容器中的/var/htdocs目录上,并且同时挂载在nginx服务容器的/var/html中。

同样创建一个logVol的卷,挂载在web服务容器中的/var/logs目录上,并且同时挂载在日志服务容器的/var/logs中。 具体效果如下:

三个容器共享卷.jpg

三个容器在一个Pod内通过两个共享的存储卷进行共享数据完成协作。

常用卷的类型

Kubernetes提供多种卷的类型选择。其中一些是通用的,而另一些相对于当前的存储技术有较大的差别的。以下是几种可用卷类型的列表:

  • emptyDir——用于存储临时数据的简单空目录。
  • hostPath——用于将目录从工作节点的文件系统挂载到Pod中。
  • gitRepp——通过检出Git仓库的内容来初始化的卷。
  • nfs——挂载到pod中的NFS共享卷。
  • gcePersistentDisk(Google高效能型存储磁盘卷),awsElasticBlockStore(AmazonWeb服务弹性块存储),azureDisk(Microsoft Azure磁盘卷)——用于挂载云服务商提供的特定存储类型。
  • cinder,cephfs,iscsi,flocker,glusterfs,quobyte,rbd,flexVolume,vsphere-Volume,photoPersistentDisk,scaleIO——挂载其他类型的网络存储。
  • configMap,secret,downwardAPI——用于将Kubernetes部分资源和集群信息公开给Pod的特殊类型的卷。
  • persistentVolumeClaim——一种使用预置或者动态配置的持久存储类型 单个容器可以同时使用不同类型的多个卷。现在我们来介绍以下的几个常用卷

emptyDir卷

emptyDir卷是最简单的卷类型,顾名思义,卷从一个空目录开始,运行的pod内的应用程序可以写入它们需要的任何文件,删除pod时,对应的卷的内容也会丢失。
创建emptyDir卷的例子:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
   volumes: #定义一个emptyDir卷
     - name: html
       emptyDir: {}
          

创建emptyDir卷实际上是在承载pod的工作节点上的实际磁盘的基础上创建的。

gitRepo卷

gitRepo卷基本上也是一个emptyDir卷,它通过克隆Git仓库并在pod启动时(在创建容器前),检出特定版本来填充数据。
gitRepo卷例子:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
   volumes: 
     - name: html
       gitRepo: 
         repository: https://github.com/kubernetes-client/java.git
         revision: master
         directory: . # 卷的根目录

gitRepo容器就像emptyDir卷一样,是一个专用目录,专门用于包含卷的容器并单独使用,当pod被删除时,卷及其内容也会被删除。

hostPath卷

hostPath卷指向节点文件系统上的特定文件或目录。在同一个节点上运行并在其hostPath卷中使用相同路径的pod可以看到相同的文件。

hostPath卷是一种持久性存储,不同于gitRepo卷和emptyDir卷,它们存储的内容在pod删除的时候也会一并被删除,但是hostPath卷的内容不会被删除。如果删除了一个pod,并且下一个pod指向了主机的相同路径的hostPath卷,则新pod将会发现上一个pod留下的数据。但是前提是必须调度于同一个工作节点上(这就是为什么不考虑将hostPath卷作为数据库的持久化存储)。
hostPath样例:

apiVersion: v1
kind: Pod
metadata:
  name: web
  labels:
    role: myrole
spec:
  containers:
    - name: web
      image: nginx
      ports:
        - name: web
          containerPort: 80
          protocol: TCP
      volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
   volumes: 
     - name: html
       Type: HostPath
       Path: /var/html

hostPath卷通常用于单节点的持久化存储。

参考资料

Kubernetes in Action中文版