k8s-持久化存储[emptyDir|hostPath|nfs]
在k8s中为什么要做持久化存储?
在k8s中部署的应用都是以pod容器的形式运行的,假如我们部署MySQL、Redis等数据库,需要对这些数据库产生的数据做备份。因为Pod是有生命周期的,如果pod不挂载数据卷,那pod被删除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到pod数据持久化存储。
我们想要使用存储卷,需要经历如下步骤
- 1、定义pod的volume,这个volume指明它要关联到哪个存储上的
- 2、在容器中要使用volumemounts挂载对应的存储
k8s持久化存储:emptyDir[临时存储]
emptyDir类型的Volume是在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。
Emptydir的官方网址:https://kubernetes.io/docs/concepts/storage/volumes#emptydir
apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 #pod中的容器需要暴露的端口 volumeMounts: - mountPath: /www #容器里的目录 name: cache-volume #卷组名字 volumes: - emptyDir: {} name: cache-volume
[root@master01 ~]# kubectl apply -f nginx.yaml deployment.apps/my-nginx created service/web01 created
[root@master01 ~]# kubectl get pod NAME READY STATUS RESTARTS AGE my-nginx-5794cc45d5-5qb49 1/1 Running 0 2m55s my-nginx-5794cc45d5-7crzq 1/1 Running 0 2m55s myapp-v1-67fd9fc9c8-bgc7w 1/1 Running 0 117m myapp-v1-67fd9fc9c8-gd2l6 1/1 Running 0 117m
查看pod的uid
[root@master01 ~]# kubectl get pod my-nginx-5794cc45d5-5qb49 -o yaml|grep uid uid: e9c9d6e0-d3be-4318-86e6-0e93cbb47eb8 uid: 311394e4-c93d-458d-a616-3d461ce0e6e5
最终node物理机上存的目录
[root@node01 ~]# tree /var/lib/kubelet/pods/311394e4-c93d-458d-a616-3d461ce0e6e5
/var/lib/kubelet/pods/311394e4-c93d-458d-a616-3d461ce0e6e5
├── containers
│ └── my-nginx
│ └── 7d2173f7
├── etc-hosts
├── plugins
│ └── kubernetes.io~empty-dir
│ ├── cache-volume
│ │ └── ready
│ └── wrapped_kube-api-access-zxhdv
│ └── ready
└── volumes
├── kubernetes.io~empty-dir
│ └── cache-volume
└── kubernetes.io~projected
└── kube-api-access-zxhdv
├── ca.crt -> ..data/ca.crt
├── namespace -> ..data/namespace
└── token -> ..data/token
11 directories, 7 files
[root@node01 ~]# cd /var/lib/kubelet/pods/311394e4-c93d-458d-a616-3d461ce0e6e5/volumes/kubernetes.io~empty-dir/cache-volume [root@node01 cache-volume]# ll 总用量 0
k8s持久化存储:hostPath[节点级别存储]
hostPath Volume是指Pod挂载宿主机上的目录或文件。 hostPath Volume使得容器可以使用宿主机的文件系统进行存储,hostpath(宿主机路径):节点级别的存储卷,在pod被删除,这个存储卷还是存在的,不会被删除,所以只要同一个pod被调度到同一个节点上来,在pod被删除重新被调度到这个节点之后,对应的数据依然是存在的。
[root@master01 ~]# cat nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 #pod中的容器需要暴露的端口 volumeMounts: - mountPath: /usr/share/nginx/html name: cache-volume #卷组名字 - name: my-tomcat image: tomcat:8.5-jre8-alpine imagePullPolicy: IfNotPresent ports: - containerPort: 8080 #pod中的容器需要暴露的端口 volumeMounts: - mountPath: /usr/share/tomcat/webapps/ROOT name: cache-volume #卷组名字 volumes: - name: cache-volume hostPath: path: /data1 type: DirectoryOrCreate #没有挂载data1目录,自动创建 --- apiVersion: v1 kind: Service metadata: name: web01 namespace: default spec: ports: - name: nginx port: 80 protocol: TCP targetPort: 80 nodePort: 30008 - name: tomcat port: 8080 protocol: TCP targetPort: 8080 nodePort: 30009 selector: run: my-nginx type: NodePort
#更新资源清单文件
[root@master01 ~]# kubectl apply -f nginx.yaml
#查看pod调度到了哪个物理节点
[root@master01 ~]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-nginx-5878bbf4c9-jcfxs 2/2 Running 0 20m 172.16.196.164 node01 <none> <none>
#由上面可以知道pod调度到了node1上,登录到node1机器,查看是否在这台机器创建了存储目录
[root@node01 ~]# ll /data1 总用量 0
hostpath存储卷缺点:
- 单节点pod删除之后重新创建必须调度到同一个node节点,数据才不会丢失
可以用分布式存储:
- nfs,cephfs,glusterfs
k8s持久化存储:nfs
搭建nfs服务
1.以k8s的控制节点作为NFS服务端
[root@master01 nfs]# yum -y localinstall *.rpm
#在宿主机创建NFS需要的共享目录
[root@master01 ~]# mkdir /data/volumes -pv mkdir: 已创建目录 "/data/volumes"
#配置nfs共享服务器上的/data/volumes目录
[root@master01 ~]# systemctl start nfs [root@master01 ~]# cat /etc/exports /data/volumes 192.168.1.0/24(rw,no_root_squash) #no_root_squash: 用户具有根目录的完全管理访问权限
#使NFS配置生效
[root@master01 ~]# exportfs -arv exporting 192.168.1.0/24:/data/volumes
root@master01 ~]# systemctl restart nfs [root@master01 ~]# systemctl enable nfs
2.以k8s的工作节点作为NFS客户端
#node节点上也安装nfs驱动
[root@node01 nfs]# yum -y localinstll *.rpm
[root@node01 nfs]# systemctl enable nfs
上手动挂载试试:
[root@node01 nfs]# mkdir /test [root@node01 nfs]# mount 192.168.1.180:/data/volumes /test
#nfs可以被正常挂载
#手动卸载:
[root@node01 nfs]# umount /test
#创建Pod,挂载NFS共享出来的目录
[root@master01 ~]# cat nginx.yaml apiVersion: apps/v1 kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx imagePullPolicy: IfNotPresent ports: - containerPort: 80 #pod中的容器需要暴露的端口 volumeMounts: - mountPath: /usr/share/nginx/html name: cache-volume #卷组名字 - name: my-tomcat image: tomcat:8.5-jre8-alpine imagePullPolicy: IfNotPresent ports: - containerPort: 8080 #pod中的容器需要暴露的端口 volumeMounts: - mountPath: /usr/share/tomcat/webapps/ROOT name: cache-volume #卷组名字 volumes: - name: cache-volume nfs: path: /data/volumes server: 192.168.1.180 --- apiVersion: v1 kind: Service metadata: name: web01 namespace: default spec: ports: - name: nginx port: 80 protocol: TCP targetPort: 80 nodePort: 30008 - name: tomcat port: 8080 protocol: TCP targetPort: 8080 nodePort: 30009 selector: run: my-nginx type: NodePort
#更新资源清单文件
[root@master01 ~]# kubectl apply -f nginx.yaml deployment.apps/my-nginx created service/web01 created
#登录到nfs服务器,在共享目录创建一个index.html
[root@master01 ~]# cd /data/volumes/ [root@master01 volumes]# cat index.html Hello, Everyone My name is hwf
#请求pod,看结果
#tomcat也是正常的,太长了不看了 [root@master01 volumes]# curl 192.168.1.182:30008 Hello, Everyone My name is hwf
#上面说明挂载nfs存储卷成功了,nfs支持多个客户端挂载,可以创建多个pod,挂载同一个nfs服务器共享出来的目录;但是nfs如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分布式存储有glusterfs和cephfs

评论