【问题标题】:Dynamically resolving container hostname to an IP将容器主机名动态解析为 IP
【发布时间】:2019-02-16 00:09:55
【问题描述】:

我在docker-compose.yml 中有几个服务需要相互交谈。这不是问题,因为作曲家在内部负责所有网络。但是,其中一项服务需要白名单才能允许与其 API 进行通信。不幸的是,此白名单仅对 IPv4 地址有限制 - 它不解析主机名。

我希望避免必须定义自己的自定义网络并为容器分配静态 IP 地址,从而保持灵活性。我进行了上下搜索,但没有看到在运行时解析服务名称的方法,甚至在构建阶段也没有。

我已尝试安装 DNS 工具并使用 dig,但无法确定 IP 地址。这可能与我对 Docker 如何处理网络层缺乏了解有关。

所以我的问题是:

  • 如何在运行时或构建阶段解析容器服务名称?
  • 使用docker-compose 构建时,它是否会为容器分配静态地址,或者是否有可能在重启后容器 IP 发生变化?

【问题讨论】:

    标签: docker docker-compose dockerfile docker-networking


    【解决方案1】:

    一个月前我遇到了类似的挑战,并且可以获得你想要的东西(即使我在 Kubernetes 上工作而不是使用 docker-compose)。

    Docker 提供了一个内部 DNS 解析系统,如 StackOverflow question 中所述。 如果您稍微修改一下dig,您会发现容器使用的 DNS IP 与您的主机不同。

    特别是,launching the Wordpress example 形成 docker-compose 文档,您可以通过以下方式查看它:

    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 字段显示127.0.0.11#53,在我的例子中,这是内部 Docker DNS 系统。您可以检查该地址是否是报告的地址(在我的情况下为172.18.0.3)安装curl 并在端口80 到达它。

    考虑到这一点,您可以创建一个脚本或程序来定期执行地址解析,获取 DNS 为该服务返回的地址列表,并相应地更新您的白名单。

    如何在运行时或构建阶段解析容器服务名称?

    以 Java 为例,您可以使用 InetAddress 类,该类给定一个 URL,它返回一个 IP4 和 IP6 地址列表(您可以使用 Apache 公共库中的 InetAddressValidator 过滤它们)。你可以看到更多here(这就是我解决问题的方法)。在 Linux 中,有一个特定的系统调用 getaddrinfo,用于获取给定 URL 的 IP 列表。

    使用 docker-compose 构建时,它是否会为容器分配静态地址,或者是否有可能在重启后容器 IP 发生变化?

    关于第二个问题,docker-compose 使用与docker build 相同的逻辑,因此不会分配静态IP 地址或类似地址。最重要的是,如果容器崩溃并重新启动,它的 IP 可能会发生变化。

    【讨论】:

    • 如果可以的话,我会再给你一个支持。感谢您抽出宝贵时间将这么多细节纳入您的答案。我求助于使用自定义网络配置并将需要已知地址的单个容器分配给静态 IP。我不喜欢这个解决方案,所以我一定会给你一个机会。再次感谢您花时间写这篇文章!干杯。
    • 很高兴为您提供帮助。如果您需要帮助,请不要介意给我发消息,或者如果您打开其他 Stackoverflow 问题,请告诉我!干杯
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-12
    • 1970-01-01
    • 2011-05-07
    • 2019-09-29
    • 1970-01-01
    • 2013-11-29
    相关资源
    最近更新 更多