65.9K
CodeProject 正在变化。 阅读更多。
Home

五种 CI/CD 服务对比结果

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2019年11月12日

CPOL

11分钟阅读

viewsIcon

5988

本文展示了五种 CI/CD 服务的对比结果。

引言

在本系列文章中,我将概述五种不同 CI/CD 服务的对比结果,即:

在此次比较中,我将使用每种服务来运行测试并将一个 Docker 化(Dockerised)的 Node.js 应用程序部署到 AWS Elastic Beanstalk。我将详细介绍如何配置每种服务的 CI/CD 流程,并提供一些性能统计数据来比较这些服务。

测试项目和流程

托管由各种服务测试和部署的项目代码库可以在此处找到。该应用程序是一个小型 Node.js/Express 应用程序,已进行 Docker 化,并包含一个单独的测试。请克隆此应用程序并将其推送到您自己的 Github 代码库,因为我们将在本文中频繁使用它。

对于每种服务的测试遵循的流程如下:

结果

结果可以在下表中看到。我鼓励您按照说明亲自复现这些结果。几点说明:

配置时间是主观的,因为它取决于您对每个工具的熟悉程度。为了透明起见,我已经通过 Buddy 设置了管道,您可以在我的其他博文中看到。也就是说,能够通过可视化方式设置管道可以大大缩短配置时间。

运行时间是从我第一次运行这些管道开始计算的,稍后在本帖的截图中有展示。我欢迎有关如何改进我的运行时间的建议。所有运行时间均来自使用这些服务提供的默认机器。当然,这些可以进行配置,价格比较不在本文的讨论范围之内。

根据我的用例,Buddy 是明显的赢家。由于我不是 DevOps 专家,可视化设置 CI/CD 管道对我非常有吸引力,并且我发现它非常易于配置。Buddy 的运行时间也是最快的,但我猜想人们很快会提出改进我现有管道的建议。不过,Buddy 不如其他服务出名,因此在使用其服务时,您应该仔细审查其产品,然后再选择它而不是竞争对手的服务。

其次,我推荐 AWS CodePipeline,因为它配置起来出奇地简单,这并非我以往使用 AWS 的经验。CodePipeline 与其他 AWS 服务深度集成,这使其功能非常强大。如果您已经重度使用 AWS,我强烈推荐此服务。

我个人发现 Gitlab 在所有服务中最难使用,因为它文档不够完善。Travis 和 CircleCI 的文档都非常完善,如果我没有使用 AWS 或者不能使用像 Buddy 这样的小型公司,我肯定会考虑这些服务。

如果您有任何建议,请评论——我希望能定期更新这一系列文章,加入进一步的优化。如果您不同意我的发现,请告知我。最后,请尝试亲自复现这些结果,并分享您在自己公司中使用这些工具的经验。

方法论

创建 AWS 用户

在本文中,我们需要创建一个 AWS 用户,以便 CI/CD 服务能够以编程方式访问 Elastic Beanstalk。在 IAM 中导航到 IAM 服务。

点击用户

点击添加用户

随意命名您的用户。在此示例中,我将其命名为 CIComparisonBlogUser,并授予他们编程访问权限,然后点击下一步

然后,我们需要为此用户添加策略。点击直接附加现有策略,搜索 AWSElasticBeanstalkFullAccess,附加该策略,然后点击下一步

查看您的用户,并将访问密钥 ID秘密访问密钥保存在安全的位置。这些凭据将在设置每个 CI 服务时使用。

创建 Elastic Beanstalk 应用

我们需要在 Elastic Beanstalk 上创建一个应用程序,所有服务都可以部署到该应用程序。导航到 AWS Elastic Beanstalk,您应该会看到以下启动屏幕。

点击开始使用

为您的应用程序命名(我命名为 CI Comparison Blog),选择 Docker 作为平台,并选择示例应用程序,我们暂时使用它。点击创建应用程序,然后去喝杯咖啡,因为它需要一些时间来启动。

点击提供的URL以查看示例应用程序。

创建 Docker Hub 存储库

所有服务都需要进行的最后一步是创建一个 Docker Hub 存储库。前往 https://hub.docker.com/,登录,您应该会看到以下欢迎屏幕。

点击存储库,然后点击创建存储库

随意命名您的存储库(我命名为 ci-comparison-blog),然后点击创建

您应该会看到您创建的存储库。需要记住的关键部分是您的 andrewbestbier/ci-comparison-blog 的等效项。

设置 CircleCI 管道

要设置 CircleCI 管道,请前往 https://circleci.com/ 并点击使用 Github 登录(您需要通过 Github 授权 CircleCI)。

