做者:王悦
爱可生研发团队成员,负责数据库管理平台相关项目的开发和故障排查,好奇 MySQL 技术原理及各种数据库实现方案。
本文来源:转载自公众号-图解 MySQL
*爱可生开源社区出品,原创内容未经受权不得随意使用,转载请联系小编并注明来源。
注:阅读本文须要了解 pod,controller,service 等一些 kubernetes 的基本概念。
容器凭借其良好的移植性,敏捷性和革命性的打包方式迅速成为云服务的新基础设施。但 Docker 毕竟只是 “container runtime”,咱们须要一个编排框架做为系统核心来串联开发、测试、部署、运维等整个软件生命周期。kubernetes 就提供这样一个框架,提供大量容器的部署、编排、管理的能力。mysql
虽然 kubernetes 社区一直在努力使得有状态应用成为一等公民,也推出了 statefulset 控制器支持 pod 的顺序部署,稳定的域名访问和存储访问。但鉴于 MySQL 部署运维的多样性和复杂性,在 kubernetes 上部署 MySQL 仍然要面临众多挑战。git
传统虚拟机环境下,咱们经过虚 IP 的方式,让业务应用都配置事先定义的一个虚 IP 为连接数据库的地址,而后由高可用服务保证虚 IP 始终能被路由到 master 数据库。github
在 kubernetes 中,出现了一层网络插件屏蔽了底层网络拓扑,高可用服务管理虚 IP 的方式须要随之适应调整,好比经过 service 结合标签完成虚 IP 的漂移,但 service 自己是 kubernetes 提供的一项功能,其可靠性和性能都取决于 kubernetes 服务的稳定。sql
以性能来讲,service 是 kube proxy 组件经过配置 iptables 实现的,当 iptables 规则较多时不可避免的会产生时延,须要咱们针对性的解决。数据库
在 kubernetes 中,若是将 MySQL 制做为 container 运行在一个 pod 中,container 会将 MySQL 进程和运行环境隔离在一个单独的 namespace 中。监控组件在获取 MySQL 的一些 metirc 时,可能不得不进入与 MySQL 同一个 namespace 中,在部署和设计监控组件时须要考虑到这些限制。api
在 kubernetes 中,支持配置各类不一样的存储。若是使用本地存储 local persistent volume,则须要绑定 MySQL 在一个固定的节点,这就彻底浪费了 kubernetes 灵活调度的自然优点;而若是使用远程共享存储,确实是将 MySQL 进程与其存储彻底解耦,使得 MySQL 进程能够在任意节点调度,然而考虑到高 I/O 吞吐量的状况,就不是那么美好了。网络
设计时须要考量远程存储是否可以知足 MySQL 的带宽要求。架构
kubernetes 提供的 statefulset 控制器只能提供最基本的部署,删除功能,没法实现完善的 MySQL 集群高可用/备份恢复操做。对于有状态应用的部署,仍须要定制开发,因此多数公司提供了定制的 operator 来完成应用容器的管理。好比 etcd operator,MySQL operator,后文将为你们详述我测试使用 MySQL operator 的一些记录。oracle
注:operator 是 CoreOs 推出的旨在简化复杂有状态应用管理的框架,咱们能够经过 operator 自定义一个有状态应用容器的控制器,operator 经过 kubernetes API 观察集群现有状态,管理集群行为,以达到用户指望的集群状态。
说完了问题和挑战,咱们来讲说收益。框架
结合kubernetes的cni网络插件能够快速实现限流,黑白名单...
敏捷部署,滚动更新,依据负载状况的节点调度...
然而考虑到 MySQL 这类持久层软件的特殊性,不能简单的套用 kubernetes 的原生 API 功能,好比滚动更新须要考虑主从角色的前后顺序,配套高可用软件在 MySQL 更新阶段的行为,业务流量的切换等等。这些在传统环境中已经解决的问题在 kubernetes 中仍然须要被从新规划解决方案。
鉴于以上种种挑战,在 kubernetes 上管理 MySQL 须要一套专为 MySQL 设计的控制器(就咱们前面说到的 operator),目前开源社区中比较流行的有如下两个控制器:
先简单过一遍功能:
具体的安装步骤就不在这里详述了,你们能够参考
下面探索一下 operator 部署时的一些实现方式:
Q: pod 重启后可否保证明例的数据不丢失?
A:operator 在建立实例时会将 datadir 配置为 mysqlvolume 挂载(如 pvc 或 emptydir),因此实例重启后可以从新挂载恢复数据。注:限制是用户不能自定义 data,binlog,redolog 目录,若是不在默认的 /var/lib/mysql 目录中,数据会随 pod 重启而消亡
Q:能够为 mysqld container 设置 cpu,mem 资源限制吗?
A:能够在建立集群时配置限制,但该功能只在 master 版本上存在,目前 helm hub 中使用的是 0.3.0 tag 版本,该版本中无该功能
Q:业务和实例不在一个 kubernetes 集群时该如何链接?
A:在实例所在集群上先部署一个 mysql-router,而后经过暴露 mysql-router 给外部集群来提供访问。
暴露方式有多种可选,如 NodePort,LoadBalancer,Ingress 等
可见 Oracle MySQL operator 提供的功能很是基础,并且其 github 仓库已经一年多没有维护了,官方好像不是很想推进 MySQL 上 kubernetes,毕竟传统云服务提供的 RDS 服务已经可以知足大部分用户场景。
另外,Percona 也提供了一个 MySQL 的 operator,可以部署高可用 master-slave 结构的 MySQL,但依托于 Percona 版的 MySQL 提供的功能,并不支持原生的 MySQL 镜像。
使用 operator 运维有状态应用确实可以解决多数问题,但维护数据库应用自己就是复杂困难的,须要适应不少场景,在 kubernetes 上彻底解决这些问题短时间内很是困难。
上述两个 MySQL operator 目前的实现都相对基础,直接在生产环境部署的稳定性也没有保障,只能做为调研测试的对象。