前言

一、准备工作

环境搭建

  1. 集群环境:如果没有请参考文章使用kubeadm快速部署一个K8s集群
  2. nfs工具安装:在master和node节点中都安装nfs,并且启动
# 在mater中执行
[root@ecs-431f-0001 /]# yum -y install nfs-utils 
[root@ecs-431f-0001 /]# systemctl enable rpcbind 启动rpc设置开机自启动
[root@ecs-431f-0001 /]# systemctl start nfs-server 启动nfs-server
[root@ecs-431f-0001 /]# systemctl enable nfs-server 设置开机自启动
# 在node节点192.168.0.109上执行,用于进行挂载mysql的数据
[root@ecs-431f-0002 /]# yum -y install nfs-utils 
[root@ecs-431f-0002 /]# mkdir -p /nfsdata/mysql 
[root@ecs-431f-0002 /]# echo “/nfsdata *(rw,sync,no_root_squash)“ >> /etc/exports 
[root@ecs-431f-0002 /]# systemctl enable rpcbind 启动rpc设置开机自启动
[root@ecs-431f-0002 /]# systemctl start nfs-server 启动nfs-server
[root@ecs-431f-0002 /]# systemctl enable nfs-server 设置开机自启动
[root@ecs-431f-0002 /]# showmount -e 192.168.0.109 
Export list for 192.168.0.109:
/nfsdata *

注:*表示内网所有机器都可访问并挂载目录,这里最好添加白名单限制,仅对K8S集群内节点开放

# 打开配置文件
vim /etc/exports

# 未设置权限
/data/nfs *(rw,no_root_squash)

# 添加挂载IP限制
/data/nfs 192.168.0.109/24(rw,async,no_root_squash)
  • 使挂载配置生效并验证
# 重新挂载并显示(无需重启服务)
exportfs -rv

# 本机查看挂载情况
showmount -e

# 在其它节点查看挂载情况
showmount -e 192.168.0.109
  • 验证nfs是否成功

1、在master中新建一个测试文件夹 mkdir /test,执行下面的命令

[root@ecs-431f-0001 /]# mount -t nfs 192.168.0.109:/nginxvolume /test
mount.nfs: mounting 192.168.0.109:/nginxvolume failed, reason given by server: No such file or directory

出现上面的错误,说明挂载没有成功,最好的方法就是重新启动一下。如下操作。

2、如果修改完配置文件之后需要重新启动一下nfcrpcbind

[root@ecs-431f-0002 nginxvolume]# sudo service nfs-server restart 
Redirecting to /bin/systemctl restart nfs-server.service
[root@ecs-431f-0002 nginxvolume]# showmount -e 192.168.0.109 
Export list for 192.168.0.109:
/nginxvolume *
/nfsdata     *

3、 重复1的操作,并在master机器中写入一个文件测试,在nfs的服务器镜进行查看。
在这里插入图片描述
在这里插入图片描述
说明nfs测试成功。
4、使用命令umount /test解除master的nfs挂载。但是会遇到一些问题umount.nfs4: /test: device is busy
通过fuser命令进行查看

[root@localhost /]# fuser -m -v /test/
                     用户     进程号 权限   命令
[root@ecs-431f-0001 ~]# fuser -m -v /test/
                     USER        PID ACCESS COMMAND
/test:               root     kernel mount /test
                     root       2996 ..c.. su
-v 表示 verbose 模式。进程以 ps 的方式显示,包括 PID、USER、COMMAND、ACCESS 字段

-m 表示指定文件所在的文件系统或者块设备(处于 mount 状态)。所有访问该文件系统的进程都被列出。

如上所示,有个进程占用了,将其kill掉,再重新取消挂载。

[root@localhost /]# kill -9 2996
[root@localhost /]# umount /test/
[root@localhost /]#

这样卸载的方式有可能不能接触挂载,可以使用umont -l /test 直接取消挂载。

编写yaml文件

1.创建PV