接下来,点击设置项目,找到您的 Github 存储库(我的名为 ci-comparison-blog),然后点击右侧的设置齿轮

点击环境变量,并添加您的 AWS 和 Docker Hub 凭据(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYDOCKER_USERDOCKER_PASS)。稍后将使用这些。

接下来,点击侧边栏的添加项目,搜索您的 Github 存储库,然后点击设置项目

您将看到一个屏幕,提供有关如何设置项目的说明。最重要的说明是“创建一个名为 .circleci 的文件夹,并添加一个名为 config.yml 的文件”。

如果您查看我们的 Github 存储库,您可以看到我已经创建了这个文件。

version: 2
jobs:
  test:
    working_directory: ~/app
    docker:
      - image: circleci/node:latest # (1)
    steps:
      - checkout
      - run:
          name: Update npm
          command: 'sudo npm install -g npm@latest'
      - restore_cache: # (2)
          key: dependency-cache-{{ checksum "package-lock.json" }}
      - run:
          name: Install npm dependencies
          command: npm install
      - save_cache: 
          key: dependency-cache-{{ checksum "package-lock.json" }}
          paths:
            - ./node_modules
      - run:
          name: Run tests # (3)
          command: 'npm run test'
  docker-deploy-image:
    working_directory: ~/app
    machine:
      docker_layer_caching: true # (4)
    steps:
      - checkout
      - run: | # (5)  
          docker build -t andrewbestbier/ci-comparison-blog .  
          docker login -u $DOCKER_USER -p $DOCKER_PASS
          docker push andrewbestbier/ci-comparison-blog
  deploy-aws:
    working_directory: ~/app
    docker:
      - image: circleci/python:latest
    steps:
      - checkout
      - run: # (6)
          name: Installing deployment dependencies
          working_directory: /
          command: 'sudo pip install awsebcli --upgrade'
      - run: # (7)
          name: Deploying application to Elastic Beanstalk
          command: eb deploy
workflows:
  version: 2
  build-test-and-deploy:
    jobs:
      - test
      - docker-deploy-image:
          requires:
            - test
      - deploy-aws:
          requires:
            - docker-deploy-image

