目前 openbayes 的几乎所有组件都部署在 k8s 内部,但 mysql 作为核心的数据存储节点对其要求都蛮高的,通常来说是需要独立部署的,对于目前的业务场景,其要求主要包含以下几点:
之所以希望将 mysql 部署到 k8s 内主要还是希望达到以下目的:
openbayes 本身对数据库性能的要求没有那么高,用户的大量数据是以分布式存储的形式保存的,mysql 的负载通常不高,这也让 mysql 部署在 k8s 里成为了可能。
下面介绍 bitpoke/mysql-operator 如何满足上述要求。
在使用云服务商的数据库的时候我就在想,如果能有一套 k8s 的 operator 能够支持快速部署 / 数据库配置 / 周期性备份 / prometheus 指标暴露就好了,在做了简单的搜索后还真的发现了这么个东西 bitpoke/mysql-operator ,满足了说所提及的这一切:
https://github.com/bitpoke/mysql-operator/blob/master/deploy/charts/mysql-operator/values.yaml 这是 helm charts 的 values.yaml 把这个文件下载到本地,按照具体环境做一定修改后执行以下命令即可部署 operator 了:
# 这里用的是 helm3
helm repo add bitpoke https://helm-charts.bitpoke.io
helm install mysql-operator bitpoke/mysql-operator \
-f values.yaml \
-n infra --create-namespace
其中 values.yaml
需要修改的部分主要就是两部分:
persistence.enabled: false
可以按照自己的情况做修改,这里只支持 storageClass
的方式部署好之后才是第一步,即成功部署了 operator
本身,下面就是具体部署一个 mysql
了,在 https://github.com/bitpoke/mysql-operator/tree/master/examples 有一个例子,可以看到 mysql 被定义为了一个叫做 MysqlCluster
的 CRD。主要需要修改的部分有以下:
secretName
见 https://github.com/bitpoke/mysql-operator/blob/master/examples/example-cluster-secret.yaml 指初始化的一些数据,如 root 密码,数据库名称,用户名,用户密码image
/ mysqlVersion
mysql 的镜像,同样推荐修改为国内的镜像,具体版本也依照实际情况backupSchedule
如果设置则是需要周期性备份,数据会按照该配置定期备份到指定的对象存储中,当然 backupSecretName
也需要配置正确才能使用mysqlConf
对应 mysql.cnf 中的字段,依据自己需求配置volumeSpec
数据持久化方式,和上文中 operator
的类似,但是更灵活,支持 hostPathinitFileExtraSQL
感觉这个 MysqlCluster 是希望用户每个数据库建立一个独立的资源,但是 openbayes 这里有一些附属数据库如果分开放置感觉有点没必要,所以这里就采用这个机制同时初始化了其他的数据库 initFileExtraSQL:
- "CREATE DATABASE IF NOT EXISTS `<otherdb>`"
- "DROP USER IF EXISTS <otheruser>@'%'"
- "CREATE USER <otheruser>@'%' IDENTIFIED BY '<PASSOWRD>'"
- "GRANT ALL PRIVILEGES ON <otherdb>.* TO <otheruser>@'%'"
- "FLUSH PRIVILEGES"
注意这里有个奇怪的写法是需要先去 DROP USER
... 至于为啥我并不知道,我只知道不这么做就是会报错...
如上文所述,这个 MysqlCluster
支持自动的备份,当然也支持主动的备份,具体的文档在Cluster Backups and Recovery。
既然支持备份也支持恢复,具体的文档在也在Cluster Backups and Recovery。
这些步骤我都测试过了,确认可以走的通的。以及这个备份的功能已经非常体贴了:
在备份到 s3 不成功可以看看具体的报错信息,它具体备份采用的是 rclone 这个工具。不成功基本就是两个方向:
如上图所示,这是我直接将 https://grafana.com/grafana/dashboards/7362 这个仪表盘导入所看到的效果。
增加一个额外的 NodePort 即可:
apiVersion: v1
kind: Service
metadata:
name: local-openbayes-mysql-nodeport-master
spec:
ports:
- name: mysql
port: 3306
protocol: TCP
targetPort: 3306
nodePort: 30016
selector:
app.kubernetes.io/managed-by: mysql.bitpoke.org
app.kubernetes.io/name: mysql
mysql.bitpoke.org/cluster: <local-openbayes>
role: master
type: NodePort
在使用的过程中遇到一个特殊的情况,mysql 如果和其他的服务共用一个 storageClass 可能会出现 io 抢占的情况,导致 mysql 的延迟非常巨大。目前 k8s 还没有一个很好的办法解决这个问题。唯一想到的就是为 mysql 分配一套单独的 storageClass(比如 local storage path 的方案)。