如何构建Docker镜像并使用Gi​​tLab托管Docker镜像库

容器化正在迅速成为在云环境中打包和部署应用程序的最被接受的方法。它提供的标准化,以及其资源效率(与完整的虚拟机相比)和灵活性,使其成为一个伟大的推动因素......

介绍

容器化正在迅速成为在云环境中打包和部署应用程序的最被接受的方法。 它提供的标准化以及其资源效率(与完整虚拟机相比)和灵活性使其成为现代DevOps思维模式的强大推动力。 当您的应用程序和微服务完全容器化时,许多有趣的云本地部署,编排和监控策略成为可能。

Docker容器是目前最常用的容器类型。 尽管像Docker Hub这样的公共Docker镜像仓库充满了您可以在今天使用Docker并使用的容器式开源软件镜像,但您需要私有代码来支付服务来构建和存储图像,或者运行自己的软件以这样做。

GitLab Community Edition是一个自托管软件套件,提供Git存储库托管,项目跟踪,CI / CD服务以及Docker映像注册表等功能。 在本教程中,我们将使用GitLab的持续集成服务从示例Node.js应用程序构建Docker镜像。 这些图像将被测试并上传到我们自己的私人Docker注册表中。

先决条件

在开始之前,我们需要设置一个安全的GitLab服务器一个GitLab CI运行器来执行持续集成任务。 以下部分将提供链接和更多详细信息。

一个使用SSL进行安全保护的GitLab服务器

为了存储我们的源代码,运行CI / CD任务并托管Docker注册表,我们需要在Ubuntu 16.04服务器上安装GitLab实例。 GitLab目前推荐使用至少2个CPU内核和4GB内存的服务器

您可以通过以下教程完成这些先决条件要求:

另外,我们将使用来自Let's Encrypt的SSL证书来保护服务器。 为此,您需要一个指向服务器的域名:

一个GitLab CI Runner

如何在Ubuntu 16.04上使用GitLab CI设置持续集成管道将为您提供GitLab CI服务的概述,并向您展示如何设置CI runner来处理作业。 我们将在本教程中创建的演示应用程序和运行器基础结构之上进行构建。

第1步 - 设置特权GitLab CI亚军

在必备的GitLab持续集成教程中,我们使用sudo gitlab-runner register及其交互式配置过程设置了一个GitLab运行器。 该跑步者能够在隔离的Docker容器内运行软件的构建和测试。

但是,为了构建Docker镜像,我们的运行者需要完全访问Docker服务本身。 推荐的配置方式是使用Docker官方的docker-in-docker镜像来运行作业。 这要求授予跑步者一个特殊的privileged执行模式,所以我们将创建一个启用此模式的第二跑步者。

注意:授予runner 特权模式基本上禁用了使用容器的所有安全优势。 不幸的是,支持Docker的跑步者的其他方法也带有类似的安全隐患。 请查看Docker Build官方GitLab文档 ,了解更多关于不同跑步选项的信息,以及哪种最适合您的情况。

因为使用特权跑步者有安全隐患,所以我们将创建一个项目特定的跑步者,它只接受我们的hello_hapi项目中的Docker作业(GitLab管理员可以随时手动将此跑步者添加到其他项目中)。 在您的hello_hapi项目页面中,单击左侧菜单底部的设置 ,然后在子菜单中单击CI / CD

GitLab项目设置菜单

现在点击跑步者设置部分旁边的展开按钮:

GitLab“跑步者设置”展开按钮

会有一些关于设置特定跑步者的信息 ,包括注册令牌。 记下这个令牌。 当我们使用它来注册一个新的跑步者时,跑步者只会被锁定到这个项目。

GitLab项目特定的跑步者选项

当我们在这个页面上时,点击禁用共享运行程序按钮。 我们希望确保我们的Docker作业始终运行在我们的特权运行器上。 如果一个非特权的共享运行器可用,GitLab可能会选择使用该运行器,这会导致构建错误。

登录到具有您当前的CI运行器的服务器。 如果您尚未安装机器,请返回并完成安装GitLab CI Runner服务
在继续之前,先决条件教程的一部分。

现在,运行以下命令来设置特权项目特定的runner:

sudo gitlab-runner register -n \
  --url https://gitlab.example.com/ \
  --registration-token your-token \
  --executor docker \
  --description "docker-builder" \
  --docker-image "docker:latest" \
  --docker-privileged
Registering runner... succeeded                     runner=61SR6BwV
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

