我有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-unit输出,您可以在其中看到其他两个正在正常运行。
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发布于 2015-05-12 23:29:26
这里有几个问题。首先,您不能对docker使用--link参数。这是一个特定于docker的指令,用于将同一docker引擎上的一个容器链接到另一个容器。在您的示例中,您有多个引擎,因此此技术将不起作用。
通常,在云服务中,一个服务需要另一个服务,就像您的情况一样。如果另一个服务(尚未)正在运行,那么需要它的服务应该表现良好,要么退出,要么等待所需的服务准备就绪。因此,必须发现所需的服务。有许多技术可用于发现阶段和等待阶段。例如,您可以在每个容器中编写一个“wrapper”脚本。该包装器可以完成这些任务。在您的示例中,您可以在back.service和graphite.service中使用一个脚本将信息写入etcd数据库,如下所示:
ExecStartPre=/usr/bin/env etcdctl set /graphite/status ready }'然后,在前面的启动脚本中,您可以执行etcdctl get / when /status来查看容器何时准备就绪(并且在准备就绪之前不会继续)。如果您愿意,您可以将ip地址和端口存储在石墨脚本中,以便前端脚本可以选择要连接的位置。
另一种发现技术是使用registrator。这是一个非常方便的docker容器,每当容器来来去去时,它都会更新etcd中的目录结构。这使得使用我上面列出的发现技术变得更容易,而不需要每个容器都声明自己,它变得自动。你仍然需要'front‘容器有一个等待服务出现在etcd数据库中的启动脚本。我通常在coreos启动时启动注册器。实际上,我创建了两个副本,一个用于发现内部地址(法兰绒地址),另一个用于外部地址(在我的容器之外可用的服务)。以下是在我的机器上管理的数据库注册器的示例:
/skydns/net/tacodata/services/cadvisor-4194/fo2:cadvisor:4194 @fo1 ~/prs $ etcdctl ls --递归/skydns/net/tacodata/services/cadvisor-4194/fo1:cadvisor:4194 /skydns/net/tacodata/services/cadvisor-4194/fo3:cadvisor:4194 / /skydns/net /skydns/net/tacodata /skydns/net/tacodata //skydns/net/tacodata/services/cadvisor-4194/fo1:cadvisor:4194 /skydns /net/tacodata//skydns/net/tacodata/services/cadvisor-4194/fo3:cadvisor:4194/cadvisor-4194/skydns/net/tacodata/services/cadvisor-4194/fo2:cadvisor:4194/skydns/net/tacodata/services/cadvisor-4194/fo1:cadvisor:4194/skydns/net/tacodata/services/cadvisor-4194/fo3:cadvisor:4194//skydns/tacodata/ /skydns/net/tacodata/services/internal/cadvisor-4194/fo2:cadvisor:4194 /internal /skydns/net/tacodata/services/internal/cadvisor-4194 /skydns/net/tacodata/services/internal/cadvisor-4194/fo1:cadvisor:4194 /skydns/net/tacodata/services/internal/cadvisor-4194/fo3:cadvisor:4194 /skydns/net/tacodata/services/internal/cadvisor-8080 /skydns/net/tacodata/services/internal/cadvisor-8080/fo2:cadvisor:8080 /skydns/net/tacodata/services/internal/cadvisor-8080/fo1:cadvisor:8080 /skydns/net/tacodata/services/internal/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使用注册者提供的信息提供dns服务。因此,长话短说,我可以简单地让我的应用程序使用主机名(主机名默认为docker映像的名称,但它可以更改)。因此,在这个示例中,我的应用程序可以连接到cadvisor-8080,dns将为它提供它拥有的3个ip地址中的一个(它位于3台机器上)。dns还支持srv记录,因此,如果您使用的不是众所周知的端口,srv记录可以为您提供端口号。
使用coreos和fleet,很难不让容器本身参与到发布/发现/等待游戏中。至少这是我的经验。
-g
https://stackoverflow.com/questions/30192914
复制相似问题