您好我正在尝试部署包含相同图像的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
我的猜测是这可能是端口的问题? 这里是播放应用程序的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
有谁知道这里究竟是什么问题?
答案 0 :(得分:1)
ports
如果您不需要API服务器上的端口在Docker 之外响应,则根本不需要指定ports
。图像中的EXPOSE
语句已经存在。您的nginx容器已经可以访问Docker网络中每个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服务器可以与外部网络隔离,从而提高安全性。
同样,这假设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个案例中指定了非暴露的容器端口。
有关详情,请参阅Compose file reference。