Volume是Pod中能够被多个容器访问的共享目录。
K8s中的Volume定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下。
K8s中的Volume与Pod的生命周期相同,但与容器的生命周期不相关,当容器终止或者重启时,Volume中的数据也不会丢失。
K8s支持多种类型的Volume,例如GlusterFS、Ceph等先进的分布式文件系统。
Volume的使用也比较简单,在大多数情况下,先在Pod上声明一个Volume,然后在容器里引用该Volume并Mount到容器里的某个目录上。
例如要给Tomcat Pod增加一个名字为datavol的Volume,并且Mount到容器的/mydata-data目录上,则只要在Pod定义文件做如下定义即可:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
volumes:
- name: datavol
emptyDir: {}
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /mydata-data
name: datavol
imagePullPolicy: IfNotPresent
Volume可以让一个Pod里的多个容器共享文件、让容器的数据写到宿主机的磁盘上或者写文件到网络存储中,K8s的Volume还扩展出容器配置文件集中化定义与管理的功能,通过ConfigMap这个新的资源对象来实现的。
一个emptyDir Volume是在Pod分配到Node时创建的。从名称就可以看出,初始内容为空,并且无须指定宿主机上对应的目录文件,K8s会自动分配一个目录,当Pod从Node上移除时,emptyDir中的数据也会被永久删除。
emptyDir的一些用途如下:
hostPath用于在Pod上挂载宿主机上的文件或目录,通常可以用于以下几方面。
在使用这种类型的Volume时,需要注意以下几点。
在下面的例子中使用宿主机的/data目录定义了一个hostPath类型的Volume:
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
spec:
replicas: 2
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
volumes:
- name: "persistent-storage"
hostPath:
path: "/data"
containers:
- name: myweb
image: kubeguide/tomcat-app:v1
ports:
- containerPort: 8080
volumeMounts:
- mountPath: /mydata-data
name: persistent-storage
imagePullPolicy: IfNotPresent
使用NFS网络文件系统提供的共享目录存储数据时,需要在系统中部署一个NFS Server。定义NFS类型的Volume的示例如下:
volumes:
- name: nfs
nfs:
#NFS服务器地址
server: nfs-server.localhost
path: "/"
找一台服务器部署nfs服务端,安装nfs,设置挂载路径
安装nfs
yum install -y nfs-utils
mkdir -p /data/nfs
vim /etc/exports
/data/nfs *(rw,no_root_squash)
cd /data/nfs
vim hello.html
hello nfs
所有k8s集群node节点安装nfs
yum install -y nfs-utils
在nfs服务端启动nfs服务
systemctl start nfs
ps -ef | grep nfs
在k8s集群部署应用
vi nfs-nginx.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
nfs:
server: 192.168.44.134
path: /data/nfs
创建使用nfs存储的deployment
kubectl apply -f nfs-nginx.yaml
查看Pod
kubectl get pods
登陆服务器查看挂载
kubectl exec -it nginx-depl- bash
#nfs服务器创建html
ls /usr/share/nginx/html
hello.html
暴露nginx服务
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort
Volume是定义在Pod上的,属于计算资源的一部分,实际上网络存储是相对独立于计算资源而存在的一种实体资源。比如在使用虚拟机的情况下,通常会定义一个网络存储,然后从中划出一个网盘并挂载到虚拟机上。Persistent Volume(简称PV)和与之相关联的Persistent Volume Claim(简称PVC)也起到了类似的作用。
PV可以理解成K8s集群中的某个网络存储中对应的一块存储,与Volume很类似,但有以下区别。
PV和PVC
基于NFS类型PV的yaml定义文件如下所示,声明了需要5Gi的存储空间:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
nfs:
path: /somepath
server: 172.17.0.2
PV的accessMode属性,目前有以下类型:
如果某个Pod想申请某种类型的PV,则首先需要定义一个PersistentVolumeClaim(PVC)镜像:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 8Gi
然后在Pod的Volume定义中引用上述PVC即可:
volumes:
- name: mypd
persistentVolumeClaim:
claimName: myclaim
PV是有状态的对象,有以下几种状态:
创建PVC
pvc.yaml如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-dep1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: wwwroot
mountPath: /usr/share/nginx/html
ports:
- containerPort: 80
volumes:
- name: wwwroot
persistentVolumeClaim:
claimName: my-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi
创建PV
pv.yaml如下所示:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteMany
nfs:
path: /k8s/nfs
server: 192.168.44.134
部署PVC和PV
kubectl apply -f pvc.yaml
kubectl apply -f pv.yaml
查看pv和pvc
kubectl get pv,pvc