如何设置docker容器之间的链接,以便重新启动不会破坏它?

Fan*_*Lin 80 deployment docker

我有几个像我这样的码头工人集装箱

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

由于Nginx需要连接Web应用程序1和2中的Web应用程序服务器,并且Web应用程序需要与postgresql交谈,所以我有这样的链接

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

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

对于Web应用程序容器,它们的IP地址最初会是这样的

  • 172.17.0.2
  • 172.17.0.3

在我更换它们之后,它们现在有了新的IP地址

  • 172.17.0.5
  • 172.17.0.6

此时,Nginx容器中的那些公开环境变量仍指向旧IP地址.这就出现了问题,如何在不破坏其他容器之间的连接的情况下更换容器?同样的问题也会发生在PostgreSQL上,如果我想升级PostgreSQL映像版本,我当然需要删除它并运行新的,但后来我需要重建整个容器图,这对于真正的不是一个好主意生活服务器操作.

Abe*_*iño 53

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

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

1)使用动态DNS

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

我们从SkyDock开始.它适用于两个docker容器,DNS服务器和一个自动更新的监视器.后来我们使用Consul(也使用了一个dockerized版本:docker -consul)转向了一些更自定义的东西.

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

2)使用docker bridge ip

暴露容器端口时,您只需将它们绑定到docker0具有(或可能具有)已知地址的桥.

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

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


Hem*_*ela 20

链接用于特定容器,而不是基于容器的名称.因此,当您删除容器时,链接将断开连接,新容器(即使具有相同名称)也不会自动取代它.

新的网络功能允许您按名称连接到容器,因此,如果您创建新网络,则连接到该网络的任何容器都可以通过其名称访问其他容器.例:

1)创建新网络

$ docker network create <network-name>       
Run Code Online (Sandbox Code Playgroud)

2)将容器连接到网络

$ docker run --net=<network-name> ...
Run Code Online (Sandbox Code Playgroud)

要么

$ docker network connect <network-name> <container-name>
Run Code Online (Sandbox Code Playgroud)

3)按名称Ping容器

docker exec -ti <container-name-A> ping <container-name-B> 

64 bytes from c1 (172.18.0.4): icmp_seq=1 ttl=64 time=0.137 ms
64 bytes from c1 (172.18.0.4): icmp_seq=2 ttl=64 time=0.073 ms
64 bytes from c1 (172.18.0.4): icmp_seq=3 ttl=64 time=0.074 ms
64 bytes from c1 (172.18.0.4): icmp_seq=4 ttl=64 time=0.074 ms
Run Code Online (Sandbox Code Playgroud)

请参阅文档的部分;

注意:与旧版本不同links,新网络不会创建环境变量,也不会与其他容器共享环境变量.

此功能目前不支持别名


Swe*_*ler 10

您可以使用大使容器.但是不要将大使容器链接到您的客户端,因为这会产生与上面相同的问题.而是使用docker主机上的ambassador容器的公开端口(通常为172.17.42.1).例:

postgres卷:

$ docker run --name PGDATA -v /data/pgdata/data:/data -v /data/pgdata/log:/var/log/postgresql phusion/baseimage:0.9.10 true
Run Code Online (Sandbox Code Playgroud)

Postgres的容器:

$ docker run -d --name postgres --volumes-from PGDATA -e USER=postgres -e PASS='postgres' paintedfox/postgresql
Run Code Online (Sandbox Code Playgroud)

postgres的大使容器:

$ docker run -d --name pg_ambassador --link postgres:postgres -p 5432:5432 ctlc/ambassador
Run Code Online (Sandbox Code Playgroud)

现在,您可以启动postgresql客户端容器,而无需链接大使容器并访问网关主机上的postgresql(通常为172.17.42.1):

$ docker run --rm -t -i paintedfox/postgresql /bin/bash
root@b94251eac8be:/# PGHOST=$(netstat -nr | grep '^0\.0\.0\.0 ' | awk '{print $2}')
root@b94251eac8be:/# echo $PGHOST
172.17.42.1
root@b94251eac8be:/#
root@b94251eac8be:/# psql -h $PGHOST --user postgres
Password for user postgres: 
psql (9.3.4)
SSL connection (cipher: DHE-RSA-AES256-SHA, bits: 256)
Type "help" for help.

postgres=#
postgres=# select 6*7 as answer;
 answer 
--------
     42
(1 row)

bpostgres=# 
Run Code Online (Sandbox Code Playgroud)

现在您可以重新启动大使容器,而无需重新启动客户端.

  • 是的,它会的.如果您不想这样,可以使用"-p 172.17.42.1:5432:5432". (2认同)