在 K8s 部署和运行 Canal 集群
相关背景
本文是基于 Canal 最新源码,对于其进行符合业务的优化后,再编译、打包和部署到 K8s。同时,由于在之前的文章已经讨论过 Canal 的 binlog 账户创建、 MySQL 数据库部署,以及相关包变更等,下文不再涉及此类内容。
由于使用 RocketMQ
的服务模式,避免无效编译打包,将目录下 pox.xml
文件中,关于 client-adapter
和 example
相关模块注释。
在 Canal 源码中(根目录下),docker
文件夹中的脚本文件(*.sh
)的功能,是将源码编译打包为容器,以及运行容器。相关文件用途说明如下:
build.sh
:将源码编码打包为canal-admin
和canal-deployer
两个容器镜像;Dockerfile
: 用于定义和构建canal-deployer
Docker 镜像;Dockerfile_admin
: 用于定义和构建canal-admin
Docker 镜像;image/app.sh
: 用于容器启停canal-deployer
应用;image/app_admin.sh
: 用于容器启停canal-admin
应用;
其它文件暂不作说明。现分 Canal Admin 和 Canal Deployer 两个部分,讨论如何进行 K8s 部署和运行。
Canal Admin
变更运行脚本
由于适配现有 CI/CD 流水线,需要将build.sh
转化为流水线步骤,以及调整相应的脚本文件:image/app_admin.sh
。
转化 build.sh
为流水线步骤
build.sh
中 Admin 相关的内容如下:
;
&& && ;
其中变量 $BASE
为build.sh
的目录路径,即/path/canal/docker
,该文件实现功能步骤如下:
- 删除该目录下名称格式为
canal.*.tar.gz
的所有文件; - 回到
/path/canal
目录,使用 Maven 清理并打包 Canal 源码,生成的最终压缩文件在/path/canal/target
目录下; - 将
/path/canal/target
目录中的名称格式为canal.admin-*.tar.gz
的文件,复制到目录/path/canal/docker
; - 根据
/path/canal/docker/Dockerfile_admin
文件的定义,将目录/path/canal/docker
下的相关文件打包为容器镜像。
变更 image/app_admin.sh
由于使用独立的 MySQL 的数据库,容器中 MySQL 不再使用,因此,需要移除该文件中 MySQL 相关的内容。与此同时,使用独立的数据库,需要将 K8s 的 ConfigMap 配置的 application.yml
替换到原 conf
下,即在 start_admin()
函数中,添加以下内容:
上述代码功能为先删除原有默认配置,再复制 K8s 的 ConfigMap 配置的 application.yml
替换原有配置。
其中,appconfig
为 K8s 的 ConfigMap 挂载目录,在此之前,需要在 K8s 上新建 Key 为 application.yml
的配置,容器启动时,会在 appconfig
目录下,将该配置生成 application.yml
文件。
若不这样处理,k8s 部署 canal-admin 数据保存不到canal_manager 中。
image/app_admin.sh
的 start_admin()
函数最终如下:
源码编译打包
在使用流水线进行打包前,我们可以在相关环境使用以下命令进行预验证:
mvn clean package -Dmaven.test.skip -Denv=release
Linux 环境打包生成的文件在在 /path/canal/target
目录下,文件名称格式为 canal.admin-*.tar.gz
和 canal.deployer-*.tar.gz
。
构建容器镜像
调整 Docker 代理地址
因中国内政策原因,无法访问 hub.docker.com
获取镜像,构建容器镜像前,需要更新可用的国内镜像代理,以下是截止目前可用的代理地址:
调整 Dockerfile_admin
因 canal-admin
运行容器不需要 MySQL,我们也不需要将其打包到容器镜像,只需要 Dockerfile_admin
中基础镜像,变更为 (canal-deployer
)Dockerfile
中使用的基础镜像,即
##删除原 FROM canal/osadmin:v3-amd64,替换为
构建镜像
执行构建命令:
docker build --no-cache -t canal-admin:xxx /path/canal/docker/ -f /path/canal/docker/Dockerfile_admin
构建完成后,再将该包上传到 harbor,然后删除本地镜像,以释放空间。
部署到 K8s
由于 canal-admin-service.yaml
和 canal-admin-deployment.yaml
,视环境而定,这里不再赘述。只给出 canal-admin-configmap.yaml
部分配置:
apiVersion: v1
data:
application.yml: |-
server:
port: 8080
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
spring.datasource:
address: ipaddress:3306
database: canal_manager
username: canal_user
password: canal_password
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://${spring.datasource.address}/${spring.datasource.database}?useUnicode=true&characterEncoding=UTF-8&useSSL=false
hikari:
maximum-pool-size: 30
minimum-idle: 1
canal:
adminUser: admin
adminPasswd: 123456
kind: ConfigMap
metadata:
name: canal-admin-configmap
namespace: canal
上述配置中 server.port=8080
,是通过 K8s 设定 canal-admin-service
的端口是 8080
,需要保持一致,否则无法访问。
Canal Deployer
Canal Deployer 也称 Canal Server,是本次部署的关键,决定 Canal 能否应用的成败。
本文不会说明如何成功运行 ZooKeeper(以下称“ZK”),但一定要确保有正常可用的 ZK。由于 Canal Admin 需要通过 ZK 获取 Canal Server 运行状态,以及 Canal Server 执行 binlog 同步也无法离开 ZK,如果没有正常 ZK,就无法确定 Canal 是否部署成功,也无法开展正常业务。(忽视了 ZK 的可用性,让我额外花了两天排查问题。)
变更运行脚本
与 Admin 一样,