NFS实现k8s(kubernetes)pod数据永久持久化

1.什么是持久化存储? For Example: 我们做系统迁移,要把原来的服务迁移到K8S中,系统用的Mysql数据库,也要迁移到K8S,我们知道,K8S运行的是一个一个Pod,K8S对Pod自动化管理,一个Pod挂了,另外一个Pod就会马上拉起来,假如运行Mysql的Pod挂了,马上重新拉起来,那原来Pod中存储的数据还会存在吗?或者说新拉起来的Pod会进行数据恢复吗?答案是:NO! 如果没有持久化存储,那兄弟,你真正的做到了从删库到跑路!从这样一个真实的场景,我们应该认识到K8S持久化存储的重要性,可以说,没有持久化技术,K8S就没有任何发展的前景!今天,我就深入的和大家聊一聊K8S中做持久化存储的几种解决方案,并用实操让大家玩转K8S!话不多说,撸起袖子,干就完了!

PV:

全称是PersistentVolumes,它是一种插件,它能够支持多种数据存储服务器,通过PV,我们能在K8S集群中,把我们的数据持久化到外部的服务器中。下图是PV能够支持的数据存储服务类型。

微信截图_20210525110237.png
我们可以看到,它能支持这么多种数据存储服务,那我们来实战一下:选择NFS来作为我们的数据存储服务。

2.NFS服务器搭建
NFS 是什么? nfs(network file system) 网络文件系统,是FreeBSD支持的文件系统中的一种,允许网络中的计算机之间通过TCP/IP网络共享资源

1)找一台centos 7机器,执行以下脚本,搭建 NFS服务器:
vim install_nfs.sh

#!/bin/bash

# 安装nfs
yum install -y nfs-utils

# 创建nfs目录
mkdir -p /nfs/data/
mkdir -p /nfs/data/mysql

# 授予权限
chmod -R 777 /nfs/data

# 编辑export文件
cat > /etc/exports << EOF
/nfs/data *(rw,no_root_squash,sync)
EOF

# 使得配置生效
exportfs -r

# 查看生效
exportfs

# 启动rpcbind、nfs服务
systemctl restart rpcbind && systemctl enable rpcbind
systemctl restart nfs && systemctl enable nfs

# 查看rpc服务的注册情况
rpcinfo -p localhost

# showmount测试
showmount -e ip(ip地址)

复制代码

执行脚本:chmod +x install_nfs.sh && ./install_nfs.sh

2)在K8S集群所有节点上安装NFS客户端

yum -y install nfs-utils systemctl start nfs && systemctl enable nfs

NFS 服务器有了,那我们如何让PV和NFC关联上呢?看下面代码:

# 定义nginx pv(生产者)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
  labels:
    app: nginx001
  namespace: nginx-pv-pvc
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 2Gi
  nfs:
    path: /nfs/data/nginx
    server: 192.168.29.104
复制代码

PV也作为一种K8S的资源,被K8S管理,所以它的定义肯定也是yaml。上述代码我们定义了一个nginx-pv,accessModes权限是ReadWriteMany读写权限,capacity storage 定义了2G的存储空间,挂载目录是/nfs/data/nginx,NFS 服务器IP是192.168.29.104,好了,我们这样就定义了一个PV。
定义完了我们就能用了吗?
我们考虑一个问题: 假如你作为这一块儿的设计者,每次想使用外部存储服务,都要自己创建一个PV,这样做麻烦吗?一个公司中不仅有开发,还有运维,如果我们想用外部存储服务,直接告诉运维,让运维给我们在K8S中准备一些PV,我们自己挑选着用,这岂不是方便很多。
所以,“好事者” 想的比较周到。我们的PV是和外部的服务器相连,Pod是不能使用的,我们要用另外一种叫做PersistentVolumeClaim 简称 PVC 的资源来连接PV,我们的Pod连接PVC 就可以使用了。类似于消息中间件的生产者和消费者的关系。PV是生产者,PVC是消费者。

3)PersistentVolumeClaim

PVC定义:

# 定义nginx pvc(消费者,用于和pod绑定)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  labels:
    app: nginx001
  namespace: nginx-pv-pvc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
复制代码

简单明了,我定义一个名字叫 nginx-pvc的PVC,权限是ReadWriteMany读写权限,需要的存储空间是 2G。
那我们思考一个问题:PV,PVC我们都定义好了,我们在PVC定义中并没有看到和PV绑定的相关配置,那他们两个是怎么绑定的呢?
其实,内部是配对是这样的:通过PVC定义的 accessModes 读写权限,和storage定义的2G内存,PVC会自动找到符合这些配置的PV进行绑定。一个PV被PVC绑定后,不能被别的PVC绑定。

4)PV、PVC实战

我们还来定义一个Nginx Pod,使用PV,PVC,NFS来做持久化存储;我这里就把上面定义的pv、pvc都写到一个yaml文件里

vim nginx-pv-pvc.yaml

---
# 定义nginx pv(生产者)
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
  labels:
    app: nginx001
  namespace: nginx-pv-pvc
spec:
  accessModes:
  - ReadWriteMany
  capacity:
    storage: 2Gi
  nfs:
    path: /nfs/data/nginx
    server: 192.168.29.104

---
# 定义nginx pvc(消费者,用于和pod绑定)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
  labels:
    app: nginx001
  namespace: nginx-pv-pvc
spec:
  accessModes:
  - ReadWriteMany
  resources:
    requests:
      storage: 2Gi
  
---
# 定义nginx pod,绑定pvc(nginx-pvc)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-wyn001
  namespace: nginx-pv-pvc
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx001
  template:
    metadata:
      name: nginx-wyn001
      labels:
        app: nginx001
    spec:
      containers:
      - name: nginx-wyn001
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
          - name: nginx-data-volume
            mountPath: /usr/share/nginx/html
        resources:
          requests:
            cpu: 1000m
            memory: 200M
          limits:
            cpu: 2000m
            memory: 300M
      volumes:
        - name: nginx-data-volume
          persistentVolumeClaim:
            claimName: nginx-pvc
复制代码

创建:
kubectl apply -f nginx-pv-pvc.yaml

我们可以看到 使用 persistentVolumeClaim:claimName: nginx-pvc 定义了我我们要使用名字为nginx-pvc的 PVC。
注意:我们在NFS服务器上定义的路径是/nfs/data/nginx 首先我们需要去 nfs/data下创建 nginx的文件夹,不然你的pod是启动不起来的,这个坑我替大家踩了!
接下来,在master节点上启动。

查看:kubectl get po,pv,pvc -n nginx-pv-pvc

微信截图_20210525112344.png

现在的数据目录关系这样的:

容器数据目录:/usr/share/nginx/html 通过pvc,pvc又通过pv映射到了nfs服务器的 /nfs/data/nginx目录

现在我们在nfs服务器的 /nfs/data/nginx目录创建几个文件,然后到nginx pod中查看是否已经有了这些文件

ls /nfs/data/nginx/

微信截图_20210525112733.png

查看pod:

kubectl exec -it -n nginx-pv-pvc nginx-wyn001-5fdbd66695-xs6p2 — ls /usr/share/nginx/html

微信截图_20210525112940.png

从上图得知,容器内已经有了数据,现在我这个pod是部署在node1节点上面的,我把该pod删掉重建后,它正好部署到node2节点上,然后我再次查看了pod中容器的/usr/share/nginx/html目录,发现数据已经自动挂载上去了

当然,还可以采用 storage class方式实现数据的持久化,由于篇幅较长,下期再出一篇这方面的文章给大家

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享