【问题标题】:Restarting named container assigns different IP重启命名容器分配不同的IP
【发布时间】:2014-09-03 19:44:35
【问题描述】:

我在尝试使用 Docker 部署我的应用程序时遇到了一个问题,即重新启动命名容器会为容器分配不同的 IP。也许解释我在做什么会更好地解释这个问题:

  • Postgres 在名为 "postgres"
    $ PG_ID=$(docker run --name postgres postgres/image) 的单独容器中运行
  • 我的 webapp 容器链接到 postgres 容器
    $ APP_ID=$(docker run --link postgres:postgres webapp/image)

将 postgres 容器映像链接到 webapp 容器会在 webapp 容器中插入一个带有 postgres 容器 IP 的主机文件条目。这允许我使用postgres:5432(我正在使用 Django btw)在我的 webapp 中指向 postgres db。这一切都很好,除非由于某种原因 postgres 崩溃。

在我手动停止 postgres 进程以模拟 postgres 进程崩溃之前,我验证了 postgres 容器的 IP:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.73

现在为了模拟崩溃,我停止了 postgres 容器:

$ docker stop $PG_ID

如果我现在使用重新启动 postgres

$ docker start $PG_ID

容器的ip发生变化:

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.74

因此,webapp 容器中指向 postgres 容器的 IP 不再正确。我虽然通过命名容器 docker 为它分配了一个具有特定配置的名称,以便您可以在容器(网络和卷)之间可靠地链接。如果 IP 发生变化,这似乎无法达到目的。

如果每次 postgres 重新启动时我都必须重新启动我的 webapp 进程,这似乎并不比仅使用单个容器来运行两个进程更好。然后我可以使用 supervisor 或类似的东西来保持它们都运行并使用localhost 来链接进程。

我还是 Docker 新手,是我做错了什么还是 Docker 中的错误?

【问题讨论】:

  • 你会发现这个related question & answer很有用。
  • 谢谢。将看看ddns。希望不会那么困难。 Docker 看起来很酷,但似乎需要一些学习曲线才能正确使用它......

标签: linux networking docker linux-containers


【解决方案1】:

第二次更新:也许您已经发现了这一点,但作为解决方法,我计划将服务映射到共享数据库到主机接口(ej:使用 -p 5432:5432),并将 webapps 连接到主机 IP( docker0 接口的 IP:在我的 Ubuntu 和 CentOS 中,IP 是 172.17.42.1)。如果你重新启动 postgres 容器,容器的 IP 将会改变,但我可以使用 172.17.42.1:5432 访问。缺点是您将该端口暴露给所有容器,并松散了 --link 为您提供的细粒度映射。

--- 旧更新:

更正:Docker 会将“postgres”映射到 webapp 容器上 /etc/hosts 文件中的容器 IP。因此,在 webapp 容器中,您可以 ping 'postgres',它将映射到 IP。

第一次更新:我看到 Docker 生成并挂载 /etc/hosts、/etc/resolv.conf 等以始终获得正确的信息,但这不适用于重新启动链接容器时。所以,我(错误地)假设 Docker 会更新主机文件。

-- 原始(错误)响应:

添加--hostname=postgres-db(你可以使用任何东西,我使用了不同于'postgres'的东西以避免与容器名称混淆):

$ docker run --name postgres --hostname postgres-db postgres/image

Docker 会将“postgres-db”映射到容器的 IP(检查 webapp 容器上 /etc/hosts 的内容)。

这将允许您从 webapp 容器运行“ping postgres-db”。如果 IP 发生变化,Dockers 会为你更新 /etc/hosts。

在 Django 应用程序中,使用“postgres-db”而不是 IP(或您使用 PostgreSql 容器的 --hostname 使用的任何内容)。

再见! 奥拉西奥

【讨论】:

  • 请检查您的事实。 Docker 链接容器时只使用--name 参数。 --hostname 仅用于在postgres 容器中插入条目,而不是在webappcontainer 中。
  • miki725:你说得对,我在测试中感到困惑。我对名称和主机名使用了相同的字符串,并假设在 /etc/hosts 中使用了“主机名”中指定的字符串...
【解决方案2】:

根据https://docs.docker.com/engine/reference/commandline/run/,应该可以使用--ip 选项为您的容器分配一个静态IP——在创建容器时——

例子:

docker run -itd --ip 172.30.100.104 --name postgres postgres/image

....其中 172.30.100.104 是自定义桥接/覆盖网络上的免费 IP 地址。

即使 postgres 容器崩溃/重新启动,这也应该保留相同的 IP 地址。

看起来这是在 Docker Engine v 1.10 或更高版本中发布的,因此如果您的版本较低,则必须先升级。

【讨论】:

    【解决方案3】:

    从 Docker 1.0 开始,他们实现了更强的链接容器。现在您可以像使用主机名一样使用容器实例名称。

    这是link

    我找到了一个link,可以更好地描述您的问题。虽然这个问题得到了回答,但我想知道这个ambassador 模式是否不能解决问题......这假设大使比链接的服务更可靠。

    【讨论】:

    • 请阅读我的问题。一旦父容器重新启动,它的 IP 就会发生变化,因此 hosts 文件中的任何内容都不再有效。
    猜你喜欢
    • 1970-01-01
    • 2016-04-15
    • 2019-07-30
    • 1970-01-01
    • 2014-08-06
    • 2013-09-15
    • 2015-03-12
    • 2021-01-10
    • 2021-11-03
    相关资源
    最近更新 更多