### 5.1.14网络名称空间支持

[](<>)[](<>)

网络名称空间是来自主机系统的网络堆栈的逻辑副本。网络名称空间对于设置容器或虚拟环境很有用。每个名称空间都有自己的IP地址、网络接口、路由表等等。默认名称空间或全局名称空间是主机系统物理接口所在的名称空间。

当MySQL连接跨越名称空间时，特定于名称空间的地址空间可能会导致问题。例如，在容器或虚拟网络中运行的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 |
+--------------------+
```

在这种情况下，预期[`用户（）`](information-functions.html#function_user)价值是`admin@203.0.113.10`。如果发起连接的地址与显示的地址不同，则此类行为可能会导致难以正确分配帐户权限。

为了解决这个问题，MySQL允许指定用于TCP/IP连接的网络名称空间，以便连接的两个端点都使用约定的公共地址空间。

MySQL 8.0.22及更高版本在实现它们的平台上支持网络名称空间。MySQL中的支持适用于：

-   MySQL服务器，[**mysqld**](mysqld.html).

-   X插件。

-   这个[**mysql**](mysql.html)客户和客户**mysqlxtest**测试套件客户端。（不支持其他客户端。必须从要连接到的服务器的网络命名空间中调用它们。）

-   定期复制。

-   组复制，仅当使用MySQL通信堆栈建立组通信连接时（来自MySQL 8.0.27）。

    以下部分介绍如何在MySQL中使用网络名称空间：

-   [主机系统先决条件](network-namespace-support.html#network-namespaces-host-prerequisites)

-   [MySQL配置](network-namespace-support.html#network-namespaces-mysql-configuration)

-   [网络名称空间监视](network-namespace-support.html#network-namespaces-monitoring)

#### 主机系统先决条件

在MySQL中使用网络名称空间支持之前，必须满足以下主机系统先决条件：

-   主机操作系统必须支持网络名称空间。（例如，Linux。）

-   MySQL使用的任何网络名称空间都必须首先在主机系统上创建。

-   系统管理员必须配置主机名解析以支持网络名称空间。

    笔记

    已知的一个限制是，在MySQL中，主机名解析不适用于特定于网络命名空间的主机文件中指定的名称。例如，如果`红色`命名空间是在`/etc/netns/red/hosts`文件，绑定到名称在服务器端和客户端都失败。解决方法是使用IP地址而不是主机名。

-   系统管理员必须启用`CAP_系统管理`支持网络名称空间的MySQL二进制文件的操作系统权限([**mysqld**](mysqld.html), [**mysql**](mysql.html), **mysqlxtest**).

    重要的

    有可能`CAP_系统管理`是一个安全敏感的操作，因为它使进程能够执行除设置名称空间之外的其他特权操作。有关其效果的描述，请参见<https://man7.org/linux/man-pages/man7/capabilities.7.html>.

    因为`CAP_系统管理`必须由系统管理员显式启用，默认情况下，MySQL二进制文件没有启用网络命名空间支持。系统管理员应该评估使用`CAP_系统管理`在启用它之前。

    以下示例中的说明将设置名为`红色`和`蓝色`。您选择的名称可能不同，主机系统上的网络地址和接口也可能不同。

    调用此处显示的命令作为`根`操作系统用户，或在每个命令前面加上**苏多**.例如，调用**知识产权**或**集帽**如果你不在，就命令他`根`使用**叶秀多**或**sudo setcap**.

    要配置网络名称空间，请使用**知识产权**命令对于某些操作**知识产权**命令必须在特定名称空间（必须已经存在）内执行。在这种情况下，按如下方式开始命令：


```
ip netns exec namespace_name
```

例如，此命令在`红色`用于启动环回接口的命名空间：

```
ip netns exec red ip link set lo up
```

添加名为`红色`和`蓝色`，每个都有自己的虚拟以太网设备，用作名称空间和自己的环回接口之间的链接：

```
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
```

移除`红色`和`蓝色`链接和名称空间：

```
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_系统管理`能力。下面**集帽**命令假定您已将位置更改为包含MySQL二进制文件的目录（根据需要调整系统的路径名）：

```
cd /usr/local/mysql/bin
```

同意`CAP_系统管理`适当二进制文件的功能：

```
setcap cap_sys_admin+ep ./mysqld
setcap cap_sys_admin+ep ./mysql
setcap cap_sys_admin+ep ./mysqlxtest
```

查证`CAP_系统管理`能力：

```
$> getcap ./mysqld ./mysql ./mysqlxtest
./mysqld = cap_sys_admin+ep
./mysql = cap_sys_admin+ep
./mysqlxtest = cap_sys_admin+ep
```

除去`CAP_系统管理`能力：

```
setcap -r ./mysqld
setcap -r ./mysql
setcap -r ./mysqlxtest
```

重要的

如果重新安装以前应用过的二进制文件**集帽**，你必须使用**集帽**再一次例如，如果执行就地MySQL升级，则无法授予`CAP_系统管理`功能再次导致与命名空间相关的故障。服务器尝试绑定到具有命名命名空间的地址时失败，并出现以下错误：

```
[ERROR] [MY-013408] [Server] setns() failed with error 'Operation not permitted'
```

使用[`--网络名称空间`](mysql-command-options.html#option_mysql_network-namespace)选项失败如下：

```
ERROR: Network namespace error: Operation not permitted
```

#### MySQL配置

假设满足了前面的主机系统先决条件，MySQL支持为连接的侦听（入站）端配置服务器端命名空间，并为连接的出站端配置客户端命名空间。

在服务器端[`绑定地址`](server-system-variables.html#sysvar_bind_address), [`管理员地址`](server-system-variables.html#sysvar_admin_address)和[`mysqlx_bind_地址`](x-plugin-options-system-variables.html#sysvar_mysqlx_bind_address)系统变量具有扩展语法，用于指定用于侦听传入连接的给定IP地址或主机名的网络名称空间。要为地址指定名称空间，请添加斜杠和名称空间名称。例如，服务器`我的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`*.

-   主机系统必须支持网络名称空间，并且每个命名名称空间必须之前已设置。命名不存在的命名空间会产生错误。

-   [`绑定地址`](server-system-variables.html#sysvar_bind_address)和（从MySQL 8.0.21开始）[`mysqlx_bind_地址`](x-plugin-options-system-variables.html#sysvar_mysqlx_bind_address)接受多个逗号分隔地址的列表，变量值可以指定全局命名空间、命名命名空间或混合命名空间中的地址。

    如果在尝试使用命名空间的服务器启动期间发生错误，则服务器不会启动。如果X Plugin在插件初始化过程中出现错误，导致其无法绑定到任何地址，则该插件的初始化序列将失败，服务器也不会加载该插件。

    在客户端，可以在以下上下文中指定网络名称空间：

-   对于[**mysql**](mysql.html)客户和客户**mysqlxtest**测试套件客户端，使用[`--网络名称空间`](mysql-command-options.html#option_mysql_network-namespace)选项例如：

    ```
    mysql --host=192.0.2.2 --network-namespace=red
    ```

    如果[`--网络名称空间`](mysql-command-options.html#option_mysql_network-namespace)选项，则连接使用默认（全局）命名空间。

-   对于从副本服务器到源服务器的复制连接，请使用[`将复制源更改为`](change-replication-source-to.html)语句（来自MySQL 8.0.23）或[`将主机更改为`](change-master-to.html)语句（MySQL 8.0.23之前）并指定`网络名称空间`选项例如：

    ```
    CHANGE REPLICATION SOURCE TO
      SOURCE_HOST = '192.0.2.2',
      NETWORK_NAMESPACE = 'red';
    ```

    如果`网络名称空间`选项，复制连接使用默认（全局）命名空间。

    下面的示例设置了一个MySQL服务器，用于侦听全局数据库中的连接，`红色`和`蓝色`名称空间，并显示如何配置从`红色`和`蓝色`名称空间。假设`红色`和`蓝色`已创建名称空间，如中所示[主机系统先决条件](network-namespace-support.html#network-namespaces-host-prerequisites).

1.  将服务器配置为侦听多个名称空间中的地址。把这些线放到服务器上`我的cnf`文件并启动服务器：

    ```
    [mysqld]
    bind_address = 127.0.1.1,192.0.2.2/red,198.51.100.2/blue
    ```

    该值告诉服务器监听环回地址`127.0.0.1`在全局命名空间中，地址`192.0.2.2`在`红色`名称空间和地址`198.51.100.2`在`蓝色`名称空间。

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';
    ```

