网络命名空间是主机系统网络堆栈的逻辑副本。网络命名空间对于设置容器或虚拟环境很有用。每个命名空间都有自己的 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
之前评估运行具有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
选项,则复制连接使用默认(全局)命名空间。
以下示例设置了在全局、red
和 blue
命名空间中监听连接的 MySQL 服务器,并显示了如何配置从 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 地址的值。您也可以尝试调用 mysql 而不使用
--network-namespace
选项,以查看连接尝试是否成功,以及如果成功,USER()
值如何受到影响。
出于复制监控目的,以下信息源有一个列显示连接适用的网络命名空间
Performance Schema
replication_connection_configuration
表。请参阅 第 29.12.11.1 节,“replication_connection_configuration 表”。副本服务器连接元数据存储库。请参阅 第 19.2.4.2 节,“复制元数据存储库”。