vim mysql-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: mypv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain   # 手动删除 
  storageClassName: nfs
  nfs:
    path: /nfsdata/mysql
    server: 192.168.0.109 #

2.创建PVC

vim mysql-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc1
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 4Gi
  storageClassName: nfs

查看pv和pvc的状态

[root@ecs-431f-0001 config]# kubectl get pv,pvc
NAME                     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
persistentvolume/mypv1   5Gi        RWX            Recycle          Bound    default/mypvc1   nfs                     52m

NAME                           STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/mypvc1   Bound    mypv1    5Gi        RWX            nfs            51m

3.创建mysql-pod

vim mysql-deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  template:
    metadata:
      labels:
        app: mysql
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:           #配置变量,设置mysql的密码
        - name: MYSQL_ROOT_PASSWORD
          value: root
        ports:
        - containerPort: 3306
        volumeMounts:
        - name: mysql-persistent-storage
          mountPath: /var/lib/mysql                 #MySQL容器的数据都是存在这个目录的,要对这个目录做数据持久化
      volumes:
      - name: mysql-persistent-storage
        persistentVolumeClaim:
          claimName: mypvc1           #指定pvc名称

4.创建SVC

apiVersion: v1
kind: Service
metadata:
  name: mysql
spec:
  selector:
    app: mysql
  type: NodePort
  ports:
  - port: 3306
    targetPort: 3306
    nodePort: 31921
[root@ecs-431f-0001 config]# kubectl get deployment
NAME                READY   UP-TO-DATE   AVAILABLE   AGE
mysql               1/1     1            1           52m
tomcat-deployment   2/2     2            2           11d
[root@ecs-431f-0001 config]# kubectl get  svc
NAME                    TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
kubernetes              ClusterIP   10.96.0.1        <none>        443/TCP          26d
mysql                   NodePort    10.96.177.243    <none>        3306:31921/TCP   3h3m
NAME                                 READY   STATUS    RESTARTS   AGE
mysql-774dc9f4d7-tc7bz               1/1     Running   0          53m

使用Navicat测试连接

在这里插入图片描述
创建数据库
在这里插入图片描述
在Linux中查看有无创建的数据库

在这里插入图片描述
数据已经同步

测试数据是否会丢失

1.手动删除节点上的容器

[root@ecs-431f-0001 ]# kubectl get pod -o wide 查看运行的节点
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE            NOMINATED NODE   READINESS GATES
mysql-774dc9f4d7-tc7bz               1/1     Running   0          64m    10.244.2.9    ecs-431f-0002   <none>           <none>
[root@ecs-431f-0001]# kubectl get pod -o wide          #查看pod运行在哪个节点
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE            NOMINATED NODE   READINESS GATES
mysql-774dc9f4d7-tc7bz               1/1     Running   0          64m    10.244.2.9    ecs-431f-0002   <none>           <none>
#运行在node1节点,现在去node01节点手动将其容器删除
[root@ecs-431f-0002]# docker ps       #查看MySQL容器的ID
[root@ecs-431f-0002]# docker rm -f 54db3e8727f0 #将MySQL的容器删除
#由于Deployment的保护策略,当删除容器后,它会根据pod的yaml文件生成一个新的容器,但新容器的ID号就变了
#回到master节点,登录到数据库,查看数据是否还存在
[root@ecs-431f-0001 config]# kubectl exec mysql-774dc9f4d7-tc7bz -it -- mysql -uroot -proot
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| tenant             |
+--------------------+
5 rows in set (0.00 sec)

2.模拟宕机

问题总结

因为pvc和pv实现的持久化存储是不可逆的,如果不小心删除了pv,此时pv还会有保护机制,就是一直处于Terminaling的状态,直到你把他所关联的pod也删除,该pv才会消失,但是也会遇到删除pod,但是pv一直删除不了的情况,这样我们可以强制给他删除。
只需要执行命令:xxx pv的名称

kubectl patch pv xxx -p '{"metadata":{"finalizers":null}}'
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