【问题标题】:Implement Docker isolation for multiple users为多个用户实现 Docker 隔离
【发布时间】:2021-05-31 18:49:07
【问题描述】:

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

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

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

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

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

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

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

【问题讨论】:

  • 不要尝试在本地构建项目。从 CI 中的分支创建构建,将这些构建推送到 docker hub,然后您的测试人员可以简单地拉取这些图像。然后,您的 docker-compose 可以停止构建并简单地引用要拉取的预构建图像。你让自己的生活变得艰难。试用 gitlab CI,看看一个简单的配置可以对您的工作流程产生什么影响,它带有免费分钟。您会发现这样做的成本远低于您为尝试使此选项“工作”而付出的所有努力">
  • @PaulCollingwood 我们遇到的主要问题是我们无法在笔记本电脑上构建/运行 docker 镜像。这就是我们通过配置一台高端服务器而不是为每个测试人员购买新笔记本电脑来实现的目标。
  • 这不是@PaulCollingwood 所说的。与其购买新的笔记本电脑,不如设置一个自动 CI/CD。 Gitlab 以一种简单的方式允许这样做(也在免费计划中)。 Gitlab 可以从新提交(通过 kubernetes)自动创建环境,测试人员只需使用它们。
  • @akop 我们已经有一个詹金斯服务器。但是我们需要在推送到 git 之前测试我们的代码。这就是我们目前面临的问题。
  • 为什么?当每个人都推送到它自己的分支(谷歌为“git flow”)并使用“merge requets”时,没有理由在测试之前将代码保持在本地。

标签: docker kubernetes docker-compose


【解决方案1】:

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

Docker 中的 Docker 可用于从另一个 Docker 守护进程运行 Docker 守护进程。 (Docker 守护进程是使用docker 时实际管理容器的进程)。详情请参阅Docker architectureDinD original blogpost


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

让我们用这个docker-compose.yml 来考虑 2 位测试人员:

version: 3
services:
  app:
    image: my/app:latest
    ports:
      - 8080:80
  1. 运行 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
  1. 每个测试人员都可以通过设置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. 与测试人员 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

【讨论】:

    【解决方案2】:

    OP 已经运行了 CI/CD 系统。问题是:测试人员如何在自己的环境中编写新的测试用例,而不是在本地机器上运行。

    我建议您在新的“高端”服务器上设置一个 k8s (kubernetes) 实例。当您只有一台服务器(又名节点)时,minikube 的安装非常简单且足够。

    使用 k8s,您可以控制 docker 容器(或使用正确的动词“orchestrate”)。
    接下来您可以执行以下操作之一:

    1. 为测试笔记本电脑编写了一个脚本,以便他们可以启动新环境。您可以使用$USER-变量进行正确命名。请注意,测试人员现在可能可以访问 k8s。
    2. 我的最爱:不要为用户创建环境,而是为合并请求创建环境。它们不受用户约束,可以由您的版本控制系统(例如 gitlab)创建。测试人员可以打开一个 MR,你的服务器设置一个新的环境,测试人员就可以开始了。而且您的测试人员无法访问 k8s。
    3. 不推荐,但可以:为每个测试人员手动创建环境。

    【讨论】:

      猜你喜欢
      • 2021-09-16
      • 2020-12-22
      • 2019-04-17
      • 2015-05-18
      • 1970-01-01
      • 2015-07-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多