使用 Docker 构建

栏目: 服务器 · 发布时间: 6年前

内容简介:使用 Docker 构建

使用 Docker 构建

GitLab CI 允许你使用 Docker Engine 构建和测试基于 Docker 的项目。

这也允许您使用 docker - compose 和其他 docker-enabled 的工具。

持续集成/持续部署的新趋势之一是:

  1. 创建应用程序镜像,
  2. 针对创建的镜像运行测试,
  3. 将镜像推送到远程 Registry,并
  4. 从推送的镜像部署到服务器。

当您的应用程序已经具有可用于创建和测试镜像的 Dockerfile 时,它也很有用:

[crayon-592837dc16763251780303 inline="true"  class="bash"]$ docker build -t my-image dockerfiles/
$ docker run my-docker-image /script/to/run/tests
$ docker tag my-image my-registry:5000/my-image
$ docker push my-registry:5000/my-image

[/crayon]

这需要 GitLab Runner 的特殊配置,以在作业期间启用 docker 支持。

Runner 配置

在作业中有三种方法可以使用 docker build docker run ,每个都有自己的考虑。

使用 Shell 执行器

最简单的方法是在 shell 执行模式下安装 GitLab Runner。然后 GitLab Runner 作为 gitlab - runner 用户执行作业脚本。

  1. 安装 GitLab Runner
  2. 在 GitLab Runner 安装期间,选择 shell 作为执行作业脚本或使用命令的方法:

    [crayon-592837dc1677f360374054 inline="true"  class="bash"]sudo gitlab-ci-multi-runner register -n \
      --url https://gitlab.com/ \
      --registration-token REGISTRATION_TOKEN \
      --executor shell \
      --description "My Runner"
    

    [/crayon]

  3. 在服务器上安装 Docker Engine。

    有关如何在不同系统上安装 Docker Engine 的更多信息,请参阅 Supported installations

  4. 新增 gitlab - runner 用户到 docker 组:

    [crayon-592837dc1678d581765961 inline="true"  class="bash"]sudo usermod -aG docker gitlab-runner
    

    [/crayon]

  5. 验证

    gitlab - runner

    是否可以访问Docker:
    [crayon-592837dc16797404884169 inline="true"  class="bash"]sudo -u gitlab-runner -H docker info
    

    [/crayon]

    现在你可以通过将 docker info 添加到 . gitlab - ci . yml 中来验证一切是否正常:

    [crayon-592837dc167a4437031041 inline="true"  class="yaml"]before_script:
      - docker info
     
    build_image:
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    

    [/crayon]

  6. 现在可以使用 docker 命令,如果需要可以安装 docker - compose

注:

* 通过在 docker 组中添加 gitlab - runner ,你可以有效地授予 gitlab - runner 的完整的 root 权限。有关更多信息,请阅读 On Docker security: docker group considered harmful

使用 docker-in-docker 执行器

第二种方法是使用专门的 Docker 镜像 docker-in-docker(dind),它安装了所有工具( docker docker - compose ),并以特权模式在该镜像的上下文中运行作业脚本。

为了做到这一点,请按以下步骤操作:

  1. 安装 GitLab Runner
  2. 从命令行注册 GitLab Runner 以使用 docker privileged 模式:

    [crayon-592837dc167cd441193319 inline="true"  class="bash"]sudo gitlab-ci-multi-runner register -n \
      --url https://gitlab.com/ \
      --registration-token REGISTRATION_TOKEN \
      --executor docker \
      --description "My Docker Runner" \
      --docker-image "docker:latest" \
      --docker-privileged
    

    [/crayon]

    上面的命令将注册一个新的 Runner 来使用 Docker 所提供的特殊 docker : latest 镜像。 请注意,它使用 privileged 模式启动构建和服务容器。 如果要使用 docker-in-docker 模式,您始终必须在 Docker 容器中使用 privileged = true

    上面的命令将创建一个类似于这个的 config . toml 条目:

    [crayon-592837dc167e2985324318 inline="true" ][[runners]]
      url = "https://gitlab.com/"
      token = TOKEN
      executor = "docker"
      [runners.docker]
        tls_verify = false
        image = "docker:latest"
        privileged = true
        disable_cache = false
        volumes = ["/cache"]
      [runners.cache]
        Insecure = false
    

    [/crayon]

  3. 您现在可以在构建脚本中使用 docker

    (请注意包含

    docker : dind

    服务)
    [crayon-592837dc167ef144978683 inline="true"  class="yaml"]image: docker:latest
     
    # When using dind, it's wise to use the overlayfs driver for
    # improved performance.
    variables:
      DOCKER_DRIVER: overlay
     
    services:
      - docker:dind
     
    before_script:
      - docker info
     
    build:
      stage: build
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    

    [/crayon]

