尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

【DOCKER容器实战】-2 MySQL

【DOCKER容器实战】-2 MySQL 文章目录容器化应用实战MySQL一、单节点部署1. 启动 MySQL 容器2. 容器内客户端直接访问3. 宿主机客户端访问二、主从复制集群部署1. 主节点部署2. 主节点配置my.cnf3. 从节点部署4. 使用自定义网络替代 --link① --link 有什么缺点为什么淘汰② 自定义网络能干什么③ MySQL 主从完整实操替换替换 --link④ 常用网络命令⑤ 三种 docker 网络简单对比⑥ 主从复制里的 DNS 小重点5. 从节点配置my.cnf6. 主库创建复制账号7. 查看主库 binlog 状态8. 从库配置并启动复制三、常见报错排查1. ERROR 1794server-id 未配置或未生效2. ERROR 3021IO 线程运行中修改主从配置四、命令速查容器化应用实战MySQL[!note] 核心摘要数据持久化挂载/var/lib/mysql数据目录容器删除后数据仍保留在宿主机主从复制主库开启 binlog 创建复制账号从库change master tostart slaveSlave_IO_Running与Slave_SQL_Running均为 Yes 即成功容器互联--link已过时改用自定义网络容器名直接当域名用高频报错ERROR 1794 是server-id未配置/未生效ERROR 3021 是未先stop slave就执行change master to官方参考Hardened Images catalog | MySQL | Guides | Docker Hub一、单节点部署1. 启动 MySQL 容器[rootlocalhost ~]# docker run -p 3306:3306 \--namemysql_01\-v/opt/mysql/log:/var/log/mysql\-v/opt/mysql/data:/var/lib/mysql\-v/opt/mysql/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORDroot\-d\mysql:5.7 4513fdf2d6a9bb95e2d9b80319149abf15ecd362a25702d4698a03c8a0a9bd50单行写法[rootlocalhost ~]# docker run -d -p 3306:3306 --name mysql -v /opt/mysql/log:/var/log/mysql -v /opt/mysql/data:/var/lib/mysql -v /opt/mysql/conf:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORDroot mysql:5.7ebd20c54e8d4d3f43c609aa0caaab99f717b0ce765892f81d64763847d603380[rootlocalhost ~]# docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ebd20c54e8d4 mysql:5.7docker-entrypoint.s…4seconds ago Up4seconds0.0.0.0:3306-3306/tcp, :::3306-3306/tcp,33060/tcp mysql参数解析-p 3306:3306端口映射宿主机 3306 映射容器 mysql 3306 端口--name mysql给容器设置名字-v数据卷挂载三处/opt/mysql/log:/var/log/mysql日志目录挂载/opt/mysql/data:/var/lib/mysql数据库数据目录挂载最重要持久化数据/opt/mysql/conf:/etc/mysql/conf.d自定义配置文件挂载-e MYSQL_ROOT_PASSWORDroot环境变量设置 root 用户密码为 root-d后台守护模式运行mysql:5.7使用 mysql 5.7 镜像[!note] 数据持久化33060 是 mysql 5.7 默认 X-Protocol 端口。数据挂载到宿主机就算容器删除数据库数据还保存在宿主机/opt/mysql/data实现数据持久化。批量停止删除容器# 停止所有容器dockerstop$(dockerps-aq)# 删除所有容器dockerrm$(dockerps-aq)2. 容器内客户端直接访问[rootlocalhost ~]# docker exec -it mysql mysql -uroot -prootmysql:[Warning]Using a password on thecommandline interface can be insecure. Welcome to the MySQL monitor. Commands end with;or\g. Your MySQL connectionidis2Server version:5.7.44 MySQL Community Server(GPL)Copyright(c)2000,2023, Oracle and/or its affiliates.... mysql参数说明docker exec -it mysql-i保持标准输入打开-t分配伪终端mysql容器名称后面的mysql -uroot -proot容器内部执行 mysql 客户端命令-uroot用户名 root-proot密码 root[!warning] 密码安全直接在命令行写密码不安全会留下历史记录。更安全的登录方式不把密码写在命令行dockerexec-itmysql mysql-uroot-p执行后交互式输入密码不会泄露密码到命令历史。![[03_云原生/Docker/image/7d0471b09959ff74432b2dcae1355cb4_MD5.jpg]]3. 宿主机客户端访问先在宿主机安装 mariadb 客户端协议兼容可连接 MySQL[rootlocalhost ~]# yum install mariadb -y[rootlocalhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306Welcome to the MariaDB monitor. Commands end with;or\g. Your MySQL connectionidis3Server version:5.7.44 MySQL Community Server(GPL)Copyright(c)2000,2018, Oracle, MariaDB Corporation Ab and others. Typehelp;or\hforhelp. Type\ctoclearthe current input statement. MySQL[(none)]show databases;--------------------|Database|--------------------|information_schema||mysql||performance_schema||sys|参数解释yum install mariadb -y宿主机安装 mariadb 客户端用来连接 docker 里的 mysql 服务mysql连接参数-h 192.168.100.152数据库服务 IP宿主机 IP-P 3306端口大写 P宿主机映射端口-uroot用户名 root-proot密码 root[!warning] 连接地址注意虽然用的是 mariadb 客户端但是可以正常连接 MySQL 5.7 服务协议兼容。-h指定宿主机 IP不要写127.0.0.1127.0.0.1是容器内部回环地址。二、主从复制集群部署1. 主节点部署[rootlocalhost ~]# docker run -p 3306:3306 \--namemysql_master\-v/opt/mysql_master/log:/var/log/mysql\-v/opt/mysql_master/data:/var/lib/mysql\-v/opt/mysql_master/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORDroot\-d\mysql:5.7 4ffff00b1ec30ecc25fa32a5260101dd757b11416fbb451807784535ccd4ca0d[rootlocalhost ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f28374fcd5a4 mysql:5.7docker-entrypoint.s…5seconds ago Up5seconds0.0.0.0:3306-3306/tcp, :::3306-3306/tcp,33060/tcp mysql_master验证登录[rootlocalhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306Welcome to the MariaDB monitor. Commands end with;or\g. Your MySQL connectionidis2Server version:5.7.44 MySQL Community Server(GPL)Copyright(c)2000,2018, Oracle, MariaDB Corporation Ab and others. Typehelp;or\hforhelp. Type\ctoclearthe current input statement. MySQL[(none)]参数说明--name mysql_master容器命名为主节点mysql_master挂载目录全部带上mysql_master区分主节点数据避免和从节点目录冲突/opt/mysql_master/log主节点日志/opt/mysql_master/data主节点数据文件/opt/mysql_master/conf主节点配置文件-p 3306:3306主节点映射宿主机 3306 端口环境变量MYSQL_ROOT_PASSWORDroot设置 root 密码登录使用宿主机 IP192.168.100.152端口 3306 验证连通性。2. 主节点配置my.cnf[rootlocalhost ~]# vim /opt/mysql_master/conf/my.cnf[client] default-character-setutf8 [mysql] default-character-setutf8 [mysqld] init_connectSET collation_connection utf8_unicode_ci init_connectSET NAMES utf8 character-set-serverutf8 collation-serverutf8_unicode_ci skip-character-set-client-handshake skip-name-resolve server_id1 log-binmysql-bin read-only0 binlog-do-dbschool replicate-ignore-dbmysql replicate-ignore-dbsys replicate-ignore-dbinformation_schema replicate-ignore-dbperformance_schema核心主从配置项说明server_id1数据库节点 ID主库设置为 1从库必须是别的数字集群内不能重复log-binmysql-bin开启二进制日志文件名前缀mysql-bin主从复制依赖 binlogread-only0主库关闭只读可以读写binlog-do-dbschool只把school库的变更记录进 binlog只同步这个库replicate-ignore-db忽略同步的库mysql、sys、information_schema、performance_schema系统库不同步skip-name-resolve跳过域名解析加快数据库连接速度上面一大部分是 utf8 字符集相关配置统一数据库字符集修改完配置后需要重启mysql_master容器生效dockerrestart mysql_master3. 从节点部署[rootlocalhost ~]# docker run -p 3307:3306 \--namemysql_slave\-v/opt/mysql_slave/log:/var/log/mysql\-v/opt/mysql_slave/data:/var/lib/mysql\-v/opt/mysql_slave/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORDroot\-d\--linkmysql_master:mysql_master\mysql:5.7 5c1ebfd265d0b8ec706408bf2681d82d5039f78cb33fe292234c888a3f8f3d50[rootlocalhost ~]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5c1ebfd265d0 mysql:5.7docker-entrypoint.s…31seconds ago Up30seconds33060/tcp,0.0.0.0:3307-3306/tcp, :::3307-3306/tcp mysql_slave f28374fcd5a4 mysql:5.7docker-entrypoint.s…10hours ago Up10hours0.0.0.0:3306-3306/tcp, :::3306-3306/tcp,33060/tcp mysql_master参数说明-p 3307:3306从库宿主机端口使用3307容器内部依然 3306和主库端口区分开--name mysql_slave容器命名为从节点挂载目录全部为mysql_slave与主库目录隔离防止数据冲突--link mysql_master:mysql_master旧版 docker 容器互联在 slave 容器内可以用主机名mysql_master访问主库容器root 密码同样设置为root[!warning]--link已过时--link属于过时技术新版本推荐使用 docker 自定义网络见下节。4. 使用自定义网络替代--link--link是老旧的容器互联方案已经不推荐继续使用自定义网络custom bridge是 docker 官方推荐的替代方案用来解决容器之间互相通信。①--link有什么缺点为什么淘汰只能单向A link BA 能访问 BB 不能访问 A配置写死在容器启动参数容器重启后域名解析偶发失效只支持桥接默认bridge网络不支持多容器集群做主从、集群很不方便② 自定义网络能干什么创建一个独立网桥加入这个网络的所有容器互相可以通过容器名字直接通信双向互通不需要 linkDNS 自动解析容器名直接当作主机名网络隔离不在这个网络的容器访问不到容器后期可以随时加入/退出网络不用重建容器③ MySQL 主从完整实操替换替换--link创建自定义网络# 创建名为 mysql-net 的自定义桥接网络dockernetwork create mysql-net启动主节点加入自定义网络去掉--linkdockerrun-p3306:3306\--namemysql_master\--networkmysql-net\-v/opt/mysql_master/log:/var/log/mysql\-v/opt/mysql_master/data:/var/lib/mysql\-v/opt/mysql_master/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORDroot\-dmysql:5.7启动从节点同样加入同一个网络删掉--linkdockerrun-p3307:3306\--namemysql_slave\--networkmysql-net\-v/opt/mysql_slave/log:/var/log/mysql\-v/opt/mysql_slave/data:/var/lib/mysql\-v/opt/mysql_slave/conf:/etc/mysql/conf.d\-eMYSQL_ROOT_PASSWORDroot\-dmysql:5.7[!note] 效果此时在mysql_slave容器内部直接写主机名mysql_master就能访问主库效果和 link 一样但是更稳定。配置主从复制时master_host就填mysql_master。④ 常用网络命令# 查看所有网络dockernetworkls# 查看网络详情看哪些容器挂载进来dockernetwork inspect mysql-net# 将已有容器追加加入网络容器已经启动也可以加dockernetwork connect mysql-net 容器名# 容器脱离网络dockernetwork disconnect mysql-net 容器名# 删除网络没有容器挂载才能删dockernetworkrmmysql-net⑤ 三种 docker 网络简单对比网络类型用途bridge默认默认网桥容器之间默认不通需要 link老旧自定义 bridge开发/测试用适合 MySQL 主从这种多容器集群推荐host容器直接复用宿主机网络不做端口映射性能高⑥ 主从复制里的 DNS 小重点在从库执行change master toCHANGE MASTERTOMASTER_HOSTmysql_master,# 自定义网络直接写容器名字DNS 自动解析MASTER_USERrepl,MASTER_PASSWORDrepl,MASTER_LOG_FILEmysql-bin.000001,MASTER_LOG_POS154;MASTER_HOST直接填容器名字不需要写 IP自定义网络 DNS 自动解析。[!tip] 总结以后做容器集群不要再写--link直接新建自定义网络所有容器--network xxx加入同一个网络即可。主库、从库两个容器都必须加入同一个自定义网络。原理自定义网络只有处在这个网络里面的容器才可以用容器名字互相 DNS 解析通信。只有从库进去、主库没进mysql_slave解析不到mysql_master主从复制连不上。两个都加入同一个mysql-netslave 内部写主机名mysql_master就能找到主库。两种情况处理情况 1还没启动容器全新部署推荐创建网络docker network create mysql-net主库启动参数加上--network mysql-net从库启动参数加上--network mysql-net直接删掉旧的--link参数不再使用情况 2主库mysql_master已经跑起来了容器已存在不用删掉重建主库直接把运行中的容器追加接入网络# 将已运行的主库加入自定义网络dockernetwork connect mysql-net mysql_master# 再把从库也接进来如果从库也已经启动dockernetwork connect mysql-net mysql_slave验证是否加入成功dockernetwork inspect mysql-net看输出里的Containers节点要同时出现mysql_master和mysql_slave两个容器。测试连通性——进入从库容器内部测试能否解析主库名字dockerexec-itmysql_slavepingmysql_master能 ping 通代表网络没问题后面配置主从复制时MASTER_HOSTmysql_master就可以生效。[!note] 小提醒宿主机访问数据库不受自定义网络影响宿主机依旧访问192.168.100.152:3306主、192.168.100.152:3307从端口映射依旧生效。自定义网络只管容器与容器之间互通不影响宿主机访问容器。5. 从节点配置my.cnf[rootlocalhost ~]# vim /opt/mysql_slave/conf/my.cnf[client] default-character-setutf8 [mysql] default-character-setutf8 [mysqld] init_connectSET collation_connection utf8_unicode_ci init_connectSET NAMES utf8 character-set-serverutf8 collation-serverutf8_unicode_ci skip-character-set-client-handshake skip-name-resolve server_id2 log-binmysql-bin read-only1 binlog-do-dbschool replicate-ignore-dbmysql replicate-ignore-dbsys replicate-ignore-dbinformation_schema replicate-ignore-dbperformance_schema和主库配置关键差异server_id2必须和主库不一样主库是 1从库设置 2集群所有节点 id 不能重复read-only1从库开启只读普通用户不能写入super 权限账号依旧可以写字符集、binlog-do-db、忽略同步库的配置和主库保持一致修改配置后重启从库容器生效dockerrestart mysql_slave[!note] 补充知识点从库开启log-bin代表开启从库二进制日志用于链式主从A→B→CB 既是从库又是下一级的主库普通一主一从场景从库也可以不开 binlog。read-only1不会限制 root 超级账号写入生产从库日常不要用 root 操作。6. 主库创建复制账号[rootlocalhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306MySQL[(none)]grantreplicationslaveon*.*tobackup%identifiedby123456;Query OK,0rowsaffected,1warning(0.02sec)MySQL[(none)]flushprivileges;Query OK,0rowsaffected(0.01sec)语句解释grant replication slave on *.* to backup% identified by 123456;创建主从复制专用账号backup密码123456%代表允许从任意地址连接只授予replication slave复制权限不授予业务增删改查权限。[!note] MySQL 5.7 会报 1 个 warning是密码策略提示不影响功能。flush privileges;刷新权限让新建账号立刻生效。docker restart mysql_master重启主库容器加载前面写好的 my.cnf 主从配置文件。[!warning] 重启后必须重新获取 binlog 状态容器重启之后需要重新登录 mysql执行show master status;拿到 binlog 文件名和 position 偏移量后面从库配置要用到。7. 查看主库 binlog 状态[rootlocalhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3306Welcome to the MariaDB monitor. Commands end with;or\g. Your MySQL connectionidis2Server version:5.7.44-log MySQL Community Server(GPL)Copyright(c)2000,2018, Oracle, MariaDB Corporation Ab and others. Typehelp;or\hforhelp. Type\ctoclearthe current input statement.MySQL[(none)]showmasterstatus\G;***************************1.row***************************File: mysql-bin.000001Position:154Binlog_Do_DB: school Binlog_Ignore_DB: Executed_Gtid_Set:1rowinset(0.00sec)字段说明File: mysql-bin.000001binlog 日志文件名从库配置MASTER_LOG_FILE需要填这个Position: 154binlog 偏移位置从库配置MASTER_LOG_POS需要填这个Binlog_Do_DB: school主库只记录school库的二进制日志对应 my.cnf 里binlog-do-dbschool[!warning] 重要主库一旦重启File 和 Position 会发生变化配置从库之前一定要重新执行show master status\G;拿到最新的值。这两个参数后面要复制到从库的change master to语句中。示例后续从库要填写的片段CHANGE MASTERTOMASTER_LOG_FILEmysql-bin.000001,MASTER_LOG_POS154;8. 从库配置并启动复制[rootlocalhost ~]# docker restart mysql_slave[rootlocalhost ~]# mysql -h 192.168.100.152 -uroot -proot -P 3307MySQL[(none)]change mastertomaster_hostmysql_master,master_userbackup,master_password123456,master_log_filemysql-bin.000001,master_log_pos154,master_port3306;MySQL[(none)]startslave;参数解释master_hostmysql_master自定义网络/link 环境下直接写主库容器名作为主机名不需要写 IPmaster_userbackup主库上创建的复制账号master_password123456复制账号密码master_log_filemysql-bin.000001主库show master status拿到的 binlog 文件名master_log_pos154主库 binlog 偏移位置master_port3306容器内部端口不是宿主机映射端口填 3306不要填宿主机的端口start slave;启动从库复制线程。查看从库复制状态showslavestatus\G;重点看这两个条件全部为 Yes 才算主从成功Slave_IO_Running: Yes Slave_SQL_Running: Yes![[03_云原生/Docker/image/c15646a7780f0d29ff58408c4b380af1_MD5.jpg]][!note] 排障方向IO 线程 No网络不通、账号密码错误、主机名解析失败SQL 线程 No主从数据不一致主键冲突等问题[!warning] 小坑提醒如果之前配置过主从执行change master to前先执行stop slave; reset slave all;清理旧配置避免残留旧参数干扰。三、常见报错排查1. ERROR 1794server-id 未配置或未生效ERROR 1794 (HY000): Slave is not configured or failed to initialize properly. You must at least set --server-id to enable either a master or a slave. Additional error messages can be found in the MySQL error log.报错原因核心从库没有配置server-id或者 server-id 没生效。MySQL 5.7 做主从不管主库还是从库server-id必须配置且主从不能相同。主库 my.cnfserver-id1从库 my.cnfserver-id2不能和主库一样常见 4 种情况✅ 写了 my.cnf但是没有重启 mysql_slave 容器配置没加载。你前面虽然改了 slave 的配置文件但是没执行docker restart mysql_slavemysql 读取的还是旧配置server-id 不存在。❌ my.cnf 挂载/映射错误docker 容器内 mysql 根本没有读到你的配置文件。docker 部署很容易踩这个坑宿主机改了 my.cnf但是容器没挂载上容器内部配置没变。❌ 从库server-id和主库server-id值一模一样冲突。❌ 配置写错例如server-id写成 0或者写在[client]段不是写在[mysqld]段。[!warning]server-id必须写在[mysqld]下面写在别的段落不生效。排查步骤进入从库容器内部确认 mysql 读到的 server-iddockerexec-itmysql_slave mysql-uroot-prootshow variables likeserver_id;如果返回server_id | 0代表配置完全没生效就是上面的问题。检查容器内 my.cnfdockerexec-itmysql_slavecat/etc/mysql/my.cnf确认[mysqld]下面有server-id2。修改完配置必须重启容器dockerrestart mysql_slave重启后再登录 mysql确认server_id不是 0再执行stop slave;reset slaveall;CHANGE MASTERTOmaster_hostmysql_master,master_userbackup,master_password123456,master_log_filemysql-bin.000001,master_log_pos154,master_port3306;startslave;showslavestatus\G[!tip] 排查经验docker mysql 镜像如果宿主机挂载配置文件失败宿主机改一万遍容器 mysql 都不会读取一定要进容器内部看配置不要只看宿主机文件。2. ERROR 3021IO 线程运行中修改主从配置ERROR 3021 (HY000): This operation cannot be performed with a running slave io thread; run STOP SLAVE IO_THREAD first.报错原因从库的 IO 复制线程还在运行不能直接执行change master to修改主从配置。change master to用来修改主库地址、binlog 文件名、偏移量必须先停止复制线程不能在 IO 线程运行状态直接改。完整正确操作顺序-- 1.先停止全部 slave 线程stop slave;-- 如果只想停 io 线程也可以 stop slave io_thread;-- 2.清除旧的主从记录多次调试强烈建议加上避免残留脏数据reset slaveall;-- 3.现在再执行 change master tochange mastertomaster_hostmysql_master,master_userbackup,master_password123456,master_log_filemysql-bin.000003,master_log_pos154,master_port3306;-- 4.启动复制startslave;-- 5.查看状态showslavestatus\G;小知识点区分stop slave;同时停止IO 线程 SQL 线程做change master to首选stop slave io_thread;只停止 IO 线程SQL 线程继续回放已经拿到的 binlogreset slave all;彻底清空从库所有主从配置适合反复调试主从环境改配置前推荐执行[!warning] 踩坑提醒如果你之前执行过start slave;只要没 stopIO 线程就处于运行状态直接跑change master to就报 3021 错误。每次重新修改主从信息第一步先执行stop slave;。四、命令速查命令作用docker run -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORDroot -d mysql:5.7运行 MySQL 容器并设置 root 密码docker exec -it mysql mysql -uroot -p容器内登录 MySQL交互式输密码更安全docker restart mysql_master重启容器使配置生效docker network create mysql-net创建自定义网络docker network connect mysql-net 容器名将已运行容器加入网络show master status\G;查看主库 binlog 文件名与位置change master to ...; start slave;从库配置并启动主从复制show slave status\G;查看从库复制状态IO/SQL 均为 Yes 成功
返回列表