一定要替换你自己的信息。 我们在命令行中设置了所有的runner选项,而不是使用交互式提示,因为提示不允许我们指定--docker-privileged模式。

你的跑步者现在已经建立,注册并且正在运行。 要验证,请切换回您的浏览器。 点击主GitLab菜单栏中的扳手图标,然后点击左侧菜单中的Runners 你的选手将被列出:

GitLab亚军列表

现在我们有了一个能够构建Docker镜像的跑步者,让我们设置一个私人Docker注册表来将它推送到。

第2步 - 设置GitLab的Docker注册表

通过设置自己的Docker注册表,您可以从自己的专用服务器上推送和提取图像,从而提高安全性并减少工作流对外部服务的依赖性。

GitLab将设置一个私人Docker注册表,只需进行一些配置更新。 首先,我们将设置注册管理机构所在的URL。 然后,我们将(可选)配置注册表以使用S3兼容对象存储服务来存储其数据。

SSH到你的GitLab服务器,然后打开GitLab配置文件:

sudo nano /etc/gitlab/gitlab.rb

向下滚动到容器注册表设置部分。 我们将取消registry_external_url行并将其设置为端口号为5555我们的GitLab主机名:

/etc/gitlab/gitlab.rb
registry_external_url 'https://gitlab.example.com:5555'

接下来,添加以下两行来告诉注册表在哪里可以找到我们的加密证书:

/etc/gitlab/gitlab.rb
registry_nginx['ssl_certificate'] = "/etc/letsencrypt/live/gitlab.example.com/fullchain.pem"
registry_nginx['ssl_certificate_key'] = "/etc/letsencrypt/live/gitlab.example.com/privkey.pem"

保存并关闭文件,然后重新配置GitLab:

sudo gitlab-ctl reconfigure
. . .
gitlab Reconfigured!

更新防火墙以允许流量到注册表端口:

sudo ufw allow 5555

现在切换到安装了Docker的另一台机器,并登录到私有Docker注册表。 如果您的本地开发计算机上没有Docker,则可以使用设置的任何服务器来运行您的GitLab CI作业,因为它已经安装了Docker:

docker login gitlab.example.com:5555

系统会提示您输入用户名和密码。 使用您的GitLab凭据登录。

Login Succeeded

成功! 注册表已建立并正在运行。 目前它会将文件存储在GitLab服务器的本地文件系统上。 如果您想使用对象存储服务,请继续本节。 如果不是,请跳至第3步。

要为注册表设置对象存储后端,我们需要知道关于对象存储服务的以下信息:

  • 访问密钥
  • 密钥
  • 例如,如果使用Amazon S3,则使用Regionus-east-1 );如果使用S3兼容服务,则使用Region Endpointhttps://nyc.digitaloceanspaces.com
  • 存储桶名称

如果您使用DigitalOcean Spaces,您可以通过阅读如何创建DigitalOcean空间和API密钥来了解如何设置新空间并获取上述信息。

当你有你的对象存储信息时,打开GitLab配置文件:

sudo nano /etc/gitlab/gitlab.rb

再次向下滚动到容器注册表部分。 查找registry['storage']块,取消注释,并将其更新为以下内容,并再次确保在适当的情况下替换自己的信息:

/etc/gitlab/gitlab.rb
registry['storage'] = {
  's3' => {
    'accesskey' => 'your-key',
    'secretkey' => 'your-secret',
    'bucket' => 'your-bucket-name',
    'region' => 'nyc3',
    'regionendpoint' => 'https://nyc3.digitaloceanspaces.com'
  }
}

如果您使用的是Amazon S3,则只需要region而不是regionendpoint 如果您使用Spaces等S3兼容服务,则需要使用regionendpoint 在这种情况下, region并不实际配置任何内容,并且您输入的值不重要,但它仍然需要存在而不是空白。

保存并关闭文件。

注意:目前存在一个错误,如果您的对象存储桶为空,注册表将在三十秒后关闭。 为避免这种情况,请在运行下一步之前在文件夹中放入一个文件。 您可以稍后在注册表添加自己的对象后将其删除。

如果您正在使用DigitalOcean Spaces,则可以使用控制面板界面进行拖放以上载文件。

重新配置GitLab一次:

sudo gitlab-ctl reconfigure

在您的其他Docker机器上,再次登录到注册表以确保一切正常:

docker login gitlab.example.com:5555

你应该得到一个Login Succeeded消息。

