阿里云数据库Redis迁移到Kubernetes

背景

项目中业务应用都跑在Kubernetes托管集群,而数据服务原先使用的是阿里云提供的MySQL RDS实例和Redis云数据库。最近考虑到下面几个因素,决定将其更换为集群中自建的版本。

  • 可用性

    云数据库的一大优势是其可用性,MySQL和Redis都很容易配置成有双活保障的实例

    但项目可用性要求没有那么高的前提下并无太大优势,尤其是Kubernetes环境下服务器宕机后容器也能自动恢复运行

    尤其对于Redis而言,三节点的哨兵集群并不难配置

  • 成本

    对于小项目而言,成本也是一个重要的考量

    一个入门级MySQL RDS实例大约每年3800元,而一个基于云盘的自建数据库仅需SSD云盘费用(1元/GB/月)以及集群中少许CPU内存资源。以20GB的MySQL为例存储费用仅为每年240元。

    需要注意的是高效云盘/SSD云盘最小容量是20GB。云盘使用限制详见:https://www.alibabacloud.com/help/zh/doc-detail/134767.htm

  • 备份

    自建数据库的备份并不复杂,仅需配置对应云盘的快照即可

  • 监控

    Kubernetes集群内的MySQL/Redis可以很方面的打开metrics,统一通过Prometheus进行监控

MySQL

部署

阿里云购买的是MySQL 5.7.28的实例。

集群中采用 bitnami/mysql --version 4.5.2 的helm chart(这是最后一个5.7版本的chart,对应版本是5.7.26),并做如下修改:

  1. 镜像版本修改为 5.7.28-debian-9-r74
  2. sql-mode修改为空
  3. 指定storage class,数据库由于性能很重要,这里直接使用ssd云盘
  4. 不需要slave实例

完整values.yaml如下

image:
  tag: 5.7.28-debian-9-r74 # 镜像版本
  pullPolicy: IfNotPresent

root:
  password: PASSWORD

replication:
  enable: false

master:
  persistence:
    storageClass: "alicloud-disk-ssd" # SSD性能较好
    size: 20Gi
  config: |-
    [mysqld]
    default_authentication_plugin=mysql_native_password
    skip-name-resolve
    explicit_defaults_for_timestamp
    basedir=/opt/bitnami/mysql
    port=3306
    socket=/opt/bitnami/mysql/tmp/mysql.sock
    tmpdir=/opt/bitnami/mysql/tmp
    max_allowed_packet=16M
    bind-address=0.0.0.0
    pid-file=/opt/bitnami/mysql/tmp/mysqld.pid
    log-error=/opt/bitnami/mysql/logs/mysqld.log
    character-set-server=UTF8
    collation-server=utf8_general_ci
    sql-mode="" # 删除sql-mode,与原数据库相同

    [client]
    port=3306
    socket=/opt/bitnami/mysql/tmp/mysql.sock
    default-character-set=UTF8

    [manager]
    port=3306
    socket=/opt/bitnami/mysql/tmp/mysql.sock
    pid-file=/opt/bitnami/mysql/tmp/mysqld.pid

slave:
  replicas: 0

不过事后看此版本chart还有待完善,如无法为service定制annotations。还是应该尝试使用最新的chart,然后更改image tag。

数据迁移

首先尝试的是 mysqldump --all-databases,由于配置了不少用户,希望将系统表也一并备份并恢复。然而出现了

Storage engine 'InnoDB' does not support system tables

很可能阿里已经对数据库做了魔改,只好自行重建用户,转而只导出数据(假设集群mysql已经forward到本机33060端口)

$ sqlfile=`date +%Y_%m%d_%H%M`.sql
$ mysqldump -h rm-abcdefg.mysql.rds.aliyuncs.com -u root -p --databases db1 db2 db3 --single-transaction --set-gtid-purged=OFF > $sqlfile
$ cat preimport.sql $sqlfile postimport.sql | mysql -uroot -p -h127.0.0.1 -P33060

其中 preimort.sqlpostimport.sql 是可选的,为的是禁止唯一性和外键检查加速导入过程

$ cat preimport.sql
SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, AUTOCOMMIT = 0;
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS = 0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS = 0;
$ cat postimport.sql
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
SET AUTOCOMMIT = @OLD_AUTOCOMMIT;
COMMIT;

Redis

部署

阿里云购买的是Redis 4.0的实例。

集群中采用 bitnami/redis --version 7.1.1 的helm chart。为与应用现有配置保持一致,本次迁移暂时没有采用哨兵模式。

配置做了如下修改:

  1. 关闭了cluster模式
  2. 指定storage class,这里对存储性能要求不高,使用高效云盘即可
  3. 另外数据实时行要求没那么高,关闭了AOF使用RDB。请结合实际情况配置。
image:
  pullPolicy: IfNotPresent

cluster:
  enabled: false

usePassword: true
password: PASSWORD

master:
  persistence:
    storageClass: "alicloud-disk-efficiency"
    size: 20Gi

configmap: |-
  appendonly no # 关闭AOF
  save 900 1 # 打开RDB
  save 300 10
  save 60 10000

数据迁移

注意迁移前需要关闭RDB并重启实例使之生效,否则redis容器退出前会覆盖传入的rdb文件

configmap: |-
  appendonly no
  save "" # 关闭RDB

从阿里云Redis下载备份RDB文件,并传入redis pod

$ rdb=hins15788434_data_20210103183437.rdb
$ kubectl cp $rdb redis-master-0:/data/dump.rdb -n prod

重启Redis以后会自动从该RDB恢复

最后记得打开RDB,结合云盘快照应该可以避免大多数情况下的数据丢失

本地连接

最后聊一下一个实际的问题,即开发调试或者排查问题过程中需要连接到集群内的数据库或者Redis。

迁移前,连接阿里云数据库只需要连接到搭建的一个内网VPN即可。

最容易想到的是将集群内MySQL/Redis的Service类型设置成NodePort,这样VPN连接后只需要连接到任意一台集群节点IP的对应端口即可。不过这样如果集群内节点发生变化(比如节点被移除),连接方式就失效了。

事实上,还有一个更好的办法是利用集群配置的SLB,通过将Service类型设置成LoadBalancer,并且通过annotations指定要复用的SLB实例,并在SLB监听中增加相应端口即可实现暴露的IP不变。具体参考:https://help.aliyun.com/document_detail/86531.html

配置如下:

master:
  service:
    type: LoadBalancer
    annotations:
      service.beta.kubernetes.io/alibaba-cloud-loadbalancer-id: lb-id-here

效果如下:

$ kubectl get svc -n common mysql-mysql
NAME          TYPE           CLUSTER-IP    EXTERNAL-IP      PORT(S)          AGE
mysql-mysql   LoadBalancer   172.23.9.17   172.19.197.170   3306:32181/TCP   2d1h

其中 EXTERNAL-IP 即为对应SLB的内网IP,假设SLB监听配置的也是3306端口,则之后只需要通过 172.19.197.170:3306 即可访问到该数据库。

总结

本文总结了从阿里云数据库和Redis迁移到Kubernetes集群自建环境的一些经验,希望对大家有用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,639评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,093评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,079评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,329评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,343评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,047评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,645评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,565评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,095评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,201评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,338评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,014评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,701评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,194评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,320评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,685评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,345评论 2 358

推荐阅读更多精彩内容