使用docker-compose运行图像的多个实例失败

嗨,我想部署4个docker容器包含相同的图像(这是一个Java Play应用程序)和Nginx应负载平衡这些实例之间。

我的docker-compose文件如下所示:

 version: '2' services: api1: tty: true image: abfalterjakob/play-api ports: - "9000" api2: tty: true image: abfalterjakob/play-api ports: - "9001" api3: tty: true image: abfalterjakob/play-api ports: - "9002" api4: tty: true image: abfalterjakob/play-api ports: - "9003" nginx: image: abfalterjakob/custom_nginx ports: - "80:80" 

运行其中一个API实例工作正常,但每当我试图运行第二个实例崩溃与此错误:

 Starting docker_api2_1 Attaching to docker_api2_1 api2_1 | tandard_init_linux.go:175: exec user process caused "no such file or directory" [recovered] api2_1 | panic: standard_init_linux.go:175: exec user process caused "no such file or directory" api2_1 | api2_1 | goroutine 1 [running, locked to thread]: api2_1 | panic(0x7de000, 0xc82013efc0) api2_1 | /usr/local/go/src/runtime/panic.go:481 +0x3e6 api2_1 | github.com/urfave/cli.HandleAction.func1(0xc82011f2e8) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:478 +0x38e api2_1 | panic(0x7de000, 0xc82013efc0) api2_1 | /usr/local/go/src/runtime/panic.go:443 +0x4e9 api2_1 | github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization.func1(0xc82011ebf8, 0xc82001e038, 0xc82011ed08) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:259 +0x136 api2_1 | github.com/opencontainers/runc/libcontainer.(*LinuxFactory).StartInitialization(0xc8200d0f50, 0x7fa4847fc918, 0xc82013efc0) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/opencontainers/runc/libcontainer/factory_linux.go:277 +0x5b1 api2_1 | main.glob.func8(0xc8200da3c0, 0x0, 0x0) api2_1 | /go/src/github.com/opencontainers/runc/main_unix.go:26 +0x68 api2_1 | reflect.Value.call(0x744b00, 0x8f0ed0, 0x13, 0x839c18, 0x4, 0xc82011f268, 0x1, 0x1, 0x0, 0x0, ...) api2_1 | /usr/local/go/src/reflect/value.go:435 +0x120d api2_1 | reflect.Value.Call(0x744b00, 0x8f0ed0, 0x13, 0xc82011f268, 0x1, 0x1, 0x0, 0x0, 0x0) api2_1 | /usr/local/go/src/reflect/value.go:303 +0xb1 api2_1 | github.com/urfave/cli.HandleAction(0x744b00, 0x8f0ed0, 0xc8200da3c0, 0x0, 0x0) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:487 +0x2ee api2_1 | github.com/urfave/cli.Command.Run(0x83cab8, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8d0420, 0x51, 0x0, ...) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/command.go:191 +0xfec api2_1 | github.com/urfave/cli.(*App).Run(0xc820001680, 0xc820070060, 0x2, 0x2, 0x0, 0x0) api2_1 | /go/src/github.com/opencontainers/runc/Godeps/_workspace/src/github.com/urfave/cli/app.go:240 +0xaa4 api2_1 | main.main() api2_1 | /go/src/github.com/opencontainers/runc/main.go:137 +0xe24 docker_api2_1 exited with code 2 

我的猜测是这可能是端口的问题? 这里是Play应用程序的Dockerfile

 FROM java:8 ADD target /app/target ADD start_script.sh /app WORKDIR /app RUN chmod +x ./start_script.sh CMD ["./start_script.sh"] EXPOSE 9000 

有没有人有一个想法是什么确切的问题在这里?

你可能不需要指定ports

如果您不需要API服务器上的端口在Docker之外响应,则根本不需要指定ports 。 图像中的EXPOSE语句已经存在。 您的nginx容器已经可以在Dockernetworking中的每个API容器上访问9000端口。

您需要将容器链接在一起,以便他们可以沟通

不过,您需要告诉nginx容器链接到其他的容器。 尝试这样的事情:

 version: '2' services: api1: tty: true image: abfalterjakob/play-api api2: tty: true image: abfalterjakob/play-api api3: tty: true image: abfalterjakob/play-api api4: tty: true image: abfalterjakob/play-api nginx: image: abfalterjakob/custom_nginx ports: - "80:80" links: - api1 - api2 - api3 - api4 

现在,您的nginx容器可以使用他们的服务和端口与API服务器通信,例如

 api1:9000 api2:9000 api3:9000 api4:9000 

这还有一个额外的好处,就是你的API服务器与外部networking隔离,这提高了安全性。

同样,这里假设API服务器不应该公开访问,但是应该只能通过nginx代理进行路由。

如果您将端口映射到外部,则必须将内部映射到外部

您正在告诉Docker使用端口9000,9001等,但您的映像只能设置为EXPOSE 9000.要将它们映射到外部,您需要设置外部端口,然后将其映射到内部端口,如下所示:

 version: '2' services: api1: tty: true image: abfalterjakob/play-api ports: - "9000:9000" api2: tty: true image: abfalterjakob/play-api ports: - "9001:9000" api3: tty: true image: abfalterjakob/play-api ports: - "9002:9000" api4: tty: true image: abfalterjakob/play-api ports: - "9003:9000" nginx: image: abfalterjakob/custom_nginx ports: - "80:80" links: - api1 - api2 - api3 - api4 

在你原来的例子中,你只使用一个端口。 这告诉docker-compose使用那个容器端口,但是安排一个随机的主机端口。 如果您已经告诉他们每个人使用端口9000,则将每个容器中的端口9000绑定到随机主机端口。 但是在4个案例中有3个指定了非暴露的集装箱港口。

有关更多信息,请参阅撰写文件参考 。