我在docker-compose.yml
有几个服务需要彼此说话。这不是问题,因为作曲家会在内部处理所有网络。但是,其中一项服务需要白名单才能与其API进行通信。此白名单仅对IPv4地址有一个不幸的限制 - 它不解析主机名。
我想避免必须定义自己的自定义网络并为容器分配静态IP地址,保持其灵活性。我上下搜索并没有看到在运行时解析服务名称的方法,甚至在构建阶段也没有。
我尝试过安装DNS工具并使用dig
但无法确定IP地址。这可能与我对Docker如何处理网络层缺乏了解有关。
所以我的问题是:
docker-compose
构建时,是否为容器分配静态地址,或者重启后容器IP是否有可能发生变化?我在一个月前遇到了类似的挑战,并且有可能获得你想要的东西(即使我正在研究Kubernetes而不是使用docker-compose)。
Docker提供了一个内部DNS解析系统,如本StackOverflow question中所述。如果您使用dig
进行一些攻击,您会发现容器使用的是来自主机的不同DNS IP。
特别是来自docker-compose文档的qazxsw poi,您可以通过以下方式查看它:
launching the Wordpress example
然后,在容器类型内:
mkdir /tmp/test && cd /tmp/test
# create a docker-compose.yaml file and past the example from the link above
docker-compose up -d
# it should be test_default, check it out with `docker network ls`
docker run --rm -it --network test_default ubuntu /bin/bash
你应该得到类似的东西:
apt-get update && apt-get install -y dnsutils
dig wordpress
在这里你看到字段root@91e47b426ed3:/# dig wordpress
; <<>> DiG 9.11.3-1ubuntu1.3-Ubuntu <<>> wordpress
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17239
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;wordpress. IN A
;; ANSWER SECTION:
wordpress. 600 IN A 172.18.0.3
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Sun Feb 17 19:39:24 UTC 2019
;; MSG SIZE rcvd: 52
说SERVER
,这是我的情况下的内部Docker DNS系统。您可以检查地址是否是报告的地址(在我的情况下是127.0.0.11#53
)安装172.18.0.3
并在curl
端口到达。
考虑到这一点,您可以创建定期执行地址解析的脚本或程序,获取DNS为该服务返回的地址列表并相应地更新白名单。
如何在运行时或构建阶段解析容器服务名称?
以Java为例,您可以使用给定URL的80
类,它会返回IP4和IP6地址列表(您可以使用Apache Common库中的InetAddress过滤它们)。你可以看到更多InetAddressValidator
(这就是我解决问题的方法)。在Linux中,有一个特定的系统调用here,用于获取给定URL的IP列表。
使用docker-compose构建时,是否为容器分配静态地址,或者重启后容器IP是否有可能发生变化?
关于第二个问题,docker-compose使用相同的getaddrinfo逻辑,因此它不会分配静态IP地址或类似的。最重要的是,如果容器崩溃并重新启动,则其IP可能会发生变化。