K8s 环境下 Canal 单机服务部署与自动化注册实践
1. 为什么要在K8s中部署Canal服务最近几年数据同步的需求越来越普遍特别是在微服务架构下数据库变更的实时捕获和分发变得尤为重要。Canal作为阿里巴巴开源的MySQL数据库增量日志解析工具正好能满足这个需求。它伪装成MySQL slave通过解析binlog来获取数据变更然后将这些变更事件推送给下游消费者。在K8s环境中部署Canal有几个明显优势资源隔离通过K8s的namespace和resource limits可以避免Canal服务影响其他应用弹性伸缩当数据变更量增大时可以快速扩展canal-server实例高可用结合K8s的健康检查机制可以确保服务持续可用简化部署通过yaml文件定义整个部署过程实现一键部署我去年在一个电商项目中就遇到过这样的场景订单系统和库存系统需要实时同步数据当时就是通过K8s部署的Canal实现的效果非常稳定。2. 部署前的准备工作2.1 环境需求检查在开始部署前建议先确认你的K8s环境满足以下条件K8s集群版本不低于1.16我们测试过1.16-1.22都兼容至少2个可用节点每个节点4核8G以上配置已安装Ingress ControllerNginx或Traefik都可以准备一个MySQL 5.7实例用于存储canal-admin的配置数据kubectl命令行工具已配置好集群访问权限2.2 数据库准备Canal-admin需要一个独立的MySQL数据库来存储配置信息。这里有个小技巧建议单独为Canal创建数据库用户而不是直接用root账号。执行以下SQL创建专用用户CREATE USER canal% IDENTIFIED BY canal_password; GRANT ALL PRIVILEGES ON canal_manager.* TO canal%; FLUSH PRIVILEGES;然后初始化数据库结构。可以从官方GitHub获取最新的SQL脚本wget https://raw.githubusercontent.com/alibaba/canal/canal-1.1.6/admin/admin-web/src/main/resources/canal_manager.sql mysql -u canal -p canal_manager canal_manager.sql3. 部署Canal-Admin管理端3.1 编写K8s部署文件Canal-admin是整个Canal体系的管理控制台我们需要先部署它。下面这个yaml文件是我在实际项目中优化过的版本增加了资源限制和健康检查apiVersion: v1 kind: ConfigMap metadata: name: canal-admin-config data: application.yml: | server: port: 8089 spring: datasource: url: jdbc:mysql://mysql-host:3306/canal_manager?useUnicodetruecharacterEncodingUTF-8 username: canal password: canal_password driver-class-name: com.mysql.jdbc.Driver canal: adminUser: admin adminPasswd: 123456 --- apiVersion: apps/v1 kind: Deployment metadata: name: canal-admin spec: replicas: 1 selector: matchLabels: app: canal-admin template: metadata: labels: app: canal-admin spec: containers: - name: canal-admin image: canal/canal-admin:v1.1.6 ports: - containerPort: 8089 volumeMounts: - name: config mountPath: /home/admin/canal-admin/conf/application.yml subPath: application.yml resources: limits: cpu: 1 memory: 2Gi requests: cpu: 500m memory: 1Gi livenessProbe: httpGet: path: / port: 8089 initialDelaySeconds: 30 periodSeconds: 10 volumes: - name: config configMap: name: canal-admin-config3.2 部署与验证执行部署命令kubectl apply -f canal-admin-deployment.yaml部署完成后可以通过以下命令检查状态kubectl get pods -l appcanal-admin kubectl logs -f pod-name如果一切正常你应该能看到类似这样的日志2023-06-15 08:12:34.123 INFO 1 --- [main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8089 (http)4. 部署Canal-Server单机版4.1 准备部署文件单机版Canal-server的部署相对简单但有几个关键配置需要注意apiVersion: apps/v1 kind: StatefulSet metadata: name: canal-server spec: serviceName: canal-server replicas: 1 selector: matchLabels: app: canal-server template: metadata: labels: app: canal-server spec: containers: - name: canal-server image: canal/canal-server:v1.1.6 env: - name: canal.admin.manager value: http://canal-admin:8089 - name: canal.admin.user value: admin - name: canal.admin.passwd value: 6BB4837EB74329105EE4568DDA7DC67ED2CA2AD9 - name: canal.register.ip value: canal-server-0.canal-server.default.svc.cluster.local - name: canal.admin.register.auto value: true ports: - containerPort: 11111 name: metrics - containerPort: 11112 name: admin resources: limits: cpu: 2 memory: 4Gi requests: cpu: 1 memory: 2Gi4.2 自动注册配置这里有几个关键点需要注意canal.register.ip必须设置为K8s内部可解析的地址密码需要使用MySQL的password函数加密后的值自动注册功能需要确保canal-server能访问到canal-admin的服务可以通过以下命令获取密码的加密值SELECT PASSWORD(your_password);5. 验证与问题排查5.1 检查服务状态部署完成后可以通过以下步骤验证登录canal-admin控制台默认账号admin/123456在服务器管理页面应该能看到自动注册的canal-server实例检查实例状态是否为运行中如果状态异常可以按以下步骤排查# 查看pod日志 kubectl logs -f canal-server-0 # 检查网络连通性 kubectl exec -it canal-server-0 -- curl -v http://canal-admin:8089 # 检查资源配置 kubectl describe pod canal-server-05.2 常见问题解决在实际部署中我遇到过几个典型问题注册失败通常是因为网络策略阻止了pod间的通信检查NetworkPolicy配置内存不足解析大事务时Canal可能消耗较多内存适当增加memory limitbinlog位置错误可以在admin控制台重置binlog位置6. 生产环境优化建议经过多个项目的实践我总结了一些优化经验资源分配canal-admin1核2G足够canal-server建议2核4G起步根据数据量调整监控配置- name: METRICS_PULL value: true - name: METRICS_PORT value: 11111然后可以通过Prometheus采集监控指标持久化存储 对于生产环境建议为canal-server添加PVC来持久化meta.dat文件避免重启后重新定位binlog位置网络策略 限制只有特定namespace可以访问canal-server的admin端口(11112)7. 扩展与集成Canal部署完成后可以很方便地与各种系统集成Kafka集成 在canal-admin中配置adapter将变更事件发送到KafkaElasticsearch同步 使用canal-adapter实现MySQL到ES的实时同步数据仓库ETL 将变更事件发送到Flink等流处理引擎进行实时ETL我在最近的一个项目中就使用了CanalFlink的组合实现了订单数据的实时数仓构建延迟控制在秒级。