本教程将探讨在Docker中学习和测试DNS。DNS的工作方式有些不同,这取决于你在环境中使用的是自定义网络还是默认网络。良好的DNS工作对容器很重要,因为你不能依赖容器中的IP地址,因为容器是非常动态的。容器往往是短暂的和变化的。也就是说,它们会被启动、拆除,并经常在不同环境中移动。这是微服务架构的本质。IP地址不能作为从一个容器到另一个容器的对话方式,因为不能保证IP地址会是相同的。这就是为什么Docker有内置的DNS命名,它使用容器名称作为容器之间对话的等效主机名。让我们探讨一下Docker中的DNS是如何工作的。
Docker DNS练习
在这个练习中,我们要完成以下步骤。
- 创建一个新的自定义网络
- 启动一个Ubuntu容器并将其连接到自定义网络上
- 启动第二个Ubuntu容器,并将其连接到自定义网络上
- 在两个容器上安装Ping工具
- 启动两个容器
- 使用两个容器的Ping测试来测试网络连接性
创建一个自定义网络
通过在Docker中创建一个自定义网络,我们可以为连接到这个网络的任何容器启用自动DNS解析。你需要确保你为每个容器命名,因为Docker中的DNS是基于容器的名字工作的。
> docker network create custom_network
f37fa69420f0bb17b0dc57ebce73005b9d82ae41ec6690754064ca346aad7a7d
> docker network ls
NETWORK ID NAME DRIVER SCOPE
313d57da9944 bridge bridge local
f37fa69420f0 custom_network bridge local
4c835cce5ea0 host host local
085638da5c3d none null local
创建第一个Ubuntu容器
当我们创建Ubuntu容器时,我们给它一个名字并指定它要连接的网络。我们还在容器中安装了bash的ping功能。
> docker container run -it --name ubuntu_one --network custom_network ubuntu
root@b63bf5467665:/# apt update
root@b63bf5467665:/# apt install iputils-ping -y
root@b63bf5467665:/# exit
exit
创建第二个Ubuntu容器
为了测试容器之间的网络连接,我们需要建立第二个容器并将其连接到相同的自定义网络。
> docker container run -it --name ubuntu_two --network custom_network ubuntu
root@899ef9635122:/# apt update
root@899ef9635122:/# apt install iputils-ping -y
root@899ef9635122:/# exit
exit
启动两个容器
一个docker容器只有在容器内有一个活动进程在运行时才会保持运行。由于我们在上面退出了每个容器的bash shell,它们就停止了。我们可以像这样重新启动它们。
> docker container start ubuntu_one ubuntu_two
ubuntu_one
ubuntu_two
从Ubuntu One连接到Ubuntu Two
现在我们只需[连接到容器],并从一个容器向另一个容器发出一个ping命令。
> docker container exec -it ubuntu_one ping -c 3 ubuntu_two
PING ubuntu_two (172.20.0.3) 56(84) bytes of data.
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=2 ttl=64 time=0.148 ms
64 bytes from ubuntu_two.custom_network (172.20.0.3): icmp_seq=3 ttl=64 time=0.255 ms
--- ubuntu_two ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2063ms
rtt min/avg/max/mdev = 0.137/0.180/0.255/0.053 ms
从Ubuntu 2连接到Ubuntu 1
同样的测试可以通过连接到第二个容器和测试网络连接回到容器一来进行。
> docker container exec -it ubuntu_two ping -c 3 ubuntu_one
PING ubuntu_one (172.20.0.2) 56(84) bytes of data.
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=1 ttl=64 time=0.192 ms
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=2 ttl=64 time=0.170 ms
64 bytes from ubuntu_one.custom_network (172.20.0.2): icmp_seq=3 ttl=64 time=0.168 ms
--- ubuntu_one ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2100ms
rtt min/avg/max/mdev = 0.168/0.176/0.192/0.010 ms
它是有效的!这个练习显示了DNS是如何在连接到同一自定义网络的容器中自动工作的。这一点很好理解,因为当你有一个包含多个容器的项目时,你会希望它们能够很容易地相互交谈。Docker Compose通过在你启动应用程序时自动创建新的虚拟网络,使容器通信自动进行,从而使这一点变得更容易。然而,看看这个工作是如何手动进行的是有帮助的,所以我们知道Docker Compose实际上在为我们做什么。
Docker DNS是如何工作的 摘要
- DNS用于容器之间的通信。
- DNS对于默认的桥接网络和自定义的网络的工作方式不同。
- -link命令可用于桥接网络的手动DNS。
- 使用名字而不是IP地址 - 容器的静态IP地址是一种反模式。使用名字来代替通信。
- Docker DNS - Docker守护进程有一个内置的DNS服务器,容器默认使用。
- DNS默认值 - Docker将主机名默认为容器的名称。
- 只需创建一个自定义的网络,而不是依赖桥接网络上的-链接,这要容易得多。