丑帅大聪愚 發表於 2020-9-3 10:47:00

Docker 网络模式详解及容器间网络通信

<p>  当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,如 Docker 的镜像管理。然而,Docker 同样有着很多不完善的地方,网络方面就是 Docker 比较薄弱的部分。因此,我们有必要深入了解 Docker 的网络知识,以满足更高的网络需求。</p>
<p>  </p>
<h2 id="默认网络">默认网络</h2>
<p>  </p>
<p>  安装 Docker 以后,会默认创建三种网络,可以通过 <code>docker network ls</code> 查看。</p>
<pre><code class="language-shell"># docker network ls
NETWORK ID          NAME                DRIVER            SCOPE
688d1970f72e      bridge            bridge            local
885da101da7d      host                host                local
f4f1b3cf1b7f      none                null                local
</code></pre>
<p>  </p>
<p>  在学习 Docker 网络之前,我们有必要先来了解一下这几种网络模式都是什么意思。</p>
<table>
<thead>
<tr>
<th>网络模式</th>
<th>简介</th>
</tr>
</thead>
<tbody>
<tr>
<td>bridge</td>
<td>为每一个容器分配、设置 IP 等,并将容器连接到一个 <code>docker0</code> 虚拟网桥,默认为该模式。</td>
</tr>
<tr>
<td>host</td>
<td>容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。</td>
</tr>
<tr>
<td>none</td>
<td>容器有独立的 Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,IP 等。</td>
</tr>
<tr>
<td>container</td>
<td>新创建的容器不会创建自己的网卡和配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。</td>
</tr>
</tbody>
</table>
<p>  </p>
<h3 id="bridge-网络模式">bridge 网络模式</h3>
<p>  </p>
<p>  在该模式中,Docker 守护进程创建了一个虚拟以太网桥 <code>docker0</code>,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。</p>
<p>  默认情况下,守护进程会创建一对对等虚拟设备接口 <code>veth pair</code>,将其中一个接口设置为容器的 <code>eth0</code> 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 <code>vethxxx</code> 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。</p>
<p>  比如我运行一个基于 <code>busybox</code> 镜像构建的容器 <code>bbox01</code>,查看 <code>ip addr</code>:</p>
<blockquote>
<p>busybox 被称为嵌入式 Linux 的瑞士军刀,整合了很多小的 unix 下的通用功能到一个小的可执行文件中。</p>
</blockquote>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/20207760dbf44b608539ed29b9f0365e~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  然后宿主机通过 <code>ip addr</code> 查看信息如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/be67589037c246c48c2be2af63072976~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  通过以上的比较可以发现,证实了之前所说的:守护进程会创建一对对等虚拟设备接口 <code>veth pair</code>,将其中一个接口设置为容器的 <code>eth0</code> 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 <code>vethxxx</code> 这样的名字命名。</p>
<p>  同时,守护进程还会从网桥 <code>docker0</code> 的私有地址空间中分配一个 IP 地址和子网给该容器,并设置 docker0 的 IP 地址为容器的默认网关。也可以安装 <code>yum install -y bridge-utils</code> 以后,通过 <code>brctl show</code> 命令查看网桥信息。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5c7acd76f39f4901b2aa74842065109a~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  对于每个容器的 IP 地址和 Gateway 信息,我们可以通过 <code>docker inspect 容器名称|ID</code> 进行查看,在 <code>NetworkSettings</code> 节点中可以看到详细信息。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/529902ce85a140cea8043970053c3cd3~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  我们可以通过 <code>docker network inspect bridge</code> 查看所有 <code>bridge</code> 网络模式下的容器,在 <code>Containers</code> 节点中可以看到容器名称。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9df1ce538e964fe6980b19785def99f6~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<blockquote>
<p>  关于 <code>bridge</code> 网络模式的使用,只需要在创建容器时通过参数 <code>--net bridge</code> 或者 <code>--network bridge</code> 指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。</p>
</blockquote>
<p>  </p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4f5206a75a884cc2968ceb1f6c14acb6~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>Bridge 桥接模式的实现步骤主要如下:</p>
<ul>
<li>Docker Daemon 利用 veth pair 技术,在宿主机上创建一对对等虚拟网络接口设备,假设为 veth0 和 veth1。而<br>
veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。</li>
<li>Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;</li>
<li>Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,宿主机的网络报文若发往 veth0,则立即会被 Container 的 eth0 接收,实现宿主机到 Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。</li>
</ul>
<p>  </p>
<h3 id="host-网络模式">host 网络模式</h3>
<p>  </p>
<ul>
<li>host 网络模式需要在创建容器时通过参数 <code>--net host</code> 或者 <code>--network host</code> 指定;</li>
<li>采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;</li>
<li>host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。</li>
</ul>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/32ab62e6be9d4b4dbe9280ca3b9206f9~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  比如我基于 <code>host</code> 网络模式创建了一个基于 <code>busybox</code> 镜像构建的容器 <code>bbox02</code>,查看 <code>ip addr</code>:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ff4a5f7151a143c99878964833332e38~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  然后宿主机通过 <code>ip addr</code> 查看信息如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/b756f89bbcb045b4b4b180eddd307e8e~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  对,你没有看错,返回信息一模一样,我也可以肯定我没有截错图,不信接着往下看。我们可以通过 <code>docker network inspect host</code> 查看所有 <code>host</code> 网络模式下的容器,在 <code>Containers</code> 节点中可以看到容器名称。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c11969f9c87a46f088280d50263cffa7~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="none-网络模式">none 网络模式</h3>
<p>  </p>
<ul>
<li>none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 <code>--net none</code> 或者 <code>--network none</code> 指定;</li>
<li>none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。</li>
</ul>
<p>  </p>
<p>  比如我基于 <code>none</code> 网络模式创建了一个基于 <code>busybox</code> 镜像构建的容器 <code>bbox03</code>,查看 <code>ip addr</code>:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/8c55e1e006db44edacbe76f4a66d7d5c~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  我们可以通过 <code>docker network inspect none</code> 查看所有 <code>none</code> 网络模式下的容器,在 <code>Containers</code> 节点中可以看到容器名称。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ed2060f2dbd04d07a5f4c6926d96a271~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="container-网络模式">container 网络模式</h3>
<p>  </p>
<ul>
<li>Container 网络模式是 Docker 中一种较为特别的网络的模式。在创建容器时通过参数 <code>--net container:已运行的容器名称|ID</code> 或者 <code>--network container:已运行的容器名称|ID</code> 指定;</li>
<li>处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。</li>
</ul>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/905bc296603243ad8ee09e13b651e5ba~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  <strong>Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等</strong>。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。</p>
<p>  </p>
<p>  比如我基于容器 <code>bbox01</code> 创建了 <code>container</code> 网络模式的容器 <code>bbox04</code>,查看 <code>ip addr</code>:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d73dd522f2b2426980c16f8bf6c208f0~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  容器 <code>bbox01</code> 的 <code>ip addr</code> 信息如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/4096c75836e2470f8b1554fadf32309e~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  宿主机的 <code>ip addr</code> 信息如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9c01adabe22947ac94c460f0f31ae3b7~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  通过以上测试可以发现,Docker 守护进程只创建了一对对等虚拟设备接口用于连接 bbox01 容器和宿主机,而 bbox04 容器则直接使用了 bbox01 容器的网卡信息。</p>
<p>  这个时候如果将 bbox01 容器停止,会发现 bbox04 容器就只剩下 lo 接口了。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7f2ad30a92fc479a91163483880ccd62~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  然后 bbox01 容器重启以后,bbox04 容器也重启一下,就又可以获取到网卡信息了。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ff5616d7bf9841d4a739a3934267db98~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="link"><s>link</s></h3>
<p>  </p>
<p>  <code>docker run --link</code> 可以用来链接两个容器,使得源容器(被链接的容器)和接收容器(主动去链接的容器)之间可以互相通信,并且接收容器可以获取源容器的一些数据,如源容器的环境变量。</p>
<p>  这种方式<strong>官方已不推荐使用</strong>,并且在未来版本可能会被移除,所以这里不作为重点讲解,感兴趣可自行了解。</p>
<p>  官网警告信息:https://docs.docker.com/network/links/</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c5055248e51c42ec98c5b6d4753a00cb~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h2 id="自定义网络">自定义网络</h2>
<p>  </p>
<p>  虽然 Docker 提供的默认网络使用比较简单,但是为了保证各容器中应用的安全性,在实际开发中更推荐使用自定义的网络进行容器管理,以及启用容器名称到 IP 地址的自动 DNS 解析。</p>
<blockquote>
<p>  从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 <code>--name</code> 为容器命名即可。</p>
<p>  但是使用 Docker DNS 有个限制:<strong>只能在 user-defined 网络中使用</strong>。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。</p>
</blockquote>
<p>  </p>
<h3 id="创建网络">创建网络</h3>
<p>  </p>
<p>  通过 <code>docker network create</code> 命令可以创建自定义网络模式,命令提示如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fa11cfbc030c43e6ae59605e7e0c364c~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  进一步查看 <code>docker network create</code> 命令使用详情,发现可以通过 <code>--driver</code> 指定网络模式且默认是 <code>bridge</code> 网络模式,提示如下:</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/1d85bdfe5b9146c2a06cf4a6cf18ad96~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  创建一个基于 <code>bridge</code> 网络模式的自定义网络模式 <code>custom_network</code>,完整命令如下:</p>
<pre><code class="language-shell">docker network create custom_network
</code></pre>
<p>  </p>
<p>  通过 <code>docker network ls</code> 查看网络模式:</p>
<pre><code class="language-shell"># docker network ls
NETWORK ID          NAME                DRIVER            SCOPE
b3634bbd8943      bridge            bridge            local
062082493d3a      custom_network      bridge            local
885da101da7d      host                host                local
f4f1b3cf1b7f      none                null                local
</code></pre>
<p>  </p>
<p>  通过自定义网络模式 <code>custom_network</code> 创建容器:</p>
<pre><code class="language-shell">docker run -di --name bbox05 --net custom_network busybox
</code></pre>
<p>  </p>
<p>  通过 <code>docker inspect 容器名称|ID</code> 查看容器的网络信息,在 <code>NetworkSettings</code> 节点中可以看到详细信息。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9870393ae7264736a92760346a658685~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="连接网络">连接网络</h3>
<p>  </p>
<p>  通过 <code>docker network connect 网络名称 容器名称</code> 为容器连接新的网络模式。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ca8a513089204fb395d50d4b09a473cd~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<pre><code class="language-shell">docker network connect bridge bbox05
</code></pre>
<p>  通过 <code>docker inspect 容器名称|ID</code> 再次查看容器的网络信息,多增加了默认的 <code>bridge</code>。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5edf3faf3452498a87706d6579530274~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="断开网络">断开网络</h3>
<p>  </p>
<p>  通过 <code>docker network disconnect 网络名称 容器名称</code> 命令断开网络。</p>
<pre><code class="language-shell">docker network disconnect custom_network bbox05
</code></pre>
<p>  通过 <code>docker inspect 容器名称|ID</code> 再次查看容器的网络信息,发现只剩下默认的 <code>bridge</code>。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/2ada8ecd5219441ab1060911c46876df~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<h3 id="移除网络">移除网络</h3>
<p>  </p>
<p>  可以通过 <code>docker network rm 网络名称</code> 命令移除自定义网络模式,网络模式移除成功会返回网络模式名称。</p>
<pre><code class="language-shell">docker network rm custom_network
</code></pre>
<blockquote>
<p>注意:如果通过某个自定义网络模式创建了容器,则该网络模式无法删除。</p>
</blockquote>
<p>  </p>
<h2 id="容器间网络通信">容器间网络通信</h2>
<p>  </p>
<p>  接下来我们通过所学的知识实现容器间的网络通信。首先明确一点,容器之间要互相通信,必须要有属于同一个网络的网卡。</p>
<p>  我们先创建两个基于默认的 <code>bridge</code> 网络模式的容器。</p>
<pre><code class="language-shell">docker run -di --name default_bbox01 busybox
docker run -di --name default_bbox02 busybox
</code></pre>
<p>  </p>
<p>  通过 <code>docker network inspect bridge</code> 查看两容器的具体 IP 信息。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7f54dc0b4a66411b950cf8e9173be5f4~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  然后测试两容器间是否可以进行网络通信。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/77e83da2ffbb4470b2bb4ae7ef38cf3c~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  经过测试,从结果得知两个属于同一个网络的容器是可以进行网络通信的,但是 IP 地址可能是不固定的,有被更改的情况发生,那容器内所有通信的 IP 地址也需要进行更改,能否使用容器名称进行网络通信?继续测试。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ecbc2db61b8d4cdc98246c1684411ff2~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  经过测试,从结果得知使用容器进行网络通信是不行的,那怎么实现这个功能呢?</p>
<p>  从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 <code>--name</code> 为容器命名即可。</p>
<p>  但是使用 Docker DNS 有个限制:<strong>只能在 user-defined 网络中使用</strong>。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。</p>
<p>  我们先基于 <code>bridge</code> 网络模式创建自定义网络 <code>custom_network</code>,然后创建两个基于自定义网络模式的容器。</p>
<pre><code class="language-shell">docker run -di --name custom_bbox01 --net custom_network busybox
docker run -di --name custom_bbox02 --net custom_network busybox
</code></pre>
<p>  </p>
<p>  通过 <code>docker network inspect custom_network</code> 查看两容器的具体 IP 信息。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ff791f1e736b4cf3bef92b5a5350aa38~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  然后测试两容器间是否可以进行网络通信,分别使用具体 IP 和容器名称进行网络通信。</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/bc09527ce8854195b37a2d44d3d8ef77~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<p>  </p>
<p>  经过测试,从结果得知两个属于同一个自定义网络的容器是可以进行网络通信的,并且可以使用容器名称进行网络通信。</p>
<p>  那如果此时我希望 <code>bridge</code> 网络下的容器可以和 <code>custom_network</code> 网络下的容器进行网络又该如何操作?其实答案也非常简单:让 <code>bridge</code> 网络下的容器连接至新的 <code>custom_network</code> 网络即可。</p>
<pre><code class="language-shell">docker network connect custom_network default_bbox01
</code></pre>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d13129eb080b40419bb32f71a0416390~tplv-k3u1fbpfcp-zoom-1.image" alt="" title=" " loading="lazy"></p>
<blockquote>
<p>学完容器网络通信,大家就可以练习使用多个容器完成常见应用集群的部署了。后面就该学习 Docker 进阶部分的内容 Docker Compose 和 Docker Swarm。</p>
</blockquote>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fd373a4509194a7fa7728e56506b522e~tplv-k3u1fbpfcp-zoom-1.image" alt="" loading="lazy"></p>
<p>本文采用 <code>知识共享「署名-非商业性使用-禁止演绎 4.0 国际」许可协议</code>。</p>
<p>大家可以通过 <code>分类</code> 查看更多关于 <code>Docker</code> 的文章。</p>
<p>  </p>
<p>🤗 您的<code>点赞</code>和<code>转发</code>是对我最大的支持。</p>
<p>📢 扫码关注 <code>哈喽沃德先生</code>「文档 + 视频」每篇文章都配有专门视频讲解,学习更轻松噢 ~</p>
<p><img src="//p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/229144d1c78545d88ad1f96af6300b26~tplv-k3u1fbpfcp-zoom-1.image" alt="" loading="lazy"></p>
<p><img src="https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d8daee9958cd463ba151d36fbdee0091~tplv-k3u1fbpfcp-zoom-1.image" alt="" loading="lazy"></p>


</div>
<div id="MySignature" role="contentinfo">
    欢迎大家访问我的个人网站。<br/>
https://mrhelloworld.com<br><br>
来源:https://www.cnblogs.com/mrhelloworld/p/docker11.html
頁: [1]
查看完整版本: Docker 网络模式详解及容器间网络通信