一、kubernetes管理储存资源-------volume
我们经常说:容器和pod是短暂的,其含义是他们的生命周期可能很短,会被频繁的销毁和创建。容器销毁时,保存在容器内部文件中的数据都会被清除。
为了持久化保存容器的数据,可以使用kubernetes volume。
volume的生命期独立于容器,pod中的容器可能被销毁和重建,但volume会被保留。
二、emptydir
emptydir是最基础的volume类型。一个emptydir volume是host上的一个空目录。
emptydir volume对于容器来说都是持久的,对于pod则不是,当pod从节点删除时,volume的内容也会被删除。但如果只是容器被销毁而pod还在,则volume不受影响。也就是说: emptydir volume的生命周期与pod一致。
1.案例:
mkdir datavolume
apiVersion: v1
kind: Pod
metadata:
name: producer-consumer
spec:
containers:
- image: busybox
name: producer
volumeMounts:
- mountPath: /producer_dir
name: shared-volume
args:
- /bin/sh
- -c
- echo "hello world" > /producer_dir/hello; sleep 30000
- image: busybox
name: consumer
volumeMounts:
- mountPath: /consumer_dir
name: shared-volume
args:
- /bin/sh
- -c
- cat /consumer_dir/hello ; sleep 3000
volumes:
- name: shared-volume
emptyDir: {}
验证结果:
kubectl logs 显示容器consumer 成功读到了 producer 写入的数据,验证两个容器共享emptydir volume
因为emptydir是docker host 文件系统里的目录,其效果相当于执行了 docker run -v /producer_dir和 docker run -v /consumer_dir 。通过docker_inspect 查看容器的详细配置信息,我们发现两个容器都mount到一个目录:
docker inspect k8s_producer_producer-consumer_default_331af6f6-8a1e-4721-bc86-a62ca1d28a6b_0
docker inspect k8s_consumer_producer-consumer_default_331af6f6-8a1e-4721-bc86-a62ca1d28a6b_0
emptydir是host上创建的临时目录,其优点是能够方便地为pod中的容器提供共享存储,不需要额外的配置,但他不具备持久性,如果pod不存在了,emptydir也没有了。
三、 hostPath volume
hostpath volume的作用是将docker host文件系统中已经存在的目录mount给pod的容器。大部分应用都不会使用hostPath volume,因为这实际上增加了pod与节点的耦合,限制了pod的使用。不过那些需要访问kubernetes或docker内部数据。
比如kube-apiserver和kube-controller-manager就是这样应用,通过:
kubectl edit --namespace=kube-system pod kube-apiserver-k8s-master
查看 kube-apiserver pod的配置,下面volume的相关部分:
这里定义了三个hostPath volume k8s、certs和pki,分别对应host目录 /etc/kubernetes 、/etc/ssl/certs 和/etc/pki。
如果pod被销毁了,hostPath对应的目录也会被保留,从这点看、hostPath的持久性比emptydir强,不过一旦host崩溃,hostPath也就没法访问了。
四、外部storage provider
五、pv & pvc
volume提供了非常好的数据持久化方案,不过在可管理性上还有不足。
六、NFS PersistentVolume
作为准备工作,我们已经在k8s-master节点上搭建了一个NFS服务器,目录为、nfsdata:
创建一台nfs服务器
yum install rpcbind nfs-utils -y (每台都安装)
mkdir /nfsdata
vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
systemctl start rpcbind && systemctl enable rpcbind (每台都启动)
systemctl start nfs-server.service && systemctl enable nfs-server.service
验证:
showmount -e 192.174.1.53
提前创建目录好为创建PV做准备
mkdir /nfsdata/pv1
1.创建一个pv mypv1 配置文件nfs-pv1.yml
vim nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.174.1.53
kubectl apply -f nfs-pv1.yml
验证结果:
2.创建pvc 配置文件nfs-pvc1.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mypvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
kubectl apply -f nfs-pvc1.yml
验证结果:
从kubectl get pvc和kubectl get PV的输出可以看到mypvc1已经bound到mypv1,申请成功。
3.在pod中使用存储了,pod配置文件pod1.yml
vim pod1.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod1
spec:
containers:
- image: busybox
name: mypod1
volumeMounts:
- mountPath: /mydata
name: mydata
args:
- /bin/sh
- -c
- sleep 30000
volumes:
- name: mydata
persistentVolumeClaim:
claimName: mypvc1
验证结果:
验证PV是否可用:
kubectl exec mypod1 touch /mydata/test1
在pod中创建的文件 /mydata/pv1,确实已经保存到了NFS服务器目录 /nfsdata/pv1中。
七、回收pv
1. 当pv不需要时候,可以通过删除pvc回收。
kubectl delete -f pod1.yml
kubectl delete pvc mypvc1
验证结果:
2.因为pv的回收策略设置为recycle,所以数据会被清除,但这可能不是我们想要的结果。如果我们希望保留数据,可以将策略设置为retain
vim nfs-pv1.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mypv1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/pv1
server: 192.174.1.53
kubectl apply -f nfs-pv1.yml
部署结果:
删除验证:
八、pv动态供给
九、Mysql使用pv和pvc
如何为mysql数据库提供持久化储存,步骤为:
1.首先创建pv和pvc
配置如下:
1.pv.yml
vim mysql-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfsdata/mysql-pv
server: 192.174.1.53
2.mysql-pvc1.yml
vim mysql-pvc1.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: nfs
mkdir -p /nfsdata/mysql-pv nfs服务器创建目录
部署结果:
2.部署mysql,配置文件如下:
vim mysql.yml
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: mysql
name: mysql
spec:
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- image: mysql:5.7
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: "/var/lib/mysql"
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pvc1
---
apiVersion: v1
kind: Service
metadata:
labels:
app: mysql
name: mysql
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306
kubectl apply -f mysql.yml
mysql被部署到k8s-node2上,通过客户端访问service mysql:
kubectl run -it --rm --image=mysql:5.7 --restart=Never mysql-client -- mysql -h mysql -ppassword
3.更新数据库
一段时间后,kubernetes将mysql迁移到mysql-node1上
验证数据一致性:
kubectl run -it --rm --image=mysql:5.7 --restart=Never mysql-client -- mysql -h mysql -ppassword
mysql服务恢复 数据还存在