学习本节内容前,希望你已经对Docker中volume的概念有了初步的了解。
Volume是Pod中能够被多个容器共享的磁盘目录。我们知道,默认情况下Docker容器中的数据都是非持久化的,在容器消亡后数据也会消失。因此Docker提供了Volume机制以便实现数据的持久化。Kubernetes中Volume的概念与Docker中的Volume类似,但不完全相同。具体区别如下:
- Kubernetes中的Volume与Pod的生命周期相同,但与容器的生命周期不相关。当容器终止或重启时,Volume中的数据也不会丢失。
- 当Pod被删除时,Volume才会被清理。并且数据是否丢失取决于Volume的具体类型,比如emptyDir类型的Volume数据会丢失,而PV类型的数据则不会丢失。
Kubernetes提供了非常丰富的Volume类型,下面是一些常用的Volume类型:
- emptyDir
- hostPath
- gcePersistentDisk
注意,这些 volume 并非全部都是持久化的,比如 emptyDir、secret、gitRepo 等,这些 volume 会随着 Pod 的消亡而消失。
emptyDir
一个emptyDir volume是在Pod分配到Node时创建的。顾名思义,它的初始内容为空,在同一个Pod中的所有容器均可以读写这个emptyDir volume。当 Pod 从 Node 上被删除(Pod 被删除,或者 Pod 发生迁移),emptyDir 也会被删除,并且数据永久丢失。
一个简单的例子:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
emptyDir类型的volume适合于以下场景:
- 临时空间。例如某些程序运行时所需的临时目录,无需永久保存。
- 一个容器需要从另一容器中获取数据的目录(多容器共享目录)
hostPath
hostPath类型的volume允许用户挂在Node上的文件系统到Pod中,如果 Pod 需要使用 Node 上的文件,可以使用 hostPath。
一个简单的例子:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory
hostPath支持type属性,它的可选值如下:
hostPath.PNG
hostPath volume通常用于以下场景:
- 容器中的应用程序产生的日志文件需要永久保存,可以使用宿主机的文件系统进行存储。
- 需要访问宿主机上Docker引擎内部数据结构的容器应用,通过定义hostPath为/var/lib/docker目录,使容器内应用可以直接访问Docker的文件系统。
在使用hostPath volume时,需要注意:
- 在不同的Node上具有相同配置的Pod,可能会因为宿主机上的目录和文件不同,而导致对Volume上目录和文件的访问结果不一致。
gcePersistentDisk
gcePersistentDisk 可以挂载 GCE(Google Compute Engine) 上的永久磁盘到容器,需要 Kubernetes 运行在 GCE 的 VM 中。需要注意的是,你必须先创建一个永久磁盘(Persistent Disk,PD)才能使用gcePersistentDisk volume。
volumes:
- name: test-volume
# This GCE PD must already exist.
gcePersistentDisk:
pdName: my-data-disk
fsType: ext4
awsElasticBlockStore
与gcePersistentDisk类似,awsElasticBlockStore 使用Amazon Web Service(AWS)提供的EBS Volume,挂在到Pod中。需要 Kubernetes 运行在 AWS 的 EC2 上。另外,需要先创建一个EBS Volume才能使用awsElasticBlockStore。
volumes:
- name: test-volume
# This AWS EBS volume must already exist.
awsElasticBlockStore:
volumeID: <volume-id>
fsType: ext4
nfs
NFS 是 Network File System 的缩写,即网络文件系统。Kubernetes 中通过简单地配置就可以挂载 NFS 到 Pod 中,而 NFS 中的数据是可以永久保存的,同时 NFS 支持同时写操作。
volumes:
- name: nfs
nfs:
# FIXME: use the right hostname
server: 10.254.234.223
path: "/"
gitRepo
通过挂在一个空目录,并从GIT仓库克隆一个repository供Pod使用。
volumes:
- name: git-volume
gitRepo:
repository: "git@somewhere:me/my-git-repository.git"
revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
使用 subPath
Pod 的多个容器使用同一个 Volume 时,subPath 非常有用。
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
关于
persistentVolumeClaim
,请参考:Kubernetes对象之PersistentVolume,StorageClass和PersistentVolumeClaim
网友评论