网络命名空间是一个逻辑副本的网络栈来自主机系统。网络命名空间对于设置容器或虚拟环境非常有用。每个命名空间都有其自己的IP地址、网络接口、路由表等。默认或全局命名空间是主机系统物理接口所在的那个。
命名空间特定的地址空间可能会导致问题,当MySQL连接跨越命名空间时。例如,MySQL实例在容器或虚拟网络中的网络地址空间可能与主机机器的地址空间不同。这可能会产生奇怪的现象,例如客户端连接来自一个命名空间的地址,而服务器认为来自不同的地址,即使客户端和服务器运行在同一台机器上。假设这两个进程都在IP地址为203.0.113.10
的主机上,但使用不同的命名空间。连接可能会产生这样的结果:
$> mysql --user=admin --host=203.0.113.10 --protocol=tcp
mysql> SELECT USER();
+--------------------+
| USER() |
+--------------------+
| admin@198.51.100.2 |
+--------------------+
在这种情况下,预期的USER()
值是admin@203.0.113.10
。这种行为可能会使得账户权限的分配变得困难,因为连接的来源地址可能不是它所显示的那样。
为了解决这个问题,MySQL启用了指定网络命名空间来使用TCP/IP连接,以便连接的两个端点使用共同的地址空间。
MySQL支持在实现命名空间的平台上。MySQL中的支持适用于:
-
MySQL服务器,mysqld。
-
X插件。
-
mysql客户端和mysqlxtest测试套件客户端。(其他客户端不支持。它们必须从服务器的网络命名空间中调用,以便连接到服务器。)
-
常规复制。
-
组复制,只有在使用MySQL通信栈来建立组通信连接时。
以下部分描述了如何在MySQL中使用网络命名空间:
在使用MySQL中的网络命名空间支持之前,主机系统必须满足以下先决条件:
-
主机操作系统必须支持网络命名空间。(例如,Linux。)
-
任何要由MySQL使用的网络命名空间必须首先在主机系统上创建。
-
主机名解析必须由系统管理员配置以支持网络命名空间。
Note一个已知的限制是,在MySQL中,主机名解析不适用于网络命名空间特定的主机文件中指定的名称。例如,如果在
red
命名空间中的主机名的地址在/etc/netns/red/hosts
文件中指定,绑定到名称将在服务器和客户端两侧失败。解决方法是使用IP地址而不是主机名。 -
系统管理员必须为支持网络命名空间的MySQL二进制文件(mysqld、mysql、mysqlxtest)启用
CAP_SYS_ADMIN
操作系统特权。Important启用
CAP_SYS_ADMIN
是一个安全敏感的操作,因为它启用了进程执行其他特权操作的能力,除了设置命名空间外。有关其效果的描述,请参阅https://man7.org/linux/man-pages/man7/capabilities.7.html。因为
CAP_SYS_ADMIN
必须由系统管理员明确启用,MySQL二进制文件默认情况下不启用网络命名空间支持。系统管理员应该在启用之前评估启用CAP_SYS_ADMIN
的安全隐患。
以下示例中的指令设置了名为 red
和 blue
的网络命名空间。您选择的名称可能不同,也可能是主机系统上的网络地址和接口。
以 root
操作系统用户身份或在每个命令前添加 sudo 前缀来调用以下命令。例如,要调用 ip 或 setcap 命令,如果您不是 root
,请使用 sudo ip 或 sudo setcap。
使用 ip 命令来配置网络命名空间。在某些操作中,ip 命令必须在特定命名空间中执行(该命名空间必须已经存在)。在这种情况下,命令以以下方式开始:
ip netns exec namespace_name
例如,以下命令在 red
命名空间中执行,以便启动回环接口:
ip netns exec red ip link set lo up
要添加名为 red
和 blue
的命名空间,每个命名空间都有其自己的虚拟以太网设备,用于命名空间之间的链接和自己的回环接口:
ip netns add red
ip link add veth-red type veth peer name vpeer-red
ip link set vpeer-red netns red
ip addr add 192.0.2.1/24 dev veth-red
ip link set veth-red up
ip netns exec red ip addr add 192.0.2.2/24 dev vpeer-red
ip netns exec red ip link set vpeer-red up
ip netns exec red ip link set lo up
ip netns add blue
ip link add veth-blue type veth peer name vpeer-blue
ip link set vpeer-blue netns blue
ip addr add 198.51.100.1/24 dev veth-blue
ip link set veth-blue up
ip netns exec blue ip addr add 198.51.100.2/24 dev vpeer-blue
ip netns exec blue ip link set vpeer-blue up
ip netns exec blue ip link set lo up
# if you want to enable inter-subnet routing...
sysctl net.ipv4.ip_forward=1
ip netns exec red ip route add default via 192.0.2.1
ip netns exec blue ip route add default via 198.51.100.1
命名空间之间的链接图如下所示:
red global blue
192.0.2.2 <=> 192.0.2.1
(vpeer-red) (veth-red)
198.51.100.1 <=> 198.51.100.2
(veth-blue) (vpeer-blue)
要检查哪些命名空间和链接存在:
ip netns list
ip link list
要查看全局和命名命名空间的路由表:
ip route show
ip netns exec red ip route show
ip netns exec blue ip route show
要删除 red
和 blue
链接和命名空间:
ip link del veth-red
ip link del veth-blue
ip netns del red
ip netns del blue
sysctl net.ipv4.ip_forward=0
因此,包括网络命名空间支持的 MySQL 二进制文件才能实际使用命名空间,您必须授予它们 CAP_SYS_ADMIN
能力。以下 setcap 命令假设您已经更改了目录以包含 MySQL 二进制文件(根据系统的需要调整路径名):
cd /usr/local/mysql/bin
要授予 CAP_SYS_ADMIN
能力适当的二进制文件:
setcap cap_sys_admin+ep ./mysqld
setcap cap_sys_admin+ep ./mysql
setcap cap_sys_admin+ep ./mysqlxtest
要检查 CAP_SYS_ADMIN
能力:
$> getcap ./mysqld ./mysql ./mysqlxtest
./mysqld = cap_sys_admin+ep
./mysql = cap_sys_admin+ep
./mysqlxtest = cap_sys_admin+ep
要删除 CAP_SYS_ADMIN
能力:
setcap -r ./mysqld
setcap -r ./mysql
setcap -r ./mysqlxtest
如果您重新安装了之前应用了 setcap 的二进制文件,您必须再次使用 setcap。例如,如果您执行了就地 MySQL 升级,未能再次授予 CAP_SYS_ADMIN
能力将导致命名空间相关的失败。服务器将以以下错误失败尝试绑定到具有命名命名空间的地址:
[ERROR] [MY-013408] [Server] setns() failed with error 'Operation not permitted'
使用 --network-namespace
选项调用的客户端将失败如下:
ERROR: Network namespace error: Operation not permitted
假设已经满足了主机系统的先决条件,MySQL 启用了配置服务器端命名空间以侦听(入站)连接的侧面和客户端命名空间以侦听(出站)连接的侧面。
在服务器端,bind_address
、admin_address
和 mysqlx_bind_address
系统变量具有扩展语法,以指定用于侦听入站连接的网络命名空间。要指定命名空间,请在地址或主机名后添加斜杠和命名空间名称。例如,服务器 my.cnf
文件可能包含以下行:
[mysqld]
bind_address = 127.0.1.1,192.0.2.2/red,198.51.100.2/blue
admin_address = 102.0.2.2/red
mysqlx_bind_address = 102.0.2.2/red
以下规则适用:
-
可以为 IP 地址或主机名指定网络命名空间。
-
不能为通配符 IP 地址指定网络命名空间。
-
对于给定的地址,网络命名空间是可选的。如果给定,必须作为
/
后缀紧跟在地址后面。ns
-
没有
/
后缀的地址使用主机系统的全局命名空间。因此,全局命名空间是默认的。ns
-
具有
/
后缀的地址使用名为ns
ns
的命名空间。 -
主机系统必须支持网络命名空间,每个命名命名空间必须事先设置。命名不存在的命名空间将产生错误。
-
bind_address
和mysqlx_bind_address
接受多个以逗号分隔的地址列表,变量值可以指定全局命名空间、命名命名空间或混合命名空间中的地址。
如果在服务器启动期间出现错误,以致无法使用命名空间,服务器将不会启动。如果在X Plugin初始化期间出现错误,以致无法绑定到任何地址,插件将失败其初始化序列,服务器将不会加载它。
在客户端,可以在以下上下文中指定网络命名空间:
-
对于 mysql 客户端和 mysqlxtest 测试套件客户端,使用
--network-namespace
选项。例如:mysql --host=192.0.2.2 --network-namespace=red
如果省略
--network-namespace
选项,连接将使用默认(全局)命名空间。 -
对于从副本服务器到源服务器的复制连接,使用
CHANGE REPLICATION SOURCE TO
语句,并指定NETWORK_NAMESPACE
选项。例如:CHANGE REPLICATION SOURCE TO SOURCE_HOST = '192.0.2.2', NETWORK_NAMESPACE = 'red';
如果省略
NETWORK_NAMESPACE
选项,复制连接将使用默认(全局)命名空间。
以下示例设置了一个 MySQL 服务器,该服务器在全局、red
和 blue
命名空间中监听连接,并显示如何配置从 red
和 blue
命名空间连接的账户。假设 red
和 blue
命名空间已经按照 主机系统先决条件 创建。
-
配置服务器以在多个命名空间中监听地址。将这些行添加到服务器的
my.cnf
文件中,然后启动服务器:[mysqld] bind_address = 127.0.1.1,192.0.2.2/red,198.51.100.2/blue
该值告诉服务器在全局命名空间中的回环地址
127.0.0.1
上监听,在red
命名空间中的地址192.0.2.2
上监听,在blue
命名空间中的地址198.51.100.2
上监听。 -
连接到服务器的全局命名空间,并创建具有从每个命名命名空间的地址空间连接权限的账户:
$> mysql -u root -h 127.0.0.1 -p Enter password: root_password mysql> CREATE USER 'red_user'@'192.0.2.2' IDENTIFIED BY 'red_user_password'; mysql> CREATE USER 'blue_user'@'198.51.100.2' IDENTIFIED BY 'blue_user_password';
-
验证您可以连接到每个命名命名空间的服务器:
$> mysql -u red_user -h 192.0.2.2 --network-namespace=red -p Enter password: red_user_password mysql> SELECT USER(); +--------------------+ | USER() | +--------------------+ | red_user@192.0.2.2 | +--------------------+
$> mysql -u blue_user -h 198.51.100.2 --network-namespace=blue -p Enter password: blue_user_password mysql> SELECT USER(); +------------------------+ | USER() | +------------------------+ | blue_user@198.51.100.2 | +------------------------+
Note您可能会看到来自
USER()
的不同结果,该函数可以返回一个包含主机名而不是 IP 地址的值,如果您的 DNS 配置可以将地址解析为对应的主机名,并且服务器未启用skip_name_resolve
系统变量。您也可以尝试不带
--network-namespace
选项的 mysql,以查看连接尝试是否成功,以及USER()
值如何受到影响。
对于复制监控目的,这些信息源具有一个显示适用网络命名空间的列:
-
性能架构
replication_connection_configuration
表。见 第 29.12.11.1 节,“The replication_connection_configuration 表”。 -
副本服务器连接元数据存储库。见 第 19.2.4.2 节,“复制元数据存储库”。