3.  验证是否可以连接到每个命名命名空间中的服务器：

    ```
    $> 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 |
    +------------------------+
    ```

    笔记

    你可能会从中看到不同的结果[`用户（）`](information-functions.html#function_user)，如果您的DNS配置为能够将地址解析为相应的主机名，并且服务器未使用[`跳过\u名称\u解析`](server-system-variables.html#sysvar_skip_name_resolve)系统变量已启用。

    您也可以尝试调用[**mysql**](mysql.html)没有[`--网络名称空间`](mysql-command-options.html#option_mysql_network-namespace)选项，以查看连接尝试是否成功，如果成功，连接将如何进行[`用户（）`](information-functions.html#function_user)价值受到影响。

#### 网络名称空间监视

出于复制监视的目的，这些信息源有一列显示适用于连接的网络命名空间：

-   性能模式`复制\连接\配置`桌子看见[第27.12.11.1节，“复制\_联系\_“配置表”](performance-schema-replication-connection-configuration-table.html).

-   副本服务器连接元数据存储库。看见[第17.2.4.2节，“复制元数据存储库”](replica-logs-status.html).

-   这个[`显示副本状态`](show-replica-status.html)（或MySQL 8.0.22之前的版本，[`显示奴隶身份`](show-slave-status.html))声明。看见[第13.7.7.35节，“显示副本状态声明”](show-replica-status.html).
