您可以使用 Docker 中的 Docker(docker:dind 映像)在同一主机上运行多个 Docker 守护程序实例,并让每个测试人员使用不同的 DOCKER_HOST 来运行他们的 Compose 堆栈。每个应用实例都将部署在单独的 Docker 守护程序上并隔离,无需对 docker-compose.yml 进行任何更改。
Docker 中的 Docker 可用于从另一个 Docker 守护进程运行 Docker 守护进程。 (Docker 守护进程是使用docker 时实际管理容器的进程)。详情请参阅Docker architecture 和DinD original blogpost。
示例:运行 2 个暴露应用端口的 Docker 守护进程
让我们用这个docker-compose.yml 来考虑 2 位测试人员:
version: 3
services:
app:
image: my/app:latest
ports:
- 8080:80
- 运行 2 个 Docker 守护程序实例,公开守护程序端口以及将由 Docker Compose 公开的任何端口(原因见下文)
# Run docker dind and map port 23751 on localhost
# Expose Daemon 8080 on 8081 (port that will be used by Tester1)
# privileged is required to run dind (see dind-rootless exists but is experimental)
# DOCKER_TLS_CERTDIR="" is to deploy an unsecure Daemon
# it's easier to use but should only be used for testing/dev purposes
docker run -d \
-p 23751:2375 \
-p 8081:8080 \
--privileged \
--name dockerd-tester1 \
-e DOCKER_TLS_CERTDIR=""
docker:dind
# Second Daemon using port 23752
docker run -d \
-p 23752:2375 \
-p 8082:8080 \
--privileged \
--name dockerd-tester2 \
-e DOCKER_TLS_CERTDIR=""
docker:dind
- 每个测试人员都可以通过设置
DOCKER_HOST env var 在他们的 Docker 守护进程上运行自己的堆栈:
# Tester 1 shell
# use dockerd-tester1 daemon on port 23751
export DOCKER_HOST=tcp://localhost:23751
# run our stack
docker-compose up -d
dockerd-tester2 端口上的测试仪 2 也是如此:
# Tester 2 shell
export DOCKER_HOST=tcp://localhost:23752
docker-compose up -d
- 与测试人员 1 和 2 的堆栈交互
需要能够使用我们的 docker-compose 文件构建和运行测试,并且需要能够在不同端口上运行实际项目
每个测试人员的公开端口将在 Docker 守护程序主机上公开,并且可以通过 http://$DOCKER_HOST:$APP_PORT 而不是 localhost:$APP_PORT 访问(这就是我们还在每个守护程序上公开应用程序端口的原因)。 p>
考虑到我们的docker-compose.yml,测试人员将能够访问以下应用程序:
# Tester 1
# port 8081 is linked to port 8080 of Docker daemon running our app container
# itself redirect on port 8080
# in short: 8081 -> 8080 -> 80
curl localhost:8081
# Tester 2
# 8082 -> 8080 -> 80
curl localhost:8082
我们的部署将如下所示
不暴露端口的替代方案,直接使用Docker daemon IP
与第一个示例类似,您也可以直接使用 Docker 守护进程 IP 与部署的应用程序交互:
# Run daemon without exposing ports
docker run -d \
--privileged \
--name dockerd-tester1 \
-e DOCKER_TLS_CERTDIR=""
docker:dind
# Retrieve daemon IP
docker inspect --format '{{ .NetworkSettings.IPAddress }}' dockerd-tester1
# output like 172.17.0.2
# use it!
export DOCKER_HOST=172.17.0.2
docker-compose up -d
# our app port are exposed on Daemon
curl 172.17.0.2:8080
我们通过它的 IP 直接联系我们的守护进程,而不是在 localhost 上暴露它的端口。
您甚至可以在 docker-compose.yml 中使用静态 IP 定义 Docker 守护程序,例如:
version: "3"
services:
dockerd-tester1:
image: docker:dind
privileged: true
environment:
DOCKER_TLS_CERTDIR: ""
networks:
dind-net:
# static IP to set as DOCKER_HOST
ipv4_address: 10.5.0.6
# same for dockerd-tester2
# ...
networks:
dind-net:
driver: bridge
ipam:
config:
- subnet: 10.5.0.0/16
然后
export DOCKER_HOST=10.5.0.6
# ...
注意事项:
- 这可能会对性能产生一些影响,具体取决于部署守护程序的机器
- 您可以使用
dind-rootless 而不是dind 来避免使用--privileged 标志
- 出于安全原因,最好避免使用
DOCKER_TLS_CERTDIR: "",有关TLS的详细用法,请参阅TLS instruction on docker image