docker安装Canal
- 前情提示
- 安装MySQL
-
- docker安装MySQL
-
- [1. 拉取镜像](#1. 拉取镜像)
- [2. 创建容器映射宿主机目录](#2. 创建容器映射宿主机目录)
- [3. docker run](#3. docker run)
- 配置mysql
- 安装Canal
- 踩坑

前情提示
关于版本问题,官方也没有详细说明从哪个版本开始支持MySQL8.0以上版本,之后的Release都是更新binlog的解析功能,所以推荐8.0以上版本推荐最新版,5.7推荐1.1.5
v1.1.4
支持mysql8.0新的caching_sha2_password认证协议
v1.1.7
支持MySQL 8.0、Mariadb 10.x版本的compress binlog解析
v1.1.8
适配MySQL 8.4、Mariadb 11、Percona 8.0、PolarDB-X 2.0的版本

所以如果遇到Canal一直启动不成功 docker start canal 30s之后自动退出,先别慌,可能是你的配置有问题,mysql无法访问等问题
安装MySQL
docker安装MySQL
1. 拉取镜像
docker pull mysql:5.7
2. 创建容器映射宿主机目录
mkdir -p /mydata/mysql/log
mkdir -p /mydata/mysql/data
mkdir -p /mydata/mysql/conf
3. docker run
sudo docker run -d -p 3306:3306 --name mysql \
-v /mydata/mysql/log:/var/log/mysql \
-v /mydata/mysql/data:/var/lib/mysql \
-v /mydata/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7
命令解释:
docker run:在docker中启动一个容器实例
-d:该容器在后台运行
-p 3306:3306:容器与主机映射端口为,主机3306,容器3306
--name mysql:容器运行后的名称
-v /mysqldata/mysql/log:/var/log/mysql:将容器/var/log/mysql目录下的数据,备份到主机的 /mysqldata/mysql/log目录下
-v /mysqldata/mysql/data:/var/lib/mysql:将容器/var/lib/mysql目录下的数据,备份到主机的 /mysqldata/mysql/data目录下
-v /mysqldata/mysql/conf:/etc/mysql:将容器/etc/mysql目录下的数据,备份到主机的 mysqldata/mysql/conf目录下
-e MYSQL_ROOT_PASSWORD=root:设置当前mysql实例的密码为root
mysql:5.7:需要运行的容器名称以及版本号
配置mysql
打开mysql挂载主机目录下( /mydata/mysql/conf )的 my.cnf 配置文件,添加以下配置
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
init_connect=' SET collation_connection = utf8_unicode_ci '
init_connect=' SET NAMES utf8 '
character-set-server=utf8
collation-server=utf8_unicode_ci
skip-character-set-client-handshake
skip-name-resolve
datadir=/var/lib/mysql
# start binlog
log-bin = /var/lib/mysql/mysql-bin
binlog-do-db=heima
server-id = 1000
重启mysql
docker restart mysql
新建canal用户
-
执行CREATE USER前可先删除旧用户:
sqlDROP USER IF EXISTS 'canal'@'%';
赋予权限
授权 canal 链接 MySQL 账号具有作为 MySQL slave 的权限, 如果已有账户可直接 grant
create user canal@'%' IDENTIFIED by 'canal'; GRANT SELECT, REPLICATION SLAVE, REPLICATION CLIENT,SUPER ON *.* TO 'canal'@'%' identified by 'canal'; FLUSH PRIVILEGES;
参数介绍:
参数 | 作用 |
---|---|
'canal' |
用户名(Canal 服务连接 MySQL 时使用的账号名) |
'%' |
允许从任意主机 连接(% 是通配符,若限制 IP 可改为 '192.168.%' ) |
IDENTIFIED BY 'canal' |
设置用户密码为 canal (需与 Canal 容器配置的密码一致) |
SELECT |
允许读取数据(Canal 需要查询表结构和数据) |
REPLICATION SLAVE |
允许作为从库复制 Binlog(核心权限,Canal 伪装成 MySQL 从库) |
REPLICATION CLIENT |
允许查看主库/从库状态(如执行 SHOW MASTER STATUS ) |
ON *.* |
权限作用于所有数据库和表(可缩小为 heima.* 仅授权特定库) |
TO 'canal'@'%' |
将权限授予之前创建的 canal 用户 |
安装Canal
创建docker网络
解释一下原因:canal在启动时需要指定mysql的ip地址,去连接mysql,也可在配置文件中指定
但是 Docker 默认的桥接网络(bridge
)虽然允许容器间通信,但需要通过 IP 地址 (如 172.17.0.2:3306
),而容器的 IP 在重启时可能变化,导致配置不可靠。
解决方法:在自定义网络 heima
中,容器可以通过 名称 (如 mysql
、canal
)直接访问彼此,无需依赖 IP。
在
heima
网络中,Canal 只需配置mysql:3306
,Docker 会自动解析为 MySQL 容器的当前 IP-e canal.instance.master.address=mysql:3306 # 通过容器名访问
bash
# docker network create heima
docker network ls
docker network create heima
docker network connect heima mysql
# 可以查看到两个镜像的ip地址
docker network inspect heima
查看配置的heima网络
json
{
"Name": "heima",
"Id": "7b0eb7cc1ed6e5fb6d33b59e96b5cb3b35238391c6c0ffb6c2ed119862fb1739",
"Created": "2025-04-28T15:04:35.099533858+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.19.0.0/16",
"Gateway": "172.19.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"38540c02f0430d05fe63cb446a03806b5b3799e9a8a5895a25289e60f7a2bf39": {
"Name": "mysql",
"EndpointID": "0bd335bb4924588873beee55cf8b9a6581c8377367f96973e8af17022213fbd7",
"MacAddress": "02:42:ac:13:00:02",
"IPv4Address": "172.19.0.2/16",
"IPv6Address": ""
},
"f5dcd4769f47c41387d6ba4327aeb06d8d9383b5ec896db300115a9cd8686514": {
"Name": "canal",
"EndpointID": "3eced6f10ed910d16dc01799740d5ad7891164f3732684bd8430e0db9a09a63a",
"MacAddress": "02:42:ac:13:00:03",
"IPv4Address": "172.19.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
安装Canal
1.拉取canal镜像
## 拉取版本为v1.1.5的canal
docker pull canal/canal-server:v1.1.5
2.创建目录
mkdir -p /mydata/canal-server/conf
mkdir -p /mydata/canal-server/logs
mkdir -p /mydata/canal-server/conf/heima
docker cp containID:/home/admin/canal-server/conf/canal.properties /mydata/canal-server/conf
docker cp containID:/home/admin/canal-server/heima/instance.properties /mydata/canal-server/conf/heima
3.运行容器
docker run -p 11111:11111 --name canal \
-e canal.destinations=heima \
-e canal.instance.master.address=mysql:3306 \
-e canal.instance.dbUsername=canal \
-e canal.instance.dbPassword=canal \
-e canal.instance.connectionCharset=UTF-8 \
-e canal.instance.tsdb.enable=true \
-e canal.instance.gtidon=false \
-e canal.instance.filter.regex=heima\\..* \
--network heima \
-d canal/canal-server:v1.1.5
踩坑
问题1
2025-04-28 16:58:26.569 [destination = heima , address = /127.0.0.1:3306 , EventParser] ERROR c.a.o.c.p.inbound.mysql.rds.RdsBinlogEventParserProxy - dump address /127.0.0.1:3306 has an error, retrying. caused by com.alibaba.otter.canal.parse.exception.CanalParseException: java.io.IOException: connect /127.0.0.1:3306 failure
分析,Canal 服务无法连接到 MySQL 的核心问题是 配置中的 MySQL 地址错误
分析网络配置
-
heima
网络中已包含两个容器:
mysql
(IP:172.19.0.2
)canal
(IP:172.19.0.3
)
-
容器间网络互通正常。
最后的原因是canal.instance.master.address
未正确设置为 mysql:3306
而使用的是127.0.0.1:3306
因为mysql是在docker环境下运行的,桥接模式下基于docker0网桥分配IP地址和网关
docker stop canal
docker run ...
docker logs canal
docker exec -it canal /bin/bash
tail -n 50 canal-server/logs/heima/heima.log
