文章目录
前言
一、准备工作
环境搭建
- 集群环境:如果没有请参考文章使用kubeadm快速部署一个K8s集群
- 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、如果修改完配置文件之后需要重新启动一下nfc
和rpcbind
[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}}'