MySQL-MGR实战指南:打造企业级高可用数据库集群

前言

在数字化时代,企业的数据安全和业务连续性至关重要。想象一下,当关键业务数据存储在数据库中,而数据库突然出现故障,或者面临硬件故障、网络中断、自然灾害等不可预知的灾难性事件时,企业如何确保数据的完整性和业务的正常运行?这就是为什么构建企业级高可用数据库集群变得至关重要。
MySQL-MGR(MySQL Group Replication)正是解决这一问题的强有力工具。它不仅能够提供数据的一致性和高可用性,还能在故障发生时自动进行故障转移,确保业务的连续性和数据的完整性。
本文将帮助您构建一个高效、可靠的数据库集群,应对各种挑战。

MGR的介绍

MySQL Group Replication(MGR)是MySQL官方在5.7.17版本引进的一个数据库高可用与高扩展的解决方案,以插件形式提供,实现了分布式下数据的最终一致性,总结MGR特点如下:
高一致性:基于分布式paxos协议实现组复制.集群是多个MySQL Server节点共同组成的分布式集群,每个Server都有完整的副本,它是基于ROW格式的二进制日志文件和GTID特性,保证数据一致性;
高容错性:自动故障检测机制,只要不是大多数节点都宕机就可以继续工作,内置防脑裂保护机制,在主节点故障时,MGR能够自动选举新的主节点继续处理事务,保持服务的连续性;
高扩展性:节点的增加与移除会自动更新组成员信息,新节点加入后,自动从其他节点同步增量数据,直到与其他节点数据一致;
高灵活性:提供单主模式和多主模式,单主模式在主库宕机后能够自动选主,所有写入都在主节点进行,多主模式支持多节点写入。工作中优先使用单主模式。
优点:
基本无延迟,延迟比异步的小很多
支持多写模式,但是目前还不是很成熟
数据的强一致性,可以保证数据事务不丢失

事务处理流程:

事务发起:客户端向任意MGR组内节点提交事务。
事务验证:节点通过内置的事务一致性检查机制(如冲突检测、全局唯一事务ID(GTID)校验等)确保事务符合组复制的要求。
事务传播:通过复制协议模块,节点将待提交的事务以消息的形式广播到组内其他节点。每个节点接收到消息后,将其暂存到本地队列中。
共识达成:借助Paxos协议(或其变体),组内节点对事务的提交顺序进行协商并达成一致。只有当大多数节点(法定数量)同意某个事务的提交顺序时,该事务才能被确认为可执行。
事务执行:各节点按照达成一致的顺序执行事务。即使在网络分区或节点故障的情况下,只要还有足够数量的节点存活且能够相互通信,就能继续进行共识决策和事务执行,保证数据一致性。
状态报告:节点定期或在事件触发时向组内其他节点报告自己的状态,包括事务执行进度、健康状况等,以便其他节点了解整个组的全局状态

实验测试环境:

