【十期/11章/16:33】
1、Volume
2、PersistentVolume(PV)
3、PersistentVolume 动态供给
本地卷:hostPath、emptyDir
网络卷:nfs、ceph(cephfs,rbd)、glusterfs
公有云:aws、azure
k8s资源:downwardAPI、configMap、secret
Volume
- Kubernetes中的Volume提供了在容器中挂载外部存储的能力
- Pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可以使用相应的Volume
说明:Volume是Kubernetes Pod中多个容器访问的共享目录。Volume被定义在pod上,被pod的多个容器挂载到相同或不同的路径下。Pod内的容器停止和重启一般不会影响Volume中的数据。所以一般Volume被用于持久化Pod产生的数据
Volume 的主要作用是用于跨节点或者容器对数据进行同步和共享。在K8S集群之中,Pod会在各个节点之间漂移,如何保障Pod的数据持久和不同节点数据的共享,Kubernetes提出了存储卷Volume的概念。
emptyDir
- 创建一个空卷,挂载到Pod中的容器。Pod删除该卷也会被删除(与Pod绑定在一起的)
- 应用场景:Pod中容器之间数据共享
说明:emptyDir创建用于pod被调度到某个宿主机上时,同一个pod内的容器都能够读写emptyDir中的同一个文件。一旦这个pod离开了宿主机,emptyDir中的数据就会被永久删除。所以emptyDir主要用作临时空间,比如web服务器写日志或者tmp文件需要的临时目录。
emptyDir在pod分配到node上时被创建出来,kubernetes会在node上自动分配一个目录,因此无需指定宿主机node上对应的目录文件。这个目录的初始内容为空,当Pod从node上移除时,emptyDir中的数据会被永久删除
事例(emptyDir的yaml):
# 首先创建一个emptydir.yaml
vim emptydir.yaml
# 如下是emptydir的yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data # “卷”的挂载点
- name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data
volumes: # 该参数指的是“卷的来源”
- name: data
emptyDir: {}
# 创建emrtydir.yaml
kubectl apply -f emptydir.yaml
# 查看该pod的日志
kubectl logs -f my-pod -c <container name> -f
# 查看该pod创建在哪个node上
kubectl get pod -o wide
# 到该node节点中查看emptydir的文件
docker ps 查看容器名,找到对应的Pod ID(因ID对应的是下面/var/lib/kubelet/pods/目录下的一长串)
# 查看emtpydir空卷所在哪个目录
cat /var/lib/kubelet/pods/<Pod ID>/volumes/kubernetes.io~empty-dir/data/...
hostPath
- 挂载Node文件系统上文件或者目录到Pod中的容器
- 应用场景:Pod中容器需要访问宿主机文件
说明:hostPath是Pod挂载宿主机上的目录或文件,使容器可以使用宿主机进行存储。
缺点:在k8s中,pod都是动态在各node节点上调度。当一个pod在当前node节点上启动并通过hostPath存储文件到本地以后,下次调度到另一个节点上启动时,就无法使用之前节点上存储的文件。
# 创建并应用hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod-2
spec:
containers:
- name: busybox
image: busybox
args:
- /bin/sh
- -c
- sleep 36000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
hostPath:
path: /tmp # 该参数为指定宿主机的文件或目录,挂载到上面容器的/data中,就形成了映射关系,创建文件同时拥有
type: Directory
# 应用hostpath.yaml
kubectl apply -f hostpath.yaml
# 进入并查看pod中的/data目录下的文件
kubectl get pod
kubectl exec -it <pod name> sh
ls /data
# 进入pod的节点中查看yaml数据源中的/tmp下的文件
cat /tmp # 验证结果证明两边数据是一致的(也可以在node中创建个文件并验证pod容器中是否也创建了)
PersistentVolume
- PersistentVolume(PV:持久卷):对存储资源创建和使用的抽象,使存储作为集群中的资源管理
说明:PV是集群中的一块网络存储,与Node一样,也是集群的资源。PV与Volume(卷)类似。
- PersistentVolumeClaim(PVC:持久卷申请):让用户不需要关心具体的Volume实现细节
说明:PVC是一个用户的请求,与Pod类似。Pod消费Node的资源,PVC消费PV的资源。
供应:
集群管理员会创建一系列PV,这些PV包含了为集群用户提供的真实存储资源
绑定:
用户创建一个包含了容量和访问模式的持久卷申请,Master会监听PVC的产生,并尝试根据请求内容查找匹配的PV,并把PV和PVC进行绑定。用户能够获取满足需要的资源,并且在使用过程中可能超出请求数量。
如果未找到合适的卷,这一申请就会持续处于非绑定状态,一直到出现合适的PV。例如一个集群准备
了很多50G的持久卷,虽然总量足够,但也无法满足100G的申请,除非把100G的PV加入集群中。
使用:**
集群通过PVC查找绑定的PV,并Mount给Pod。对于支持多种访问方式的卷,用户在使用PVC作为卷的时候,可以指定需要的访问方式。
# 创建并应用pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00001
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes/pv00001
server: 192.168.100.162 # 指定节点的IP
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00002
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes/pv00002
server: 192.168.100.162 # 指定节点的IP
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv00003
spec:
capacity:
storage: 50Gi
accessModes:
- ReadWriteMany
nfs:
path: /ifs/kubernetes/pv00003
server: 192.168.100.162 # 指定节点的IP
# 应用pv.yaml
kubectl apply -f pv.yaml
# 查看创建的pv
kubectl get pv
# 创建并应用pvc.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: web
name: web
spec:
replicas: 1
selector:
matchLabels:
app: web
strategy: {}
template:
metadata:
labels:
app: web
spec:
containers:
- image: nginx
name: nginx
resources: {}
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
# 应用pvc.yaml
kubectl apply -f pvc.yaml
# 查看pv状态pvc
kubectl get pv #查看pv是否为绑定状态
kubectl get pvc