Docker-in-Docker 运行良好,是推荐的配置,但并不是没有挑战:

  • 启用 -- docker - privileged 禁用了容器的所有安全机制,并使你的主机由于特权升级而暴露,从而导致容器突破(主机-容器屏障)。有关更多信息,请查看官方 Docker 文档 Runtime privilege and Linux capabilities
  • 当使用 docker-in-docker 时,每个作业都处于一个干净的环境中,没有过去的历史。并发作业工作正常,因为每个构建都获得自己的 Docker Engine 实例,因此不会相互冲突。但这也意味着作业可能会更慢,因为没有缓存层。
  • 默认情况下, docker : dind 使用 -- storage - driver vfs ,这是最慢的形式。要使用其他驱动程序,请参阅使用 overlayfs 驱动程序。

使用这种方法的示例项目可以在这里找到: https://gitlab.com/gitlab-examples/docker .

Use Docker socket binding

第三种方法是将 / var / run / docker . sock 绑定装载到容器中,以便 docker 在该镜像的上下文中可用。

为了做到这点,遵循以下步骤:

  1. 安装 GitLab Runner .
  2. 从命令行注册 GitLab Runner 以使用 docker 并共享 / var / run / docker . sock

    [crayon-592837dc1680c834533733 inline="true"  class="bash"]sudo gitlab-ci-multi-runner register -n \
      --url https://gitlab.com/ \
      --registration-token REGISTRATION_TOKEN \
      --executor docker \
      --description "My Docker Runner" \
      --docker-image "docker:latest" \
      --docker-volumes /var/run/docker.sock:/var/run/docker.sock
    

    [/crayon]

    上面的命令将注册一个新的 Runner 来使用 Docker 提供的特殊 docker : latest 镜像。 请注意,它正在使用 Runner 本身的 Docker 守护进程,docker 命令产生的任何容器都将是 Runner 的兄弟,而不是所运行程序的子进程。 这可能会有不适合您的工作流程的复杂性和局限性。

    上面的命令将创建一个类似于这个的 config . toml 条目:

    [crayon-592837dc1681a405766012 inline="true" ][[runners]]
      url = "https://gitlab.com/"
      token = REGISTRATION_TOKEN
      executor = "docker"
      [runners.docker]
        tls_verify = false
        image = "docker:latest"
        privileged = false
        disable_cache = false
        volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
      [runners.cache]
        Insecure = false
    

    [/crayon]

  3. 您现在可以在构建脚本中使用 docker

    (请注意,在 Docker 执行器中使用 Docker 时,不需要包含

    docker : dind

    服务):
    [crayon-592837dc16829831249836 inline="true"  class="yaml"]image: docker:latest
     
    before_script:
    - docker info
     
    build:
      stage: build
      script:
      - docker build -t my-docker-image .
      - docker run my-docker-image /script/to/run/tests
    

    [/crayon]

虽然上述方法避免在特权模式下使用 Docker,但您应该了解以下影响:

  • 共享 docker 守护进程,禁用了容器的所有安全机制,并将主机暴露给特权提升,从而导致容器突破屏障。例如,如果一个项目运行 docker rm - f $ ( docker ps - a - q ) ,它将删除 GitLab Runner 容器。
  • 并发作业可能无效;如果你的测试创建了具有特定名称的容器,它们可能会相互冲突。
  • 将文件和目录从源代码库共享到容器中可能无法正常工作,因为卷装载是在主机上下文中完成的,而不是在构建容器中,例如:
    [crayon-592837dc1683d116571021 inline="true" ]docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
    

    [/crayon]

使用 OverlayFS 驱动程序

默认情况下,使用 docker : dind 时,Docker 使用 vfs 存储驱动程序,每次运行时都会拷贝文件系统。磁盘操作非常密集,如果使用不同的驱动程序(例如 overlay ),则可以避免这种情况。

  1. 确保使用最近的内核,最好是 & gt ; = 4.2
  2. 检查

    overlay

    模块是否加载:
    [crayon-592837dc16861671092748 inline="true" ]sudo lsmod | grep overlay
    

    [/crayon]

    如果没有结果,那就没有加载。加载之:

    [crayon-592837dc1686d334243037 inline="true" ]sudo modprobe overlay
    

    [/crayon]

    如果一切顺利,您需要确保在系统重启时也加载该模块。Ubuntu 系统上是通过编辑 / etc / modules 完成的。添加以下行:

    [crayon-592837dc16880144867623 inline="true" ]overlay
    

    [/crayon]

  3. . gitlab - ci . yml

    顶部定义一个变量以使用该驱动:
    [crayon-592837dc16892252317096 inline="true" ]variables:
      DOCKER_DRIVER: overlay
    

    [/crayon]

使用 GitLab 容器 Registry

注:

– 此功能需要 GitLab 8.8 和 GitLab Runner 1.2。