让我们来分析一下构建执行过程中发生的情况。

  1. 第一个作业 test 在 Node Docker 容器中运行。
  2. 如果 node_modules 存在于缓存中,则会恢复,否则会进行安装。
  3. 运行测试。
  4. 启用 Docker 层缓存以提高镜像构建性能(https://circleci.com/docs/2.0/glossary/#docker-layer-caching)。
  5. 接下来,使用 DOCKER_USERDOCKER_PASS 环境变量构建 Docker 镜像并将其推送到 Docker Hub。请记住将存储库更改为您创建的存储库。
  6. 安装 Elastic Beanstalk CLI 工具。
  7. 使用 eb deploy 命令将应用程序部署到 Elastic Beanstalk。此命令有效,因为我们已经通过 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 环境变量在后台由 CircleCI 进行了身份验证。

您可能想知道,eb deploy 是如何知道部署到何处的?要指定位置,您需要修改 Github 存储库中的 .elasticbeanstalk/config.yml 文件,以匹配您创建的示例 Elastic Beanstalk 应用程序。

branch-defaults:
  master:
    environment: CiComparisonBlog-env
environment-defaults:
  CiComparisonBlog-env:
    branch: null
    repository: null
global:
  application_name: CI Comparison Blog
  default_ec2_keyname: null
  default_platform: arn:aws:elasticbeanstalk:eu-west-2::platform/Docker running on
    64bit Amazon Linux/2.12.17
  default_region: eu-west-2
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: null
  sc: git
  workspace_type: Application

要查找您的等效值,请参阅以下截图以及 AWS 文档:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html

我们终于准备好了,所以点击 CircleCI 仪表板上的开始构建,如果一切顺利,您的项目将成功进行测试、构建和部署。

Gitlab

首先,请访问 https://about.gitlab.com/ 并登录。

如果这是您第一次使用 Gitlab,您将看到以下屏幕。点击创建项目

接下来,点击CI/CD for external repo选项卡,然后连接到Github

系统将提示您提供一个具有repo访问权限的 Github 个人访问令牌。为此,请遵循此简短指南:https://help.github.com/en/enterprise/2.17/user/articles/creating-a-personal-access-token-for-the-command-line

接下来,连接您的存储库。

然后,您应该会看到一个显示您的项目详细信息的仪表板。

下一步是添加环境变量。点击侧边栏的设置,然后点击弹出窗口中的CI/CD

向下滚动,并添加您的 AWS 和 Docker Hub 凭据(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYDOCKER_USERDOCKER_PASS)。

下一步是将 .gitlab-ci.yml 文件添加到您的目录根目录。如果您查看 Github 存储库,您会看到以下文件。

image: node:latest # (1)

stages:
  - build
  - test
  - docker-deploy-image
  - aws-deploy

cache:
  paths:
    - node_modules/ # (2)

install_dependencies:
  stage: build
  script:
    - npm install # (3)
  artifacts:
    paths:
      - node_modules/

testing:
  stage: test
  script: npm test # (4)

docker-deploy-image:
  stage: docker-deploy-image
  image: docker:dind
  services:
    - docker:dind
  script:
    - echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin # (5)
    - docker build -t andrewbestbier/ci-comparison-blog .
    - docker push andrewbestbier/ci-comparison-blog

aws-deploy:
  image: 'python:latest'
  stage: aws-deploy
  before_script:
    - 'pip install awsebcli --upgrade' # (6)
  script:
    - eb deploy CiComparisonBlog-env

让我们来分析一下构建执行过程中发生的情况。

  1. 基础镜像是 Node Docker 容器。
  2. node_modules 被缓存。
  3. 安装软件包。
  4. 运行测试。
  5. 接下来,使用 DOCKER_USERDOCKER_PASS 环境变量构建 Docker 镜像并将其推送到 Docker Hub。请记住将存储库更改为您创建的存储库。
  6. 安装 Elastic Beanstalk CLI 工具。
  7. 使用 eb deploy 命令将应用程序部署到 Elastic Beanstalk。此命令有效,因为我们已经通过 AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEY 环境变量在后台由 Gitlab 进行了身份验证。请注意,在此命令中,我们必须指定环境名称。

我们终于准备好了,所以推送一个小的不相关的提交,如果一切顺利,您的项目将成功进行测试、构建和部署。

Travis CI

首先,请访问 https://travis-ci.cn使用 Github 登录

然后,您应该会看到一个显示已连接项目的仪表板。我已经隐藏了其他个人项目。点击小的+按钮添加一个新项目。

接下来,搜索您的 Github 存储库,然后点击设置按钮。

向下滚动,并像其他服务一样,添加您的 AWS 和 Docker Hub 凭据(AWS_ACCESS_KEY_IDAWS_SECRET_ACCESS_KEYDOCKER_USERDOCKER_PASS)。

下一步是将 .travis.yml 文件添加到您的目录根目录。如果您查看 Github 存储库,您会看到以下文件。

language: node_js # (1)
node_js:
  - 'node'
services:
  - docker # (2)
jobs:
  include:
    - stage: test
      script:
        - npm install # (3)
        - npm test # (4)
    - stage: docker-deploy-image # (5)
      script: 
        - echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin 
        - docker build -t andrewbestbier/ci-comparison-blog .
        - docker push andrewbestbier/ci-comparison-blog
    - stage: deploy
      script: skip
      deploy: # (6)
        provider: elasticbeanstalk
        access_key_id: $AWS_ACCESS_KEY_ID
        secret_access_key: $AWS_SECRET_ACCESS_KEY
        region: 'eu-west-2'
        app: 'CI Comparison Blog'
        env: 'CiComparisonBlog-env'
        bucket_name: 'elasticbeanstalk-eu-west-2-094505317841'
        bucket_path: 'CI Comparison Blog'

让我们来分析一下构建执行过程中发生的情况。

  1. 基础镜像是 Node Docker 容器。
  2. 使用 docker 服务,以便稍后可以使用 docker 命令。
  3. 安装软件包(Travis 默认缓存 npm 模块)。
  4. 运行测试。
  5. 接下来,使用 DOCKER_USERDOCKER_PASS 环境变量构建 Docker 镜像并将其推送到 Docker Hub。
  6. 此步骤与其他服务有所不同,因为 Travis 提供了自己的 Elastic Beanstalk 部署方法(而不是使用 CLI)。只需按照 Travis 指定的格式提供 Elastic Beanstalk 配置详细信息,他们将处理其余部分。

我们终于准备好了,所以推送一个小的不相关的提交,如果一切顺利,您的项目将成功进行测试、构建和部署。

Buddy

前往 Buddy 并使用 Github 登录。然后点击创建新项目

Buddy 应该能智能地识别出我们的项目是 Express 应用程序。点击添加新管道

指定一个管道名称(我选择了 CI Blog Post),选择触发器推送时,然后点击添加新管道

然后,我们可以创建一个初始操作来安装我们的依赖项并运行测试。搜索 Node.js 操作并点击它。

系统会提示您输入要运行的 bash 命令。在我们的例子中,我们希望运行 yarn installyarn test。然后点击添加此操作

接下来,我们想从我们的源代码构建一个 Docker 镜像。搜索 Build Image 操作。

Buddy 会自动检测您的 Dockerfile,所以只需点击添加此操作

接下来,我们想将刚刚构建的镜像推送到 Docker Hub。搜索 Push Image 操作。

Buddy 会自动使用上一个操作中构建的镜像。提供您的 Docker Hub 用户名密码存储库标签,然后点击添加此操作

最后,我们想将文件部署到Elastic Beanstalk,所以搜索此操作。

会出现一个模态窗口,要求提供您的 AWS 用户访问密钥秘密访问密钥

选择AWS 区域,您的应用程序将自动出现。然后点击添加此操作

您的管道应如下所示。

点击运行管道,它应该会成功测试、构建和部署您的应用程序。

如果您愿意,您也可以在您的目录中通过 buddy.yml 文件来设置此管道。

- pipeline: "CI Blog Post"
  trigger_mode: "ON_EVERY_PUSH"
  ref_name: "master"
  ref_type: "BRANCH"
  trigger_condition: "ALWAYS"
  actions:
  - action: "Execute: yarn test"
    type: "BUILD"
    working_directory: "/buddy/ci-comparison-blog"
    docker_image_name: "library/node"
    docker_image_tag: "10"
    execute_commands:
    - "yarn install"
    - "yarn test"
    setup_commands:
    - "npm install -g gulp grunt-cli"
    mount_filesystem_path: "/buddy/ci-comparison-blog"
    shell: "BASH"
    trigger_condition: "ALWAYS"
  - action: "Build Docker image"
    type: "DOCKERFILE"
    dockerfile_path: "Dockerfile"
    trigger_condition: "ALWAYS"
  - action: "Push Docker image"
    type: "DOCKER_PUSH"
    login: "andrewbestbier"
    password: "secure!KmF0va9L3z4s450LWVlvNdHi1+6Z6+45vQbkHS4bWFo="
    docker_image_tag: "latest"
    repository: "andrewbestbier/ci-comparison-blog"
    trigger_condition: "ALWAYS"
  - action: "Upload files to Elastic Beanstalk/CI Comparison Blog"
    type: "ELASTIC_BEANSTALK"
    application_name: "CI Comparison Blog"
    environment: "e-zpfbesiqpa"
    environment_name: "CiComparisonBlog-env"
    region: "eu-west-2"
    trigger_condition: "ALWAYS"
    integration_id: 65587

AWS CodePipeline

登录 AWS 并导航到 CodePipeline 服务。然后点击创建管道

接下来,为您的管道命名(我命名为 CI-comparison),然后点击下一步

接下来,您需要添加管道源。选择 Github,按照登录提示操作,连接您的存储库,选择 master 分支,然后点击下一步

然后,我们需要添加构建阶段。选择 AWS CodeBuild 作为构建提供商,然后点击创建项目。这将打开一个新标签页,您将在其中配置构建。

为您的构建命名(我命名为 CI-comparison),然后向下滚动页面。

选择托管镜像、Ubuntu 操作系统、标准运行时和 2.0 镜像。同时启用特权标志,因为我们希望在向下滚动之前构建 Docker 镜像。

接下来,添加 DOCKER_USERDOCKER_PASS 环境变量,然后

选择使用 buildspec 文件,因为我们将在存储库的根目录中使用 buildspec.yml 文件来指定构建步骤。最后,点击继续进行 CodePipeline

选项卡将关闭,您将返回到 CodePipeline 配置。点击下一步

最后,我们需要添加部署阶段。选择 AWS Elastic Beanstalk 作为部署提供商,找到您的应用程序,然后点击下一步

检查您的管道,然后点击创建管道

现在查看我们目录根目录中的 buildspec.yml 文件。

version: 0.2

phases:
  install:
    runtime-versions:
      nodejs: 10 # (1)
    commands:
      - echo "$DOCKER_PASS" | docker login -u "$DOCKER_USER" --password-stdin  # (2)
  pre_build:
    commands:
      - npm install # (3)
      - npm test # (4)
  build:
    commands:
      - docker build -t andrewbestbier/ci-comparison-blog . # (5)
  post_build:
    commands:
      - docker push andrewbestbier/ci-comparison-blog

让我们来分析一下构建执行过程中发生的情况。

  1. 指定了 Node 版本。
  2. 构建会使用环境变量登录到我们的 Docker 账户。
  3. 安装软件包。
  4. 运行测试。
  5. 接下来,构建 Docker 镜像并将其推送到 Docker Hub。

最后,点击发布更改,它应该会成功测试、构建和部署您的应用程序。

历史

  • 2019 年 11 月 11 日:初始发布
© . All rights reserved.