我在3台机器上运行了3个容器。一种称为石墨,一种称为背面,一种称为前面。前端容器需要运行其他容器,所以我将它们分开链接:
[Unit]
Description=front hystrix
[Service]
TimeoutStartSec=0
ExecStartPre=-/usr/bin/docker kill front
ExecStartPre=-/usr/bin/docker rm -v front
ExecStartPre=/usr/bin/docker pull blurio/hystrixfront
ExecStart=/usr/bin/docker run --name front --link graphite:graphite --link back:back -p 8080:8080 blurio/hystrixfront
ExecStop=/usr/bin/docker stop front
我启动其他容器,等到它们启动并运行,然后用fleetctl启动它,它立即失败并显示以下消息:
fleetctl status front.service
? front.service - front hystrix
Loaded: loaded (/run/fleet/units/front.service; linked-runtime; vendor preset: disabled)
Active: failed (Result: exit-code) since Tue 2015-05-12 13:46:08 UTC; 24s ago
Process: 922 ExecStop=/usr/bin/docker stop front (code=exited, status=0/SUCCESS)
Process: 912 ExecStart=/usr/bin/docker run --name front --link graphite:graphite --link back:back -p 8080:8080 blurio/hystrixfront (code=exited, status=1/FAILURE)
Process: 902 ExecStartPre=/usr/bin/docker pull blurio/hystrixfront (code=exited, status=0/SUCCESS)
Process: 892 ExecStartPre=/usr/bin/docker rm -v front (code=exited, status=1/FAILURE)
Process: 885 ExecStartPre=/usr/bin/docker kill front (code=exited, status=1/FAILURE)
Main PID: 912 (code=exited, status=1/FAILURE)
May 12 13:46:08 core-04 docker[902]: 8b9853c10955: Download complete
May 12 13:46:08 core-04 docker[902]: 0dc7a355f916: Download complete
May 12 13:46:08 core-04 docker[902]: 0dc7a355f916: Download complete
May 12 13:46:08 core-04 docker[902]: Status: Image is up to date for blurio/hystrixfront:latest
May 12 13:46:08 core-04 systemd[1]: Started front hystrix.
May 12 13:46:08 core-04 docker[912]: time="2015-05-12T13:46:08Z" level="fatal" msg="Error response from daemon: Could not get container for graphite"
May 12 13:46:08 core-04 systemd[1]: front.service: main process exited, code=exited, status=1/FAILURE
May 12 13:46:08 core-04 docker[922]: front
May 12 13:46:08 core-04 systemd[1]: Unit front.service entered failed state.
May 12 13:46:08 core-04 systemd[1]: front.service failed.
我还想包括fleetctl list-units输出,你可以看到其他两个输出没有问题。
fleetctl list-units
UNIT MACHINE ACTIVE SUB
back.service 0ff08b11.../172.17.8.103 active running
front.service 69ab2600.../172.17.8.104 failed failed
graphite.service 2886cedd.../172.17.8.101 active running
答案 0 :(得分:0)
这里有几个问题。首先,你不能使用docker的--link参数。这是一个特定于docker的指令,用于在相同的docker引擎上将一个容器链接到另一个容器。在你的例子中,你有多个引擎,所以这种技术不会起作用。如果你想使用这种技术,你将需要使用大使模式:coreos ambassador,你可以使用X-Fleet指令MachineOf:使所有的docker容器在同一台机器上运行,但是,我认为这会打败你的目标。
通常,对于云服务,一项服务需要另一项服务,就像您的情况一样。如果其他服务尚未运行,那么需要它的服务应该表现良好并退出,或者等待所需服务准备就绪。因此必须发现所需的服务。发现阶段和等待阶段有许多技术。例如,您可以编写一个'包装器'每个容器中的脚本。包装器可以完成这些任务。在您的情况下,您可以在back.service和graphite.service中创建一个脚本,该脚本将信息写入etcd数据库,如:
ExecStartPre=/usr/bin/env etcdctl set /graphite/status ready }'
然后在前面的启动脚本中,您可以执行etcdctl get / graphite / status以查看容器何时准备就绪(并且直到容器才会继续)。如果您愿意,可以将IP地址和端口存储在graphite脚本中,以便前端脚本可以选择要连接的位置。
另一种发现技术是使用registrator。这是一个超级方便的docker容器,每次容器进出时都会更新etcd中的目录结构。这使得使用像我上面列出的发现技术更容易,而不必让每个容器都宣布自己,它变得自动化。你还需要前面的'容器有一个启动脚本,等待服务出现在etcd数据库中。我通常在coreos启动时启动registrator。实际上,我开始创建两个副本,一个用于发现内部地址(法兰绒),另一个用于外部(在我的容器外可用的服务)。以下是registrator在我的机器上管理的数据库示例:
core @ fo1~ / prs $ etcdctl ls --recursive / skydns / skydns /净 / skydns /网/ tacodata / skydns / NET / tacodata /服务 / skydns / NET / tacodata /服务/ cadvisor-4194 / skydns / NET / tacodata /服务/ cadvisor-4194 / Fo 2:cadvisor:4194 / skydns / NET / tacodata /服务/ cadvisor-4194 / FO1:cadvisor:4194 / skydns / NET / tacodata /服务/ cadvisor-4194 / FO3:cadvisor:4194 / skydns / NET / tacodata /服务/内部 / skydns / NET / tacodata /服务/内部/ cadvisor-4194 / skydns / NET / tacodata /服务/内部/ cadvisor-4194 / Fo 2:cadvisor:4194 / skydns / NET / tacodata /服务/内部/ cadvisor-4194 / FO1:cadvisor:4194 / skydns / NET / tacodata /服务/内部/ cadvisor-4194 / FO3:cadvisor:4194 / skydns / NET / tacodata /服务/内部/ cadvisor-8080 / skydns / NET / tacodata /服务/内部/ cadvisor-8080 / Fo 2:cadvisor:8080 / skydns / NET / tacodata /服务/内部/ cadvisor-8080 / FO1:cadvisor:8080 / skydns /净/ tacodata /服务/内/ cadvisor-8080 / FO3:cadvisor:8080
您可以看到cadvisor的内部和外部可用端口。如果我得到其中一条记录:
etcdctl get /skydns/net/tacodata/services/internal/cadvisor-4194/fo2:cadvisor:4194
{"host":"10.1.88.3","port":4194}
您可以获得在内部连接到该容器所需的一切。当与skydns结合时,这种技术真的开始闪耀。 Skydns使用registrator提供的信息提供dns服务。所以,长话短说,我可以简单地让我的应用程序使用主机名(主机名默认为docker镜像的名称,但可以更改)。所以在这个例子中,我的应用程序可以连接到cadvisor-8080,而dns将为它提供3个ip地址中的一个(它在3台机器上)。 dns还支持srv记录,因此,如果您没有使用熟知的端口,则srv记录可以为您提供端口号。
使用coreos和fleet很难不让容器本身参与发布/发现/等待游戏。至少那是我的经历。
-g