– 从 GitLab 8.12 开始,如果你的帐户启用了两步认证,则需要传递个人访问令牌而不是密码,才能登录到 GitLab 的 Container Registry。

一旦构建了 Docker 镜像,就可以将其推送到内置的GitLab 容器 Registry 中。例如,如果你在 runner 上使用 docker-in-docker,那 . gitlab - ci . yml 可能如下:

[crayon-592837dc1689f983583603 inline="true"  class="yaml"] build:
   image: docker:latest
   services:
   - docker:dind
   stage: build
   script:
     - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.example.com
     - docker build -t registry.example.com/group/project/image:latest .
     - docker push registry.example.com/group/project/image:latest

[/crayon]

必须使用为你创建的特殊 gitlab - ci - token 用户,才能推送到连接到项目的 Registry。它的密码由 $ CI_JOB_TOKEN 变量提供。这允许您自动构建和部署 Docker 镜像。

您也可以利用其他变量来避免硬编码:

[crayon-592837dc168b8321264291 inline="true"  class="yaml"]services:
  - docker:dind
 
variables:
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
 
before_script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
 
build:
  stage: build
  script:
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG

[/crayon]

在这里, $ CI_REGISTRY_IMAGE 将解析为与该项目相关联的 Registry 地址, $ CI_COMMIT_REF_NAME 将解析为该作业所在分支或标签的名称。还声明了我们自己的变量 $ IMAGE_TAG ,将两者结合起来,以节省我们在 script 部分中的输入。

这是一个更详细的例子,将任务分解为 4 个流水线(pipeline)阶段,包括并行运行的两个测试。 build 存储在容器 Registry 中,并在后续阶段使用,需要时则下载该镜像。对 master 的更改也被标记为 latest ,并使用特定于应用程序的部署脚本进行部署:

[crayon-592837dc168ee226130640 inline="true"  class="yaml"]image: docker:latest
services:
  - docker:dind
 
stages:
  - build
  - test
  - release
  - deploy
 
variables:
  CONTAINER_TEST_IMAGE: registry.example.com/my-group/my-project/my-
 
image:$CI_COMMIT_REF_NAME
  CONTAINER_RELEASE_IMAGE: registry.example.com/my-group/my-project/my-image:latest
 
before_script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN registry.example.com
 
build:
  stage: build
  script:
    - docker build --pull -t $CONTAINER_TEST_IMAGE .
    - docker push $CONTAINER_TEST_IMAGE
 
test1:
  stage: test
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker run $CONTAINER_TEST_IMAGE /script/to/run/tests
 
test2:
  stage: test
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker run $CONTAINER_TEST_IMAGE /script/to/run/another/test
 
release-image:
  stage: release
  script:
    - docker pull $CONTAINER_TEST_IMAGE
    - docker tag $CONTAINER_TEST_IMAGE $CONTAINER_RELEASE_IMAGE
    - docker push $CONTAINER_RELEASE_IMAGE
  only:
    - master
 
deploy:
  stage: deploy
  script:
    - ./deploy.sh
  only:
    - master

[/crayon]

使用容器 Registry 的注意事项:

  • 在运行命令之前必须先登录到容器 Registry。把它放在 before_script 里,会在每个作业之前运行它。
  • 使用 docker build -- pull 可以确保 Docker 在构建前获取 base 镜像的任何更改,以防您的缓存失效。这需要运行更长时间,但意味着不会遇到未打安全补丁的 base 镜像。
  • 在每个 docker run 之前做一个明确的 docker pull ,确保获取刚构建的最新镜像。如果您正在使用多个会在本地缓存镜像的 Runner,这一点尤为重要。在镜像标签中使用 git SHA 又使得这不太必要,因为每个作业都将是唯一的,并且您不应该有一个过时的镜像,但是如在依赖更改后,重新构建给定的 Commit,这仍然可能(有过时的镜像)。
  • 同时发生多个作业的情况下,你不会想直接构建为 latest

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

大数据架构商业之路

大数据架构商业之路

黄申 / 机械工业出版社 / 2016-5-1 / 69.00元

目前大数据技术已经日趋成熟,但是业界发现与大数据相关的产品设计和研发仍然非常困难,技术、产品和商业的结合度还远远不够。这主要是因为大数据涉及范围广、技术含量高、更新换代快,门槛也比其他大多数IT行业更高。人们要么使用昂贵的商业解决方案,要么花费巨大的精力摸索。本书通过一个虚拟的互联网O2O创业故事,来逐步展开介绍创业各个阶段可能遇到的大数据课题、业务需求,以及相对应的技术方案,甚至是实践解析;让读......一起来看看 《大数据架构商业之路》 这本书的介绍吧!

JS 压缩/解压工具
JS 压缩/解压工具

在线压缩/解压 JS 代码

随机密码生成器
随机密码生成器

多种字符组合密码

URL 编码/解码
URL 编码/解码

URL 编码/解码