卷是Pod的一部分,与Pod共享生命周期。它不是独立的Kubernetes对象,因此不能单独创建。
卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享。
一些卷的类型:
emptyDir:用于存储临时数据的空目录
hostPath:用于将目录从工作节点挂载到pod
gitRepo:通过检出Git仓库的内容来初始化的卷
nfs:挂载到pod中的nfs共享卷
configMap、secret、downwardAPI:用于将Kubernetes部分资源和集群信息公开给pod的特殊类型的卷
persistentVolumeClaim:一种使用预置或者动态配置的持久存储类型
单个容器可以同时使用不同类型的多个卷。
emptyDiremptyDir卷对于在同一个pod中运行的容器之间共享文件特别有用。但也可以被单个容器用于将数据临时写入磁盘。
下面的例子中,Pod包含两个容器,这个两个容器分别将卷html挂载到容器内的不同路径,实现了文件共享。html-generator每隔一秒写入当前时间到index.html,web-server提供web服务使index.html可以被访问。
# volume-share-pod.yaml apiVersion: v1 kind: Pod metadata: name: volume-share spec: containers: - image: alpine # 容器镜像一 name: html-generator volumeMounts: # 将名为html的卷挂载到容器的/var/html - name: html mountPath: /var/html command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"] - image: nginx:alpine #容器镜像二 name: web-server volumeMounts: # 与上面相同的卷卷挂载到容器的/usr/share/nginx/html - name: html mountPath: /usr/share/nginx/html readOnly: true ports: - containerPort: 80 volumes: # 创建一个名为html的卷 - name: html emptyDir: {}创建pod,设置端口转发
-> [root@kube0.vm] [~] k create -f volume-share-pod.yaml pod/volume-share created -> [root@kube0.vm] [~] k port-forward volume-share 80:80 Forwarding from 127.0.0.1:80 -> 80 Forwarding from [::1]:80 -> 80发出请求
-> [root@kube0.vm] [~] curl Sun May 24 01:14:48 UTC 2020 -> [root@kube0.vm] [~] curl Sun May 24 01:14:49 UTC 2020如果进行下面的改动,emptyDir的内容会存在内存中
volumes: - name: html emptyDir: medium: Memory gitRepogitRepo卷基本上也是一个emptyDir卷,它在容器启动前从git仓库检出填充数据。
当git仓库内容发生改变时,对已存在的Pod内的gitRepo卷是不可见的。但启动新的Pod时会检出最新的。
下面的例子中,该pod创建了一个名为html的gitRepo卷的,创建一个提供web服务的容器web-server,并将卷html挂载到web-server的/usr/share/nginx/html。
# volume-gitrepo-pod.yaml apiVersion: v1 kind: Pod metadata: name: volume-gitrepo spec: containers: - image: nginx:alpine name: web-server volumeMounts: - name: html mountPath: /usr/share/nginx/html readOnly: true ports: - containerPort: 80 volumes: # 创建一个名为html的gitRepo卷 - name: html gitRepo: repository: https://github.com/orccn/kube-dockerfile.git # 仓库地址 revision: master # 分支 directory: . # 检出到卷的根目录创建pod,设置端口转发
-> [root@kube0.vm] [~] k create -f volume-gitrepo-pod.yaml pod/volume-gitrepo created -> [root@kube0.vm] [~] k port-forward volume-gitrepo 80:80 Forwarding from 127.0.0.1:80 -> 80 Forwarding from [::1]:80 -> 80发出请求
-> [root@kube0.vm] [~] curl FROM k8s.gcr.io/etcd:3.4.3-0 hostPathhostPath卷提供的是映射到工作节点本地的持久存储。所以应仅当需要在工作节点上读写文件时才使用hostPath
下例中,Pod中创建一个名为html的hostPath卷挂载到工作节点的 /tmp/html,容器volume-hostpath将卷html挂载到/var/html,并且向其中写入文件。
# volume-hostpath-pod.yaml apiVersion: v1 kind: Pod metadata: name: volume-hostpath spec: containers: - image: alpine name: volume-hostpath command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"] volumeMounts: - name: html mountPath: /var/html volumes: - name: html hostPath: path: /tmp/html创建volume-hostpath,查看其部署在哪个节点。
-> [root@kube0.vm] [~] k create -f volume-hostpath-pod.yaml pod/volume-hostpath created -> [root@kube0.vm] [~] k get po -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES volume-hostpath 1/1 Running 0 9m32s 10.244.1.11 kube1.vm <none> <none>进入节点kube1.vm
-> [root@kube1.vm] [~] cat /tmp/html/index.html Sun May 24 02:26:14 UTC 2020 PV与PVCPV(PersistentVolume持久卷)也是一种资源,并且不属于任何命名空间。它的功能与卷类似,但是它的生命周期是独立于Pod的。PV由集群管理员创建,并被Pod通过PVC(PersistentVolumeClaim,持久卷声明)使用。
在创建PV时,管理员可以指定其大小和支持的访问模式:
ReadWriteOnce(RWO):仅允许单个节点挂载读写
ReadOnlyMany(ROX):允许多个节点挂载只读
ReadWriteMany(RWX):允许多个节点挂载读写
一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。
创建PV