现在我们已经设置了Docker注册表,让我们更新应用程序的CI配置,以构建和测试我们的应用程序,并将Docker映像推送到我们的私有注册表。

第3步 - 更新gitlab-ci.yaml并构建Docker镜像

注意:如果您没有完成关于GitLab CI先决条件文章,您需要将示例存储库复制到您的GitLab服务器。 遵循从GitHub部分复制示例存储库部分来执行此操作。

为了在Docker中构建我们的应用程序,我们需要更新.gitlab-ci.yml文件。 您可以在GitLab中通过在主项目页面中单击该文件,然后单击编辑按钮来编辑该文件。 或者,您可以将repo克隆到本地计算机,编辑文件,然后将git push回到GitLab。 这看起来像这样:

git clone git@gitlab.example.com:sammy/hello_hapi.git
cd hello_hapi
# edit the file w/ your favorite editor
git commit -am "updating ci configuration"
git push

首先,删除文件中的所有内容,然后粘贴以下配置:

.gitlab-ci.yml
image: docker:latest
services:
- docker:dind

stages:
- build
- test
- release

variables:
  TEST_IMAGE: gitlab.example.com:5555/sammy/hello_hapi:$CI_COMMIT_REF_NAME
  RELEASE_IMAGE: gitlab.example.com:5555/sammy/hello_hapi:latest

before_script:
  - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN gitlab.example.com:5555

build:
  stage: build
  script:
    - docker build --pull -t $TEST_IMAGE .
    - docker push $TEST_IMAGE

test:
  stage: test
  script:
    - docker pull $TEST_IMAGE
    - docker run $TEST_IMAGE npm test

release:
  stage: release
  script:
    - docker pull $TEST_IMAGE
    - docker tag $TEST_IMAGE $RELEASE_IMAGE
    - docker push $RELEASE_IMAGE
  only:
    - master

确保使用您自己的信息更新突出显示的URL和用户名,然后使用GitLab中的提交更改按钮进行保存。 如果您要更新GitLab以外的文件,请提交更改并将git push回到GitLab。

这个新的配置文件告诉GitLab使用最新的docker镜像( image: docker:latest )并将其链接到docker-in-docker服务(docker:dind)。 然后定义buildtestrelease阶段。 build阶段使用Dockerfile提供的Dockerfile构建Docker镜像,然后将其上传到Docker镜像注册表。 如果成功, test阶段将下载我们刚刚构建的镜像,并在其中npm test命令。 如果测试阶段成功,则release阶段将拉取图像,将其标记为hello_hapi:latest并将其推回注册表。

根据您的工作流程,您还可以添加额外的test阶段,甚至可以deploy将应用程序推送到分段或生产环境的阶段。

更新配置文件应该触发了一个新的版本。 返回到GitLab中的hello_hapi项目,然后单击CI状态指示器进行提交:

GitLab使用管道状态图标提交通知

在结果页面上,您可以点击任何阶段查看进度:

GitLab管道细节

GitLab流水线阶段进展

最终,所有阶段都应通过显示绿色复选标记图标表明他们已成功。 我们可以通过单击左侧菜单中的注册表项来找到刚构建的Docker镜像:

GitLab容器注册表图像列表

如果您单击图像名称旁边的小“文档”图标,它会将相应的docker pull ...命令复制到剪贴板。 然后您可以拉动并运行您的图像:

docker pull gitlab.example.com:5555/sammy/hello_hapi:latest
docker run -it --rm -p 3000:3000 gitlab.example.com:5555/sammy/hello_hapi:latest
> hello@1.0.0 start /usr/src/app
> node app.js

Server running at: http://56fd5df5ddd3:3000

该图像已从注册表中拉出并在容器中启动。 切换到您的浏览器并连接到端口3000上的应用程序进行测试。 在这种情况下,我们在本地机器上运行容器,所以我们可以通过本地主机通过以下URL访问它:

http://localhost:3000/hello/test
Hello, test!

成功! 您可以用CTRL-C停止容器。 从现在起,每当我们将新代码推送到我们存储库的master分支时,我们都会自动构建并测试新的hello_hapi:latest映像。

结论

在本教程中,我们设置了一个新的GitLab运行器来构建Docker镜像,创建一个私有Docker注册表来存储它们,并更新一个Node.js应用程序,以便在Docker容器内部进行构建和测试。

要了解有关此设置中使用的各种组件的更多信息,请阅读GitLab CEGitLab Container RegistryDocker的官方文档。


分享按钮