容器中的磁盘文件是易失的,这给运行在容器中的大型应用带来了一些麻烦。首先,当一个容器崩溃,kubelet会重启它,但是之前存储的文件会丢失 - 容器以一个初始的状态重建。第二,当在一个Pod中运行多个container,这些container之间常常需要共享文件。Kubernetes的Volume抽象解决了这些问题。

背景

Docker中有Volumes的概念,其中对它的管理有点松散。在Docker中,一个volume就简单的是个磁盘或者其他容器中的目录,它的生命周期是不被管理的,并且在最近的Docker版本中还只支持基于本地磁盘的volume。Docker最新版本已经提供了volume驱动,但是它的功能目前还非常有限(例如,Docker 1.7中每个容器只允许有一个volume驱动,并且不能向volume传参)。

Kubernetes的volume有一个显式的生命周期 - 和持有它的Pod的生命周期相同。因此,一个volume比它所在Pod中的任何一个容器的生命周期都要长,并且容器重启后数据仍在。当然了,如果一个Pod不存在了,它的volume也就不存在了。更重要的是,Kubernetes支持不同类型的volume,并且一个Pod可以同时使用多个类型的volume。

一个volume只是一个目录,可能其中有一些数据,对于Pod中的容器是可访问的。这个目录是哪儿来的,支撑它的介质,以及它的内容物,都是由使用的特定volume类型决定的。

要使用一个volume,一个Pod指定提供给它的那些volume(.spec.volumes字段)以及挂载到容器的位置(.soec.containers.volumeMounts字段)。

容器中的一个进程,它看待文件系统是由Docker镜像以及一个或多个volume组成的。Docker镜像是文件系统层次的根,任何volume被挂载到镜像中的特定目录上。volume不能挂载到其他volume或者有到其他volume的硬链接(hard links)。Pod中的每个容器必须独立指定mount每个volume的位置。

Volume的类型

Kubernetes支持多种volume类型:

awsElasticBlockStore

awsElasticBlockStore卷在Pod中挂载一个Amazon Web Services(AWS)EBS Volume。不同于emptyDir在Pod移除时做擦除,一个EBS卷的内容一直保留,并且卷很少被卸载。这意味着一个EBS卷可以被预填充数据,并且数据可以在Pod间进行传递。

重要:在使用之前你必须使用aws ec2 create-volume或者AWS API创建一个EBS卷。

使用一个awsElasticBlockStore卷时,有几个限制:

  • Pod运行的Node必须是一个AWS EC2实例
  • 这些实例需要和EBS卷处于相同范围(region)以及可用区域(availability-zone)
  • 一个单独的EC2实例只支持挂载一个EBS卷

创建一个EBS卷

aws ec2 create-volume --availability-zone=eu-west-1a --size=10 --volume-type=gp2

要保证zone和k8s集群相同。(并需要检查size以及EBS卷类型是否合理)

AWS EBS实例配置

apiVersion: v1
kind: Pod
metadata:
  name: test-ebs
spec:
  containerss:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-ebs
      name: test-volume
  volumes:
  - name: test-volume
    # This AWS EBS volume must already exist.
    awsElasticBlockStore:
      volumeID: <volume-id>
      fsType: ext4 

azureDisk

azureDisk用于将一个Microsoft Azure Data Disk挂载到一个Pod中。

更多细节敲这里

emptyDir

一个emptyDir卷在Pod分配给Node时首次创建,并且只要Pod在节点上运行,它就一直存在。正如它的名字所说,它初始是空的。Pod中的容器可以在一个emptyDir卷中读写到相同文件,尽管这个卷可以挂载到不同容器的相同或不同的路径。当一个Pod由于某种原因从节点上移除,emptyDir中的数据也会被永久删除。

注意:一个容器崩溃并不会从一个节点移除所在Pod,因此在容器崩溃的条件下,emptyDir卷中的数据是安全的。

emptyDir的应用场景:

  • 临时的空间,例如用于一个基于磁盘的merge sort
  • 用于从崩溃恢复的长时计算
  • 保存一个内容管理容器获取的数据,这些数据用于一个webserver容器对外提供服务

默认情况下,emptyDir卷可以基于节点上的任何介质进行存储 - 可能是磁盘或者SSD或者网络存储,这取决于你的环境。你也可以设置emptyDir.medium字段为Memory,以告知Kubernetes为你挂载一个tmpfs(基于内存的文件系统)。不同于磁盘,tmpfs非常快,并且tmpfs在节点重启时会被擦除并且你写入的数据量取决于你的容器内存大小。

示例Pod

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumnMounts:
    - mountPath: /cache
      name: cache-volume
  volumes:
  - name: cache-volumne
    emptyDir: {}    

se7en
8 声望1 粉丝