如何在 Docker 容器之间设置链接,以便重新启动不会破坏它? [英] How do I set up linkage between Docker containers so that restarting won't break it?

查看:21
本文介绍了如何在 Docker 容器之间设置链接,以便重新启动不会破坏它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个 Docker 容器像这样运行:

I have a few Docker containers running like:

  • Nginx
  • 网络应用 1
  • 网络应用 2
  • PostgreSQL

由于 Nginx 需要连接到 Web 应用程序 1 和 2 中的 Web 应用程序服务器,并且 Web 应用程序需要与 PostgreSQL 通信,所以我有这样的链接:

Since Nginx needs to connect to the web application servers inside web app 1 and 2, and the web apps need to talk to PostgreSQL, I have linkages like this:

  • Nginx --- 链接 ---> Web 应用程序 1
  • Nginx --- 链接 ---> 网络应用 2
  • Web 应用程序 1 --- 链接 ---> PostgreSQL
  • Web 应用程序 2 --- 链接 ---> PostgreSQL

这起初效果很好.但是,当我开发新版本的 web app 1 和 web app 2 时,我需要替换它们.我要做的是删除 Web 应用容器,设置新容器并启动它们.

This works pretty well at first. However, when I develop a new version of web app 1 and web app 2, I need to replace them. What I do is remove the web app containers, set up new containers and start them.

对于 Web 应用程序容器,它们的 IP 地址最初类似于:

For the web app containers, their IP addresses at first would be something like:

  • 172.17.0.2
  • 172.17.0.3

在我替换它们之后,它们将拥有新的 IP 地址:

And after I replace them, they will have new IP addresses:

  • 172.17.0.5
  • 172.17.0.6

现在,那些暴露在 Nginx 容器中的环境变量仍然指向旧的 IP 地址.问题来了.如何在不中断容器之间的链接的情况下更换容器?同样的问题也会发生在 PostgreSQL 上.如果我想升级 PostgreSQL 镜像版本,我当然需要删除它并运行新的,但是我需要重建整个容器图,所以这对于现实生活中的服务器操作来说并不理想.

Now, those exposed environment variables in the Nginx container are still pointing to the old IP addresses. Here comes the problem. How do I replace a container without breaking linkage between containers? The same issue will also happen to PostgreSQL. If I want to upgrade the PostgreSQL image version, I certainly need to remove it and run the new one, but then I need to rebuild the whole container graph, so this is not ideal for real-life server operation.

推荐答案

--link 的效果是静态的,因此不适用于您的场景(目前没有重新链接,尽管您可以删除链接).

The effect of --link is static, so it will not work for your scenario (there is currently no re-linking, although you can remove links).

我们在 dockerize.it 上使用了两种不同的方法来解决这个问题,没有链接或大使(尽管你也可以添加大使).

We have been using two different approaches at dockerize.it to solve this, without links or ambassadors (although you could add ambassadors too).

1) 使用动态 DNS

总体思路是为数据库(或任何其他服务)指定一个名称,并在启动和停止容器时使用实际 IP 更新一个短期的 DNS 服务器.

The general idea is that you specify a single name for your database (or any other service) and update a short-lived DNS server with the actual IP as you start and stop containers.

我们从 SkyDock 开始.它与两个 docker 容器、DNS 服务器和一个保持自动更新的监视器一起工作.后来我们转向使用 Consul(也使用 dockerized 版本:docker-consul).

We started with SkyDock. It works with two docker containers, the DNS server and a monitor that keeps it updated automatically. Later we moved to something more custom using Consul (also using a dockerized version: docker-consul).

此方法的演变(我们还没有尝试过)是设置 etcd 或类似工具,并使用其自定义 API 来学习 IP 和端口.软件也应该支持动态重配置.

An evolution of this (which we haven't tried) would be to setup etcd or similar and use its custom API to learn the IPs and ports. The software should support dynamic reconfiguration too.

2) 使用 docker 网桥 ip

当暴露容器端口时,您可以将它们绑定到 docker0 网桥,它具有(或可以具有)众所周知的地址.

When exposing the container ports you can just bind them to the docker0 bridge, which has (or can have) a well known address.

用新版本替换容器时,只需让新容器在同一个IP上发布同一个端口即可.

When replacing a container with a new version, just make the new container publish the same port on the same IP.

这更简单,但也更有限.如果您运行类似的软件,您可能会遇到端口冲突(例如,两个容器无法侦听 docker0 网桥上的 3306 端口)等等……所以我们目前最喜欢的是选项 1.

This is simpler but also more limited. You might have port conflicts if you run similar software (for instance, two containers can not listen on the 3306 port on the docker0 bridge), etcétera… so our current favorite is option 1.

这篇关于如何在 Docker 容器之间设置链接,以便重新启动不会破坏它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