简介
在这个实验中,你将学习如何使用 docker network create
命令有效地管理容器网络。我们将探索不同的网络类型和配置,以了解容器之间以及容器与外部世界如何进行通信。
具体来说,你将通过实践获得以下经验:创建基本的桥接网络、使用特定的子网和网关自定义桥接网络,以及为多主机通信场景设置可连接和内部覆盖网络。在本实验结束时,你将对如何为你的 Docker 容器设计和实现各种网络拓扑有深入的理解。
在这个实验中,你将学习如何使用 docker network create
命令有效地管理容器网络。我们将探索不同的网络类型和配置,以了解容器之间以及容器与外部世界如何进行通信。
具体来说,你将通过实践获得以下经验:创建基本的桥接网络、使用特定的子网和网关自定义桥接网络,以及为多主机通信场景设置可连接和内部覆盖网络。在本实验结束时,你将对如何为你的 Docker 容器设计和实现各种网络拓扑有深入的理解。
在这一步中,你将学习如何在 Docker 中创建一个基本的桥接网络。桥接网络是容器的默认网络类型。连接到同一桥接网络的容器可以相互通信,同时与其他桥接网络上的容器以及主机的网络隔离开来。
首先,让我们列出现有的 Docker 网络,查看默认的网络。
docker network ls
你应该会看到一些默认的网络,如 bridge
、host
和 none
。我们将使用的是 bridge
网络。
现在,让我们创建一个新的桥接网络。我们将其命名为 my-bridge-network
。
docker network create my-bridge-network
此命令使用默认设置创建一个新的桥接网络。Docker 会自动为该网络分配一个子网和网关。
为了验证网络是否成功创建,请再次列出 Docker 网络。
docker network ls
现在你应该在列表中看到 my-bridge-network
。
接下来,让我们检查新创建的网络,查看其详细信息,包括 Docker 分配的子网和网关。
docker network inspect my-bridge-network
此命令的输出将提供有关该网络的详细信息,例如其 ID、驱动程序(应该是 bridge
)以及 IPAM
部分下的子网和网关。
现在,让我们运行一个容器并将其连接到我们的新网络。在这个示例中,我们将使用 alpine
镜像。如果你本地没有 alpine
镜像,Docker 会自动拉取它。
docker run -d --name container1 --network my-bridge-network alpine sleep infinity
此命令以分离模式(-d
)运行一个名为 container1
的容器,将其连接到 my-bridge-network
(--network my-bridge-network
),并通过执行 sleep infinity
命令使其保持运行状态。
为了验证容器是否正在运行并连接到了正确的网络,你可以检查该容器。
docker inspect container1
在输出中,查找 Networks
部分。你应该会看到 my-bridge-network
被列出,以及该容器在该网络中分配的 IP 地址。
最后,让我们运行另一个容器并将其连接到同一网络,以演示它们之间的通信。
docker run -d --name container2 --network my-bridge-network alpine sleep infinity
现在,container1
和 container2
都连接到了 my-bridge-network
。它们应该能够使用它们在网络中的容器名称或 IP 地址相互通信。
为了测试通信,我们可以在 container1
内部执行一个命令来 ping container2
。首先,我们需要在 Alpine 容器中安装 iputils
包,以便使用 ping
命令。
docker exec container1 apk add --no-cache iputils
docker exec container2 apk add --no-cache iputils
现在,从 container1
ping container2
。
docker exec container1 ping -c 3 container2
你应该会看到成功的 ping 响应,这表明同一桥接网络上的两个容器可以进行通信。
在上一步中,我们使用默认设置创建了一个桥接网络,Docker 自动分配了子网和网关。在这一步,你将学习如何创建一个桥接网络并指定自己的子网和网关,这能让你对容器的网络配置有更多的控制权。
首先,让我们删除上一步中创建的容器和网络,以便重新开始。
docker stop container1 container2
docker rm container1 container2
docker network rm my-bridge-network
现在,让我们创建一个名为 custom-bridge-network
的新桥接网络,并使用 --subnet
和 --gateway
标志指定自定义的子网和网关。我们将使用子网 172.20.0.0/16
和网关 172.20.0.1
。
docker network create \
--driver bridge \
--subnet 172.20.0.0/16 \
--gateway 172.20.0.1 \
custom-bridge-network
--driver bridge
标志明确指定了桥接驱动程序,尽管它是默认的。--subnet
标志定义了网络的 IP 地址范围,--gateway
标志为连接到该网络的容器设置了网关 IP 地址。
为了验证网络是否使用指定的子网和网关创建成功,请检查该网络。
docker network inspect custom-bridge-network
在输出中,查看 IPAM
部分。你应该会看到 Subnet
和 Gateway
字段与你提供的值相匹配(172.20.0.0/16
和 172.20.0.1
)。
现在,让我们运行一个容器并将其连接到我们的新网络。我们将再次使用 alpine
镜像。
docker run -d --name custom-container1 --network custom-bridge-network alpine sleep infinity
此命令运行一个名为 custom-container1
的容器,并将其连接到 custom-bridge-network
。Docker 将从指定的子网(172.20.0.0/16
)为该容器分配一个 IP 地址。
为了验证容器在自定义网络中的 IP 地址,请检查该容器。
docker inspect custom-container1
在输出中,在 custom-bridge-network
的 Networks
部分下,你应该会看到一个落在 172.20.0.0/16
范围内的 IpAddress
。
让我们在同一网络上运行另一个容器。
docker run -d --name custom-container2 --network custom-bridge-network alpine sleep infinity
现在,custom-container1
和 custom-container2
都在 custom-bridge-network
上,并且应该能够相互通信。
和上一步一样,我们需要 iputils
来进行 ping 测试。
docker exec custom-container1 apk add --no-cache iputils
docker exec custom-container2 apk add --no-cache iputils
通过从 custom-container1
ping custom-container2
来测试通信。
docker exec custom-container1 ping -c 3 custom-container2
你应该会看到成功的 ping 响应,这证实了自定义桥接网络内的通信正常。
桥接网络适用于同一 Docker 主机上的容器之间的通信。然而,要实现运行在不同 Docker 主机上的容器之间的通信,你需要使用覆盖网络(overlay network)。覆盖网络由 Docker Swarm 创建和管理。
在这一步中,你将创建一个可连接的覆盖网络。可连接的覆盖网络允许独立容器(不属于 Swarm 服务的一部分)连接到它,并在不同的 Docker 主机之间进行通信。
首先,你需要在这个主机上初始化 Docker Swarm。这是创建和管理覆盖网络所必需的。
docker swarm init --advertise-addr $(hostname -I | awk '{print $1}')
此命令初始化 Swarm 并将通告地址设置为主机的 IP 地址。输出将显示当前节点现在是一个 Swarm 管理器。
现在 Swarm 已初始化,你可以创建一个可连接的覆盖网络。我们将其命名为 my-overlay-network
。--attachable
标志对于允许独立容器连接至关重要。
docker network create \
--driver overlay \
--attachable \
my-overlay-network
--driver overlay
标志指定你正在创建一个覆盖网络。--attachable
标志使该网络可供独立容器使用。
为了验证覆盖网络是否已创建,请列出 Docker 网络。
docker network ls
你应该在列表中看到 my-overlay-network
,并且其驱动程序应该是 overlay
。
现在,让我们运行一个独立容器并将其连接到新的覆盖网络。我们将使用 alpine
镜像。
docker run -d --name overlay-container1 --network my-overlay-network alpine sleep infinity
此命令运行一个名为 overlay-container1
的容器,并将其连接到 my-overlay-network
。
为了验证容器是否已连接到覆盖网络,请检查该容器。
docker inspect overlay-container1
在输出中,查找 Networks
部分。你应该会看到 my-overlay-network
被列出。
由于这是一个单主机环境,你无法完全演示多主机通信。但是,如果有多个 Swarm 节点,该网络已配置为支持多主机通信。
让我们在这个单主机上的同一覆盖网络上运行另一个容器。
docker run -d --name overlay-container2 --network my-overlay-network alpine sleep infinity
现在,overlay-container1
和 overlay-container2
都在 my-overlay-network
上,并且应该能够相互通信。
在容器中安装 iputils
以进行 ping 测试。
docker exec overlay-container1 apk add --no-cache iputils
docker exec overlay-container2 apk add --no-cache iputils
通过从 overlay-container1
ping overlay-container2
来测试通信。
docker exec overlay-container1 ping -c 3 overlay-container2
你应该会看到成功的 ping 响应,这证实了在这个单主机上的覆盖网络内的通信正常。
在上一步中,我们创建了一个可连接的覆盖网络,允许独立容器进行连接。在这一步,我们将创建一个内部覆盖网络。内部网络与外部网络隔离,这意味着除非明确允许,否则内部网络上的容器无法与外部世界(包括 Docker 主机的网络)进行通信。这对于在 Swarm 中创建隔离的服务网络非常有用。
首先,让我们清理上一步中创建的容器和网络。
docker stop overlay-container1 overlay-container2
docker rm overlay-container1 overlay-container2
docker network rm my-overlay-network
现在,让我们创建一个名为 my-internal-network
的内部覆盖网络。为此,我们使用 --internal
标志。
docker network create \
--driver overlay \
--internal \
my-internal-network
--internal
标志确保连接到该网络的容器无法与外部网络进行通信。
为了验证内部覆盖网络是否已创建,请列出 Docker 网络。
docker network ls
你应该在列表中看到 my-internal-network
,其驱动程序为 overlay
。
现在,让我们运行一个容器并将其连接到新的内部网络。我们将使用 alpine
镜像。
docker run -d --name internal-container1 --network my-internal-network alpine sleep infinity
此命令运行一个名为 internal-container1
的容器,并将其连接到 my-internal-network
。
为了验证容器是否已连接到内部网络,请检查该容器。
docker inspect internal-container1
在输出中,查找 Networks
部分。你应该会看到 my-internal-network
被列出。
让我们在同一内部网络上运行另一个容器。
docker run -d --name internal-container2 --network my-internal-network alpine sleep infinity
现在,internal-container1
和 internal-container2
都在 my-internal-network
上。它们应该能够相互通信,但无法与外部世界通信。
在容器中安装 iputils
以进行 ping 测试。
docker exec internal-container1 apk add --no-cache iputils
docker exec internal-container2 apk add --no-cache iputils
通过从 internal-container1
ping internal-container2
来测试通信。
docker exec internal-container1 ping -c 3 internal-container2
你应该会看到成功的 ping 响应,这证实了内部覆盖网络内的通信正常。
现在,让我们尝试从 internal-container1
ping 一个外部地址,例如 google.com
。
docker exec internal-container1 ping -c 3 google.com
这个 ping 操作应该会失败,因为内部网络与外部网络是隔离的。
在本次实验中,我们学习了如何使用 docker network create
命令来管理容器网络。首先,我们创建了一个基本的桥接网络,它是容器的默认网络类型,并使用 docker network ls
和 docker network inspect
命令验证了网络的创建和详细信息。接着,我们演示了如何将容器连接到这个新创建的网络。
在基本桥接网络的基础上,我们探索了如何创建具有自定义子网和网关的桥接网络,以便更好地控制网络的 IP 地址分配。最后,我们深入学习了创建覆盖网络,特别是用于多主机通信的可连接覆盖网络,以及用于在 Swarm 内进行隔离通信的内部覆盖网络,展示了 Docker 网络在不同部署场景中的多功能性。