你是否曾经想过 Docker 中的网络是如何工作的?也许你对使用 Docker 的网络层可以做的鲜为人知的事情感兴趣?以下是一些有趣的事实和用例,可能有助于日常使用。
开放端口
让我们从基础开始。端口开放是 Docker 网络中最常用的东西,但你了解它的全部内容吗?
让我们看一个简单的命令,如下所示:
1  | docker run -p 127.0.0.1:80:8080/tcp ubuntu bash  | 
这是什么意思?好吧,可能有点棘手,但它的意思是:
在端口 80 上监听 127.0.0.1 上的 TCP 连接,并将流量转发到容器内的端口 8080。
如果我们稍微简化一下:
1  | docker run -p 80:8080/tcp ubuntu bash  | 
我们省略了 IP 部分,现在 Docker 将监听所有接口,因此可以从外部访问该服务。
我们可以进一步更改符号,然后运行:
1  | docker run -p 80:8080/udp ubuntu bash  | 
这将转发 udp 连接。另一个选项是 sctp,但它并未广泛用于与 Web 相关的东西。TCP 显然是最常见的,因此如果我们跳过 /protocol 部分 - 它将默认设置为 TCP。
如果我们只运行这个会发生什么:
1  | docker run -p 8080 ubuntu bash  | 
这会将 TCP 流量从随机选择的端口转发到容器中的端口 8080。等等?随机?!我怎么知道使用了哪个端口?
只需查看 docker ps - 有一列:
1  | docker ps  | 
PORTS 列中包含你需要的所有信息,甚至更多。它还显示未转发的开放端口。此类端口无法从外部访问(docker 网络除外,但这会改变),但如果你想转发它,你可以获得此信息。
你还可以运行 docker port 来检查给定容器的映射:
1  | docker port project_phpmyadmin_1  | 
但是它缺少未映射端口的部分,所以我想你不会经常使用该命令 😉
还有最后一件事我们需要提及,那就是 docker run 的 -P 参数。
1  | docker run -P ubuntu bash  | 
-P 在主机上的随机端口上开放 Dockerfile 中提到的所有端口。
连接容器
让我们启动一个简单的 Web 服务器:
1  | docker run -d --name test_web nginx:alpine  | 
如果我们启动第二个容器,比如说 ubuntu,在其上安装 curl 并尝试访问网页:
1  | docker run -t -i --rm ubuntu bash  | 
这行不通,名称未解析!我们可以使用 docker inspect 并检查 test_web 容器的 IP 是否为 172.17.0.2,然后运行
1  | curl 172.17.0.2  | 
而且它可以工作。因此连接性有限,但这是可能的。
如果你熟悉 docker-compose,这可能会令人困惑。docker-compose 中的服务可以使用其名称轻松相互通信!如果你有一个简单的文件,例如:
1  | version: "3.6"  | 
然后 phpmyadmin 显然可以使用其名称 db 连接到 db 服务!原因很简单,它适用于同一网络内的容器,默认容器除外。
让我们尝试一下!
我们可以通过运行以下命令创建一个新网络:
1  | docker network create test  | 
并将现有容器连接到它并运行:
1  | docker network connect test test_web  | 
我假设测试 bash 容器仍然处于活动状态,你只需在上面的第二行中使用它的名称即可。现在切换回它并运行:
1  | curl test_web  | 
可以正常工作!请注意,只要两个容器共享同一网络,就无需开放端口即可从第二个容器访问它。
通过运行以下命令断开其中一个容器与新创建的网络的连接:
1  | docker network disconnect test NameOfYourBashContainer  | 
并且名称将不再解析!
还可以在创建容器时将其连接到网络,只需将网络作为输入选项之一传递即可:
1  | docker run -t -i --rm --network test ubuntu bash  | 
相关文章: