Kubernetes volumes简介

Kubernetes volumes简介

  容器中的磁盘文件生命周期比较短暂,在一些比较复杂的容器应用中会产生一些问题。1、容器crash后,kubelet会重启该容器,但这些文件会丢失掉。2、pod中的多个容器常常须要共享文件。所以,Kubernetes的Volume应然而生,用于解决这些问题。php

背景

  在Docker中,也有volumes这个概念,volume只是磁盘上一个简单的目录,或者其余容器中的volume。生命周期也不受管理,而且直到最近他们都是基于本地后端存储的。Docker如今也提供了volume driver,可是如今来讲功能也较弱(好比官网提到的Ceph volume driver,如今已经没有维护了)。
  Kubernetes的volume,有着明显的生命周期——和使用它的pod生命周期一致。所以,volume生命周期就比运行在pod中的容器要长久,即便容器重启,volume上的数据依然保存着。固然,pod再也不存在时,volume也就消失了。更重要的是,Kubernetes支持多种类型的volume,而且pod能够同时使用多种类型的volume。
  内部实现中,volume只是一个目录,目录中可能有一些数据,pod的容器能够访问这些数据。这个目录是如何产生的,它后端基于什么存储介质,其中的数据内容是什么,这些都由使用的特定volume类型来决定。
  要使用volume,pod须要指定volume的类型和内容(spec.volumes字段),和映射到容器的位置(spec.containers.volumeMounts字段)。
  容器中的进程能够看到Docker image和volumes组成的文件系统。Docker image处于文件系统架构的root,任何volume都映射在镜像的特定路径上。Volume不能映射到其余volume上,或者硬连接到其余volume。容器中的每一个容器必须堵路地指定他们要映射的volume。html

Volume类型

  Kubernetes支持不少种类的volume,包括:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、flocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PortworxVolume、ScaleIO。node

emptyDir

  当Pod被分配到一个Node上时,emptyDir volume就第一次被建立,只要Pod还运行在该Node上,该volume就一直存在。就像它名字里介绍的同样,它初始化时是空的。pod中的容器都可以彻底读写emptyDir volume中相同文件,即便volume可能被映射到每一个容器中不一样的路径下。任何状况下,一旦pod从该Node上移除了,emptyDir volume中的数据就被永久删除了。注意:容器crash并不会在Node上删除pod,所以emptyDir volume中的数据依然是安全的。
  emptyDir volume的使用场景有:
  1) 临时空间,如基于磁盘的排序场景等;
  2) 从crash中经过checkpointing作长时间的计算恢复;
  默认的,emptyDir volume能够存储在任何后端介质之上——普通磁盘、ssd或网络存储,这都取决于你的环境。然而,你也能够设置emptyDir.medium字段为Memory,告诉Kubernetes映射tmpfs(基于RAM的文件系统)。tmpfs速度很是快,但要当心它和磁盘不一样,一旦机器重启,tmpfs就会被清空,而且,tmpfs上写文件会受到容器内存的限制。
  pod示例:mysql

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

hostPath

  hostPath volume映射node文件系统中的文件或者目录到pod里。大多数Pod都不须要这个功能,但对于一些特定的场景,该特性仍是颇有做用的。这些场景包括:
  1) 运行的容器须要访问Docker内部结构:使用hostPath映射/var/lib/docker
  2) 在容器中运行cAdvisor,使用hostPath映射/dev/cgroups
  不过,使用这种volume要当心,由于:
  1) 配置相同的pod(如经过podTemplate建立),可能在不一样的Node上表现不一样,由于不一样节点上映射的文件内容不一样
  2) 当Kubernetes增长了资源敏感的调度程序,hostPath使用的资源不会被计算在内
  3) 宿主机下建立的目录只有root有写权限。你须要让你的程序运行在privileged container上,或者修改宿主机上的文件权限。
  pod示例:git

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: gcr.io/google_containers/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data

rbd

  rbd卷能够将Rados Block Device设备映射到pod中。当Pod被移除时,emptyDir卷的内容会被清空,和emptyDir不一样,rbd卷的内容还存在着,仅仅是卷被卸载掉而已。也就是说,rbd卷能够其上的数据一块儿,再次被映射,数据也能够在pod之间传递。
  重要:在使用rbd卷以前,你必须先安装Ceph环境。
  RBD的一个特性就是可以以只读的方式同时映射给多个用户使用。不幸的是,rbd卷只能被一个用户已可读写的模式映射——不能同时容许多个可写的用户使用。
  查看RBD example获取更多细节。github

cephfs

  cephfs卷能够将已经存在的CephFS卷映射到pod中。与rbd卷相同,当pod被移除时,cephfs卷的内容还存在着,仅仅是卷被卸载掉而已。另一点不一样的是,CephFS能够同时以可读写的方式映射给多个用户。
  查看CephFS example获取更多细节。web

使用subPath

  有时,能够在一个pod中,将同一个卷共享,使其有多个用处。volumeMounts.subPath特性能够用来指定卷中的一个子目录,而不是直接使用卷的根目录。
  这里有一个使用LAMP栈(Linux Apache Mysql PHP)的pod示例,该pod使用了一个共享的卷。HTML内容映射在它的html子目录,而数据库则保存在它的mysql目录。sql

apiVersion: v1
kind: Pod
metadata:
  name: my-lamp-site
spec:
    containers:
    - name: mysql
      image: mysql
      volumeMounts:
      - mountPath: /var/lib/mysql
        name: site-data
        subPath: mysql
    - name: php
      image: php
      volumeMounts:
      - mountPath: /var/www/html
        name: site-data
        subPath: html
    volumes:
    - name: site-data
      persistentVolumeClaim:
        claimName: my-lamp-site-data

资源

  emptyDir或者hostPath卷的存储介质(磁盘,SSD等)取决于kubelet根目录(如/var/lib/kubelet)所处文件系统的存储介质。如今没有限制emptyDir或者hostPath卷能使用的空间大小,也没有对容器或者pod的资源隔离。
  将来,咱们指望emptyDir或者hostPath卷可以经过resource属性,来请求指定大小的空间,而且选择存储介质类型。docker

总结

  Kubernetes的volume用于pod内部的数据存储,pod容器内部数据是能够共享的,其生命周期与所属pod生命周期相同。其用处通常是pod生命周期的临时数据存储等。数据库