实现多用户的Docker隔离

AMe*_*dis 5 docker kubernetes docker-compose

我被要求为多个用户配置带有 docker 的 ubuntu 18.04 服务器。

目的:我们有多个测试人员编写测试用例。但是我们的笔记本电脑的速度不够快,无法在 docker 环境中构建项目和运行 tescase。我们已经有一个 jenkins 服务器。但是我们需要在推送到 git 之前构建/测试我们的代码。

我得到了一个高端的 ubuntu 18.04 服务器。我必须配置服务器,让我们所有的测试人员都可以在隔离的环境中运行/调试我们的测试用例。

当测试人员将更改推送到远程服务器时,项目应该在隔离的环境中构建和运行。多个用户可以在同一个项目上工作,但一个测试人员的构建不能影响另一个。

我已经安装了 Docker 并尝试仅更改 docker-compose.yml 并添加不同的网络(当然使用多个帐户)。但这是非常痛苦的。

我需要有多个 selenoid 服务器(针对不同的用户),使用 docker 的不同诱惑报告,需要能够使用我们的 docker-compose 文件构建和运行测试,并且需要能够在不同端口上运行实际项目以便我们可以通过编写测试用例的系统。

是否可以在不更改项目 docker-compose.yml 的情况下配置环境?我应该采取什么方法?

Pie*_* B. 5

您可以在 Docker(docker:dind镜像)中使用 Docker 在同一主机上运行多个 Docker 守护程序实例,并让每个测试人员使用不同的DOCKER_HOST来运行他们的 Compose 堆栈。每个应用程序实例都将部署在一个单独的 Docker 守护进程上并被隔离,而无需在docker-compose.yml.

Docker 中的 Docker 可用于从另一个 Docker 守护程序运行 Docker 守护程序。(Docker 守护进程是使用 时实际管理容器的进程docker)。有关详细信息,请参阅Docker 架构DinD 原始博客文章


示例:运行 2 个 Docker 守护进程暴露应用程序端口

让我们考虑 2 个测试人员docker-compose.yml

version: 3
services:
  app:
    image: my/app:latest
    ports:
      - 8080:80
Run Code Online (Sandbox Code Playgroud)
  1. 运行 2 个 Docker Daemon 实例,公开 Daemon 端口和 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
Run Code Online (Sandbox Code Playgroud)
  1. 每个测试人员都可以通过设置DOCKER_HOSTenv 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
Run Code Online (Sandbox Code Playgroud)

dockerd-tester2端口上的测试仪 2 相同:

# Tester 2 shell
export DOCKER_HOST=tcp://localhost:23752
docker-compose up -d
Run Code Online (Sandbox Code Playgroud)
  1. 与测试员 1 和 2 的堆栈交互

需要能够使用我们的 docker-compose 文件构建和运行测试,并且需要能够在不同端口上运行实际项目

每个测试人员的公开端口将在 Docker 守护程序主机上公开,并且可以通过http://$DOCKER_HOST:$APP_PORT而不是访问localhost:$APP_PORT(这就是我们还在每个守护程序上公开应用程序端口的原因)。

考虑到我们的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
Run Code Online (Sandbox Code Playgroud)

我们的部署看起来像这样

在此处输入图片说明


不暴露端口的替代方案,直接使用 Docker 守护进程 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
Run Code Online (Sandbox Code Playgroud)

我们通过它的 IP 直接联系我们的守护进程,而不是在本地主机上公开它的端口。


您甚至可以使用静态 IP 定义您的 Docker 守护进程,docker-compose.yml例如:

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
Run Code Online (Sandbox Code Playgroud)

进而

export DOCKER_HOST=10.5.0.6
# ...
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 这可能会对性能产生一些影响,具体取决于部署守护进程的机器
  • 您可以使用dind-rootless代替dind来避免使用--privileged标志
  • DOCKER_TLS_CERTDIR: ""出于安全原因最好避免,请参阅图像TLS说明docker以了解 TLS 的详细用法