扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
不会。
溧水网站建设公司创新互联公司,溧水网站设计制作,有大型网站制作公司丰富经验。已为溧水成百上千提供企业网站建设服务。企业网站搭建\外贸网站制作要多少钱,请找那个售后服务好的溧水做网站的公司定做!
首先当然是能够与同样部署在K8S生态的业务应用紧密配合,应用和数据不再是割裂的两套架构,其次是K8S天生自带运维属性,把MySQL放上去之后可以结合K8S提供的丰富配置快速实现一些实用的运维功能。
比如依据负载情况的节点调度、结合cni网络插件实现限流,黑白名单等。
一、配置:
环境:
CentOS7
VMware
笔者配置了四台虚拟机:
K8S-Master节点: 3GB内存 2核CPU 20GB硬盘空间
K8S-node1节点: 2GB内存 2核CPU 30GB硬盘空间
K8S-node2节点: 2GB内存 2核CPU 30GB硬盘空间
镜像仓库节点: 2GB内存 2核CPU 50GB硬盘空间
二、节点规划:
使用三台虚拟机搭建K8S集群,使用一台虚拟机搭建镜像仓库。
每台虚拟机配置两块网卡,其中一块为“NAT模式”,用于拉取镜像等功能。
另外一块网卡为“仅主机模式”,用于集群节点间的通信。归划如下:
K8s-master节点:
仅主机模式:10.10.10.200
NAT模式: 192.168.200.130
K8S-node1节点:
仅主机模式:10.10.10.201
NAT模式: 192.168.200.131
K8S-node2节点:
仅主机模式:10.10.10.202
NAT模式: 192.168.200.132
镜像仓库节点:
仅主机模式:10.10.10.101
NAT模式: 192.168.200.150
三、版本信息
Linux内核版本:
Linux version 3.10.0-862.el7.x86_64 (builder@kbuilder.dev.centos.org)
(gcc version 4.8.5 20150623 (Red Hat 4.8.5-28) (GCC) )
#1 SMP Fri Apr 20 16:44:24 UTC 2018
K8s集群版本为1.15.0版本:
四、基于StatefulSet与PV/PVC的MySql持久化存储实验
1. 在每个节点安装nfs服务
在“镜像仓库”节点,执行以下命令:
yum install -y nfs-common nfs-utils rpcbind
在k8s集群,执行以下命令:
yum install -y nfs-utils rpcbind
2. 在“镜像仓库”节点下,配置nfs服务器
mkdir /nfs_mysql
Chmod 777 /nfs_mysql/
(在测试环境中,为了不考虑用户属性,暂时赋予777权限,但在生产环境不推荐这样做)
Chown nfsnobody /nfs_mysql/
echo “/nfs_mysql *(rw,no_root_squash,no_all_squash,sync)” /etc/exports
cat /etc/exports
/nfs_mysql *(rw,no_root_squash,no_all_squash,sync)
systemctl start rpcbind
systemctl start nfs
3. 测试nfs服务是否可用
mkdir /test
showmount -e 10.10.10.101
可见/nfs_mysql *已暴露于共享目录,接下来测试挂载是否可用:
在master节点下执行:
mount -t nfs 10.10.10.101:/nfs_mysql /test/
echo "hello-world"/test/1.txt
在镜像仓库节点下查看1.txt是否存在,若存在则挂载成功:
可见nfs服务可以正常使用,接下来删除test目录和1.txt
在镜像仓库下:
[root@hub nfs_mysql]# rm -f 1.txt
在Master节点下:
[root@k8s-master ~]# umount /test/
[root@k8s-master ~]# rm -rf /test/
同理,依照以上步骤同时创建:(提供多个mysql副本进行挂载)
nfs_mysql1
nfs_mysql2
完成后需要重启nfs服务
systemctl restart rpcbind
systemctl restart nfs
最终效果:
4. 将nfs封装成pv
创建mysql_test文件夹,将yaml文件统一保存在此目录下
mkdir mysql_test
cd mysql_test
vim mysql-pv.yml
mysql-pv.yml配置如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfs_mysql
server: 10.10.10.101
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv1
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfs_mysql1
server: 10.10.10.101
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv2
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs
nfs:
path: /nfs_mysql2
server: 10.10.10.101
注意:
在k8s集群15版本中recycle回收策略已被删除,只能用retain策略或者Delete策略。这里我们使用 persistentVolumeReclaimPolicy: Retain
执行命令:
kubectl create -f mysql-pv.yml
kubectl get pv
如图所示,即为Pv创建成功。
5. 部署MySQL,在mysql_test目录下编写mysql.yml,配置文件如下
apiVersion: v1
kind: Service
metadata:
name: mysql
labels:
app: mysql
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: mysql
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
selector:
matchLabels:
app: mysql
serviceName: "mysql"
replicas: 3
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.6
env:
- name: MYSQL_ROOT_PASSWORD
value: password
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumeClaimTemplates:
- metadata:
name: mysql-persistent-storage
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "nfs"
resources:
requests:
storage: 1Gi
执行以下命令,部署mysql服务:
kubectl create -f mysql.yml
如图可知,mysql按StatefulSet依次创建了mysql-0 mysql-1 mysql-2
查看各个Pod部在哪个节点:
6. 通过创建临时容器,使用MySQL客户端发送测试请求给MySQL master节点
注意:
主机名为mysql-0.mysql;跨命名空间的话,主机名请使用mysql-0.mysql. [NAMESPACE_NAME].如果没有指定命名空间,默认为default,即 mysql-0.mysql. default。
这里笔者打算关闭node2节点来模拟node2宕机,来测试是否实现数据的持久化存储,
所以我们向node2上的mysql1写入数据。
执行以下命令,访问mysql1:
kubectl run mysql-client --image=mysql:5.6 -it --rm --restart=Never -- mysql -h mysql-1.mysql.default -p password
创建数据库demo,并向messages表中写入hello-world
CREATE DATABASE demo;
CREATE TABLE demo.messages (message VARCHAR(250));
INSERT INTO demo.messages VALUES ('hello-world');
如图所示
接下来我们来关闭k8s-node2虚拟机,模拟宕机
查看nodes的运行状态,可知node2的状态已转变为NotReady
一段时间后,k8s将Pod MySql -1迁移到节点k8s-node1
由于时间过长,笔者把三个Pod都删除重启后,验证数据:
MySQL服务恢复,数据完好无损!
本文将演示如何在 KubeSphere[1] 上部署 RadonDB MySQL on Kubernetes 2.1.2 ,快速实现高可用的 MySQL on K8s。
若已在 KubeSphere 部署过历史版本 Operator,可以选择如下方式更新到最新版本。
可任选一个 RadonDB MySQL 配置示例[5] 部署,或自定义配置部署。
以 mysql_v1alpha1_mysqlcluster.yaml 模版为例,创建一个 RadonDB MySQL 集群。
注意
未指定项目时,集群将被默认安装在 kubesphere-controls-system 项目中。若需指定项目,安装命令需添加 --namespace=project_name 。
预期结果
预期结果
在 demo-project 项目中,查看 RadonDB MySQL 集群状态。
至此,完成在 KubeSphere 中部署 RadonDB MySQL 集群。
[1]:KubeSphere:
[2]:OpenPitrix:
[3]:创建操作:
[4]:项目网关:
[5]:配置示例:
mysql可以以docker的形式在集群内部署,也可以安装在集群之外,以服务的形式部署到集群内。
(1)、如果是在集群内部署,可以启动一个ReplicationController,用以对mysql pod进行监控,并同时启动一个Service,用以集群访问。
(2)、如果mysql是安装在集群之外,那么可以启动一个Endpoint和Service,将mysql引入集群之中。
下面分别对这两种方式进行部署。
创建mysql-rc.yaml和mysql-svc.yaml,分别如下:
mysql-rc.yaml
mysql-svc.yaml
在mysql-rc.yaml中,image参数可以指定mysql的版本,如8.0.11、5.7.22等。这里省略了,表示用latest。另外,可以指定镜像库,这里使用阿里云镜像库,在安装docker时进行了配置。env参数指定了mysql的root密码。
在mysql-svc.yaml中,targetPort表示mysql pod中mysql窗口的目标端口,默认为3306,type类型为NodePort,表示将映射到本地端口,本地端口为nodePort: 30306。
接下来启动ReplicationController和Service,执行以下命令:
启动后可以查看mysql部署在了哪个node上,执行以下命令可以查看:
(6)、退出mysql和容器,执行quit;退出mysql,按ctrl+p后,再按ctrl+q从容器中返回node主机。
设置好mysql后,可以远程连接node中的mysql,node的ip为127.0.0.1,映射的端口为30306,可以用navicat工具连接到这个myql。
虽然 kubernetes 社区一直在努力使得有状态应用成为一等公民,也推出了 statefulset 控制器支持 pod 的顺序部署,稳定的域名访问和存储访问。但鉴于 MySQL 部署运维的多样性和复杂性,在 kubernetes 上部署 MySQL 仍然要面临众多挑战。
1、业务流量入口的配置方式
传统虚拟机环境下,我们通过虚IP的方式,让业务应用都配置事先定义的一个虚IP为链接数据库的地址,然后由高可用服务保证虚IP始终能被路由到master数据库。在kubernetes中,出现了一层网络插件屏蔽了底层网络拓扑,高可用服务管理虚IP的方式需要随之适应调整,比如通过service结合标签完成虚IP的漂移,但service本身是kubernetes提供的一项功能,其可靠性和性能都取决于kubernetes服务的稳定。以性能来说,service是kubeproxy组件通过配置iptables实现的,当iptables规则较多时不可避免的会产生时延,需要我们针对性的解决。
2、容器隔离带来的监控视野问题
在 kubernetes 中,如果将 MySQL 制作为 container 运行在一个 pod 中,container 会将 MySQL 进程和运行环境隔离在一个单独的 namespace 中。监控组件在获取 MySQL 的一些 metirc 时,可能不得不进入与 MySQL 同一个 namespace 中,在部署和设计监控组件时需要考虑到这些限制。
3、存储在 kubernetes 中,支持配置各种不同的存储。
如果使用本地存储 local persistent volume,则需要绑定 MySQL 在一个固定的节点,这就完全浪费了 kubernetes 灵活调度的天然优势;而如果使用远程共享存储,确实是将 MySQL 进程与其存储完全解耦,使得 MySQL 进程可以在任意节点调度,然而考虑到高 I/O 吞吐量的情况,就不是那么美好了。设计时需要考量远程存储是否能够满足 MySQL 的带宽要求。
4、高可用/备份恢复
kubernetes 提供的 statefulset 控制器只能提供最基本的部署,删除功能,无法实现完善的 MySQL 集群高可用/备份恢复操作。对于有状态应用的部署,仍需要定制开发,所以多数公司提供了定制的 operator 来完成应用容器的管理。比如 etcd operator,MySQL operator,后文将为大家详述我测试使用 MySQL operator 的一些记录。
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流