单主模式,主节点可读写,备节点只可读
![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传](https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=htt!%5B%E5%9C%A8%E8%BF%99%E9%87%8C%E6%8F%92%E5%85%A5%E5%9B%BE%E7%89%87%E6%8F%8F%E8%BF%B0%5D(https%3A%2F%2Fi-blog.csdnimg.cn%2Fdirect%2F739e2a9498a24bf7b7e99c61cd6fddd5.png&pos_id=img-WMbkb8LP-1724147356825)
ps://img-home.csdnimg.cn/images/20220524100510.png)
1.下载安装mysql9,主节点修改配置文件如下

[mysqld]
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
##MGR配置
server_id=1 #备节点依次为2,3
gtid_mode=ON
enforce_gtid_consistency=ON
plugin_load_add='group_replication.so'
group_replication_group_name="bc946766-0c46-11ef-a8e2-0242ac110002" 
group_replication_start_on_boot=off
group_replication_local_address= "172.20.0.1:33061" #备节点按备节点的ip修改
group_replication_group_seeds= "172.20.0.1:33061,172.20.0.2:33061,172.20.0.3:33061"
group_replication_bootstrap_group=off

2.初始化mysql,启动mysql

创建一个repl用户,并赋予replication slave 权限
在每个节点上执行
    SET SQL_LOG_BIN=0;
    CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED BY '$PASSWORD';
    GRANT REPLICATION SLAVE, CONNECTION_ADMIN, BACKUP_ADMIN ON *.* TO 'repl'@'%';
    GRANT GROUP_REPLICATION_STREAM ON *.* TO 'repl'@'%';
    FLUSH PRIVILEGES;
    SET SQL_LOG_BIN=1;   
    CHANGE REPLICATION SOURCE TO SOURCE_USER='repl',
    SOURCE_PASSWORD='$PASSWORD' FOR CHANNEL 'group_replication_recovery';

3.在3个节点安装MGR模块组件

root@opseye:[(none)]> install plugin group_replication soname 'group_replication.so';
Query OK, 0 rows affected (0.02 sec)
root@opseye:[(none)]> show plugins;

+----------------------------------+----------+--------------------+----------------------+---------+
| Name                             | Status   | Type               | Library              | License |
+----------------------------------+----------+--------------------+----------------------+---------+
| binlog                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| sha256_password                  | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| caching_sha2_password            | ACTIVE   | AUTHENTICATION     | NULL                 | GPL     |
| sha2_cache_cleaner               | ACTIVE   | AUDIT              | NULL                 | GPL     |
| daemon_keyring_proxy_plugin      | ACTIVE   | DAEMON             | NULL                 | GPL     |
| CSV                              | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MEMORY                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| InnoDB                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| INNODB_TRX                       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP                       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_RESET                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM                    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMPMEM_RESET              | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX             | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CMP_PER_INDEX_RESET       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_PAGE_LRU           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_BUFFER_POOL_STATS         | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TEMP_TABLE_INFO           | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_METRICS                   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DEFAULT_STOPWORD       | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_DELETED                | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_BEING_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_CONFIG                 | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_CACHE            | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_FT_INDEX_TABLE            | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TABLES                    | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TABLESTATS                | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_INDEXES                   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_TABLESPACES               | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_COLUMNS                   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_VIRTUAL                   | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_CACHED_INDEXES            | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| INNODB_SESSION_TEMP_TABLESPACES  | ACTIVE   | INFORMATION SCHEMA | NULL                 | GPL     |
| MyISAM                           | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| MRG_MYISAM                       | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| PERFORMANCE_SCHEMA               | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| TempTable                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| ARCHIVE                          | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| BLACKHOLE                        | ACTIVE   | STORAGE ENGINE     | NULL                 | GPL     |
| FEDERATED                        | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| ndbcluster                       | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| ndbinfo                          | DISABLED | STORAGE ENGINE     | NULL                 | GPL     |
| ndb_transid_mysql_connection_map | DISABLED | INFORMATION SCHEMA | NULL                 | GPL     |
| ngram                            | ACTIVE   | FTPARSER           | NULL                 | GPL     |
| mysqlx_cache_cleaner             | ACTIVE   | AUDIT              | NULL                 | GPL     |
| mysqlx                           | ACTIVE   | DAEMON             | NULL                 | GPL     |
| group_replication                | ACTIVE   | GROUP REPLICATION  | group_replication.so | GPL     |
+----------------------------------+----------+--------------------+----------------------+---------+
set persist group_replication_single_primary_mode=on; ##多主模式设置off,单主模式设置为on
CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
SET GLOBAL group_replication_bootstrap_group=ON;
start group_replication;
SET GLOBAL group_replication_bootstrap_group=OFF;

4.备节点执行如下命令

CHANGE MASTER TO MASTER_USER='repl', MASTER_PASSWORD='repl' FOR CHANNEL 'group_replication_recovery';
set persist group_replication_single_primary_mode=on;
START GROUP_REPLICATION;

5.在主节点查看MGR加入情况

[root@opseye scripts]# mysql -uroot -p"PASSWORD" -e "
      SELECT * FROM performance_schema.replication_group_members;"
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | e346e7e5-5a24-11ef-9764-0242ac14000b | ba660f83ad88 |        3306 | ONLINE       | PRIMARY     | 9.0.1          | XCom                       |
| group_replication_applier | e38f497b-5a24-11ef-977a-0242ac14000c | 26061266b3c6 |        3306 | ONLINE       | SECONDARY   | 9.0.1          | XCom                       |
| group_replication_applier | e3be9da0-5a24-11ef-96ff-0242ac14000d | f5c6138f30f3 |        3306 | ONLINE       | SECONDARY   | 9.0.1          | XCom                       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+

6.可自行测试主节点的数据同步和主机点损坏切换。

模拟主节点挂掉,查看集群情况。
[root@opseye scripts]#  mysql -uroot -p"123456" -e "
      SELECT * FROM performance_schema.replication_group_members;
    "
mysql: [Warning] Using a password on the command line interface can be insecure.
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST  | MEMBER_PORT | MEMBER_STATE | MEMBER_ROLE | MEMBER_VERSION | MEMBER_COMMUNICATION_STACK |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+
| group_replication_applier | e38f497b-5a24-11ef-977a-0242ac14000c | 26061266b3c6 |        3306 | ONLINE       | PRIMARY     | 9.0.1          | XCom                       |
| group_replication_applier | e3be9da0-5a24-11ef-96ff-0242ac14000d | f5c6138f30f3 |        3306 | ONLINE       | SECONDARY   | 9.0.1          | XCom                       |
+---------------------------+--------------------------------------+--------------+-------------+--------------+-------------+----------------+----------------------------+

结束语

在构建和维护数据库集群的过程中,无论是配置、监控、故障恢复,还是性能优化,都需要专业的知识和经验。为了帮助您在这一旅程中更加顺利,我们诚挚推荐专业的IT监控运维服务。
江苏立维成立于2015年,核心团队来自一线互联网企业,有着十多年丰富的运维管理经验,专注于企业业务故障的发现和管理,是国内早批专注于企业业务安全稳定运行服务保障的公司。

点击链接进入我们的官网,了解更多详情:https://www.live400.com/

<think>根据报错信息,存在两个问题:1.关于SSL的警告:提示MySQL服务器没有配置SSL,元数据可能以未加密方式传输。这个警告不会导致程序退出,但需要注意安全性。2.主要错误:无法写入配置文件,权限被拒绝。这是因为容器内的mysqlrouter进程没有权限写入挂载的宿主机目录。解决方案:1.对于SSL警告,可以忽略(在测试环境中)或者配置MySQL服务器启用SSL(生产环境)。2.对于权限问题,需要确保挂载的宿主机目录对容器内的用户可写。mysqlrouter容器默认以非root用户(mysqlrouter)运行,因此需要调整宿主机目录的权限。具体步骤:方法一:修改宿主机目录权限在宿主机上,将挂载目录(/use01/docker/mysqlrouter)的所有权改为UID为999的用户(mysqlrouter用户的UID在容器内通常是999): ```bashsudo chown -R999:999 /use01/docker/mysqlrouter```方法二:在容器内以root用户运行(不推荐,因为存在安全风险)在dockerrun命令中添加`--userroot`选项,让容器以root用户运行,这样就有权限写入任何目录。但是,这可能会导致安全问题,尤其是在生产环境中。方法三:使用Docker的命名卷(推荐)避免直接挂载宿主机目录,而是使用Docker卷,这样Docker会自动管理卷的权限。创建卷: ```bashdocker volumecreate mysqlrouter_config```然后挂载卷: ```bashdocker run--namemysql-router\--networkmysql-net\-vmysqlrouter_config:/etc/mysqlrouter\-e MYSQL_HOST=mysql-master \-e MYSQL_PORT=3306\-eMYSQL_USER=mgr_user \-e MYSQL_PASSWORD='admin' \mysql/mysql-router:8.0.32 \mysqlrouter \--bootstrapmgr_user:admin@mysql-master:3306\--conf-set-option=DEFAULT.name=router\--conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \--conf-set-option=routing:read_write.bind_port=6446\--conf-set-option=routing:read_only.bind_port=6447 \--conf-set-option=routing:read_write_split.bind_port=6450\--force```方法四:调整目录权限(如果必须使用宿主机目录)确保目录对容器内的用户可写。如果宿主机目录的权限是777,那么容器内的用户也可以写入。但要注意安全风险。 ```bashsudo chmod -R777 /use01/docker/mysqlrouter```但是,更安全的做法是只更改所有者为UID999(mysqlrouter用户): ```bashsudo chown999:999 /use01/docker/mysqlrouter```另外,如果宿主机目录不存在,需要先创建: ```bashsudo mkdir -p /use01/docker/mysqlroutersudo chown999:999 /use01/docker/mysqlrouter```下面我们采用方法一(修改宿主机目录权限)来运行命令。注意:如果之前已经运行过容器并生成了文件(可能由root创建),需要先清理目录,或者更改现有文件的权限。重新运行命令前,先清理目录(如果需要):```bashsudorm -rf /use01/docker/mysqlrouter/*```然后设置权限: ```bashsudo chown -R999:999 /use01/docker/mysqlrouter```再次运行dockerrun命令。如果问题仍然存在,可以尝试在容器启动时指定用户(使用`--user`参数):```bashdockerrun --name mysql-router \--network mysql-net \-v /use01/docker/mysqlrouter:/etc/mysqlrouter\-e MYSQL_HOST=mysql-master \-e MYSQL_PORT=3306\-eMYSQL_USER=mgr_user \-eMYSQL_PASSWORD='admin'\--user999\mysql/mysql-router:8.0.32 \mysqlrouter \--bootstrapmgr_user:admin@mysql-master:3306\--conf-set-option=DEFAULT.name=router\--conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \--conf-set-option=routing:read_write.bind_port=6446 \--conf-set-option=routing:read_only.bind_port=6447 \--conf-set-option=routing:read_write_split.bind_port=6450\--force```注意:以上命令中,我们显式指定了用户ID为999(即容器内的mysqlrouter用户)。如果使用DockerCompose,可以这样配置:```yamlversion:'3' services:mysql-router:image:mysql/mysql-router:8.0.32container_name:mysql-routerenvironment:MYSQL_HOST:mysql-masterMYSQL_PORT:3306MYSQL_USER:mgr_userMYSQL_PASSWORD: admincommand:-mysqlrouter- --bootstrap- "$${MYSQL_USER}:$${MYSQL_PASSWORD}@$${MYSQL_HOST}:$${MYSQL_PORT}"- --conf-set-option=DEFAULT.name=router---conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306---conf-set-option=routing:read_write.bind_port=6446---conf-set-option=routing:read_only.bind_port=6447---conf-set-option=routing:read_write_split.bind_port=6450- --forcevolumes:- /use01/docker/mysqlrouter:/etc/mysqlrouteruser: "999"networks:- mysql-netnetworks:mysql-net:external:true```关于SSL警告,如果不需要加密,可以忽略。如果需要加密,则需要在MySQL服务器上配置SSL,并在bootstrap时指定ssl-mode,例如:```bash--bootstrap"mgr_user:admin@mysql-master:3306?ssl-mode=REQUIRED" ```但是,由于报错显示MySQL服务器没有配置SSL,因此必须先配置MySQL服务器的SSL。这超出了当前问题的范围。现在,我们主要解决权限问题。</think>### 解决 MySQL Router 权限和配置写入问题 您遇到的两个关键问题: 1. SSL 警告:`WARNING: The MySQL server does not have SSL configured...` 2. 权限错误:`Error: Could not open /etc/mysqlrouter/mysqlrouter.conf.tmp for writing: Permission denied` 以下是完整的解决方案: #### 问题分析: 1. **SSL 警告**:MySQL 服务器未启用 SSL 加密,Router 会以明文传输元数据 2. **权限问题**:容器内的 mysqlrouter 用户(UID 999)没有写入挂载目录的权限 3. **潜在问题**:SELinux 或 AppArmor 可能限制容器访问宿主机文件系统 #### 解决方案: ##### 1. 解决配置文件写入权限问题 ```bash # 在宿主机上创建目录并设置正确权限 sudo mkdir -p /use01/docker/mysqlrouter sudo chown -R 999:999 /use01/docker/mysqlrouter # mysqlrouter 用户 UID 通常是 999 sudo chmod -R 755 /use01/docker/mysqlrouter # 添加 :Z 标志处理 SELinux 上下文 docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter:Z \ # 关键修改:添加 :Z 标志 -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap mgr_user:admin@mysql-master:3306 \ --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` **关键修改:** - 添加 `:Z` 标志到卷挂载参数,处理 SELinux 上下文 - 确保目录所有权设置为 UID 999(mysqlrouter 用户) ##### 2. 使用临时容器引导配置 ```bash # 使用临时容器生成配置 docker run --rm \ --name mysql-router-temp \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter:Z \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap mgr_user:admin@mysql-master:3306 \ --directory /tmp/mysqlrouter-config \ # 在容器内生成配置 --force # 将生成的配置复制到挂载目录 docker cp mysql-router-temp:/tmp/mysqlrouter-config/. /use01/docker/mysqlrouter # 运行正式容器 docker run -d --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter:Z \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ -p 6446:6446 -p 6447:6447 -p 6450:6450 \ mysql/mysql-router:8.0.32 ``` ##### 3. 完全避免挂载问题(使用 Docker 卷) ```bash # 创建 Docker 卷 docker volume create mysqlrouter-config # 使用卷运行 docker run --name mysql-router \ --network mysql-net \ -v mysqlrouter-config:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap mgr_user:admin@mysql-master:3306 \ --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force # 检查生成的配置文件 docker run --rm -it \ -v mysqlrouter-config:/etc/mysqlrouter \ alpine ls -l /etc/mysqlrouter ``` ##### 4. 解决 SSL 警告(两种方法) **方法1:在 MySQL Router 中禁用 SSL 验证(仅测试环境)** ```bash docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter:Z \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap "mgr_user:admin@mysql-master:3306?ssl-mode=DISABLED" \ # 禁用 SSL --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` **方法2:在 MySQL 服务器启用 SSL(生产环境推荐)** ```bash # 在 MySQL 服务器容器中启用 SSL docker run --name mysql-master \ -e MYSQL_ROOT_PASSWORD=rootpass \ -e MYSQL_SSL_CERT=/etc/mysql/ssl/server-cert.pem \ -e MYSQL_SSL_KEY=/etc/mysql/ssl/server-key.pem \ -e MYSQL_SSL_CA=/etc/mysql/ssl/ca.pem \ -v ./mysql-ssl:/etc/mysql/ssl \ mysql:8.0 \ --ssl-ca=/etc/mysql/ssl/ca.pem \ --ssl-cert=/etc/mysql/ssl/server-cert.pem \ --ssl-key=/etc/mysql/ssl/server-key.pem # 然后使用 SSL 连接 docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter:Z \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ mysql/mysql-router:8.0.32 \ mysqlrouter \ --bootstrap "mgr_user:admin@mysql-master:3306?ssl-mode=REQUIRED" \ # 要求 SSL --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` #### 完整的 Docker Compose 解决方案 ```yaml version: '3.8' services: mysql-master: image: mysql:8.0 container_name: mysql-master environment: MYSQL_ROOT_PASSWORD: rootpassword MYSQL_USER: mgr_user MYSQL_PASSWORD: admin volumes: - mysql_data:/var/lib/mysql - ./mysql-ssl:/etc/mysql/ssl # SSL 证书目录 command: - --server-id=1 - --log-bin - --ssl-ca=/etc/mysql/ssl/ca.pem - --ssl-cert=/etc/mysql/ssl/server-cert.pem - --ssl-key=/etc/mysql/ssl/server-key.pem networks: - mysql-net mysql-router: image: mysql/mysql-router:8.0.32 container_name: mysql-router depends_on: - mysql-master environment: MYSQL_HOST: mysql-master MYSQL_PORT: 3306 MYSQL_USER: mgr_user MYSQL_PASSWORD: admin volumes: - mysqlrouter_config:/etc/mysqlrouter command: - mysqlrouter - --bootstrap - "$${MYSQL_USER}:$${MYSQL_PASSWORD}@$${MYSQL_HOST}:$${MYSQL_PORT}?ssl-mode=REQUIRED" - --conf-set-option=DEFAULT.name=router - --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306 - --conf-set-option=routing:read_write.bind_port=6446 - --conf-set-option=routing:read_only.bind_port=6447 - --conf-set-option=routing:read_write_split.bind_port=6450 - --force ports: - "6446:6446" - "6447:6447" - "6450:6450" networks: - mysql-net volumes: mysql_data: mysqlrouter_config: networks: mysql-net: driver: bridge ``` #### 权限诊断脚本 ```bash #!/bin/bash # diagnose_router_permissions.sh # 检查宿主机目录权限 echo "=== 宿主机目录权限 ===" ls -ld /use01/docker/mysqlrouter stat -c "%U %G" /use01/docker/mysqlrouter # 检查容器内用户 echo -e "\n=== 容器用户信息 ===" docker run --rm mysql/mysql-router:8.0.32 id # 检查 SELinux 状态 echo -e "\n=== SELinux 状态 ===" sestatus # 测试文件创建能力 echo -e "\n=== 文件创建测试 ===" docker run --rm -v /use01/docker/mysqlrouter:/test:Z \ mysql/mysql-router:8.0.32 \ bash -c "touch /test/testfile && ls -l /test/testfile && rm /test/testfile" # 检查 AppArmor 配置 echo -e "\n=== AppArmor 配置 ===" if [ -f /etc/apparmor.d/docker ]; then grep -A 10 "profile docker-default" /etc/apparmor.d/docker fi ``` #### 高级解决方案:自定义 Dockerfile ```dockerfile # 自定义 MySQL Router 镜像 FROM mysql/mysql-router:8.0.32 # 创建具有写入权限的用户 RUN groupadd -g 1001 routergroup && \ useradd -u 1001 -g routergroup routeruser && \ mkdir -p /etc/mysqlrouter && \ chown routeruser:routergroup /etc/mysqlrouter # 以自定义用户运行 USER routeruser # 设置入口点 ENTRYPOINT ["mysqlrouter"] ``` 构建和使用: ```bash # 构建镜像 docker build -t custom-mysql-router . # 运行自定义镜像 docker run --name mysql-router \ --network mysql-net \ -v /use01/docker/mysqlrouter:/etc/mysqlrouter \ -e MYSQL_HOST=mysql-master \ -e MYSQL_PORT=3306 \ -e MYSQL_USER=mgr_user \ -e MYSQL_PASSWORD='admin' \ custom-mysql-router \ --bootstrap mgr_user:admin@mysql-master:3306 \ --conf-set-option=DEFAULT.name=router \ --conf-set-option=metadata_cache:Cluster01.bootstrap_server_addresses=mysql-master:3306,mysql-slave1:3306,mysql-slave2:3306 \ --conf-set-option=routing:read_write.bind_port=6446 \ --conf-set-option=routing:read_only.bind_port=6447 \ --conf-set-option=routing:read_write_split.bind_port=6450 \ --force ``` #### 验证和监控 ```bash # 检查容器日志 docker logs mysql-router # 检查配置文件 docker exec mysql-router cat /etc/mysqlrouter/mysqlrouter.conf # 测试路由连接 mysql -h 127.0.0.1 -P 6446 -u mgr_user -padmin -e "SELECT @@server_id" # 监控路由器状态 docker exec mysql-router mysqlrouter --user=mysqlrouter status ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值