网络命名空间是主机系统网络堆栈的逻辑副本。网络命名空间对于设置容器或虚拟环境非常有用。每个命名空间都有自己的 IP 地址、网络接口、路由表等。默认或全局命名空间是主机系统物理接口所在的命名空间。
当 MySQL 连接跨越命名空间时,特定于命名空间的地址空间会导致问题。例如,在容器或虚拟网络中运行的 MySQL 实例的网络地址空间可能与主机地址空间不同。这可能会导致某些现象,例如,来自一个命名空间中地址的客户端连接对于 MySQL 服务器而言,似乎来自不同的地址,即使客户端和服务器在同一台机器上运行也是如此。假设这两个进程都在 IP 地址为 203.0.113.10
的主机上运行,但使用不同的命名空间。连接可能会产生如下结果
$> mysql --user=admin --host=203.0.113.10 --protocol=tcp
mysql> SELECT USER();
+--------------------+
| USER() |
+--------------------+
| [email protected] |
+--------------------+
在这种情况下,预期的 USER()
值为 [email protected]
。如果连接来源的地址与其显示的地址不符,则此类行为可能会导致难以正确分配帐户权限。
为了解决此问题,MySQL 允许指定用于 TCP/IP 连接的网络命名空间,以便连接的两端使用约定的通用地址空间。
MySQL 支持在实现网络命名空间的平台上使用它们。MySQL 中的支持适用于
以下部分介绍如何在 MySQL 中使用网络命名空间
在 MySQL 中使用网络命名空间支持之前,必须满足以下主机系统先决条件
主机操作系统必须支持网络命名空间。(例如,Linux。)
MySQL 要使用的任何网络命名空间都必须先在主机系统上创建。
系统管理员必须配置主机名解析以支持网络命名空间。
注意一个已知的限制是,在 MySQL 中,主机名解析不适用于网络命名空间特定主机文件中指定的主机名。例如,如果
red
命名空间中的主机名地址在/etc/netns/red/hosts
文件中指定,则在服务器端和客户端都无法绑定到该名称。解决方法是使用 IP 地址而不是主机名。系统管理员必须为支持网络命名空间的 MySQL 二进制文件(mysqld、mysql、mysqlxtest)启用
CAP_SYS_ADMIN
操作系统权限。重要启用
CAP_SYS_ADMIN
是一项安全敏感的操作,因为它允许进程除了设置命名空间之外,还可以执行其他特权操作。有关其效果的说明,请参见 https://man7.org/linux/man-pages/man7/capabilities.7.html。因为
CAP_SYS_ADMIN
必须由系统管理员显式启用,所以默认情况下,MySQL 二进制文件没有启用网络命名空间支持。系统管理员应在启用CAP_SYS_ADMIN
之前评估使用其运行 MySQL 进程的安全隐患。
以下示例中的说明设置了名为 red
和 blue
的网络命名空间。您选择的名称可能有所不同,主机系统上的网络地址和接口也可能有所不同。
在此处显示的命令可以使用 root
操作系统用户身份调用,也可以在每个命令前加上前缀 sudo 来调用。例如,如果您不是 root
用户,要调用 ip 或 setcap 命令,请使用 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
系统变量具有扩展语法,用于指定要用于侦听传入连接的给定 IP 地址或主机名的网络命名空间。要为地址指定命名空间,请添加斜杠和命名空间名称。例如,服务器 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() | +--------------------+ | [email protected] | +--------------------+
$> mysql -u blue_user -h 198.51.100.2 --network-namespace=blue -p Enter password: blue_user_password mysql> SELECT USER(); +------------------------+ | USER() | +------------------------+ | [email protected] | +------------------------+
注意您可能会看到
USER()
的不同结果,如果您的 DNS 配置为能够将地址解析为相应的主机名,并且服务器未在启用skip_name_resolve
系统变量的情况下运行,则该函数可以返回包含主机名而不是 IP 地址的值。您也可以尝试在不使用
--network-namespace
选项的情况下调用 mysql,以查看连接尝试是否成功,以及如果成功,USER()
值如何受到影响。
出于复制监控目的,以下信息源具有一列,用于显示连接适用的网络命名空间
Performance Schema
replication_connection_configuration
表。请参阅 第 29.12.11.1 节“replication_connection_configuration 表”。副本服务器连接元数据存储库。请参阅 第 19.2.4.2 节“复制元数据存储库”。