1. 概述
Concourse 是一个使用Go语言开发,开源的CICD系统。
本文我们将学习如何部署安装 Concourse,并演示其基本功能。
2. Concourse 介绍
Concourse 是一个基于流水线 (pipeline) 的自动化持续性集成和部署工具。“Pipeline” 一词在CICD系统中很流行,但Concourse的Pipeline有些不同。Concourse的Pipeline围绕资源(Resource)和作业(Job)构建。Pipeline表达了依赖关系流,类似于分布式的 Makefile 文件,
Resource:如git资源和s3资源用于表达源代码、依赖项、部署以及其他外部状态,还可用于更抽象的内容,比如通过时间资源进行的计划或间隔触发。
资源类型在Pipeline中定义,保持了Concourse的小巧通用性,无需复杂的插件系统。作业由get、put和task步骤组成,决定了作业的输入和输出。作业是幂等的、松散耦合的,可以根据项目需求扩展,而不会增加开发人员的心智负担。
Concourse中的所有操作都在容器中运行。
3. 手动安装 Concourse
Concourse 使用Golang开发,被编译为单个可执行二进制文件,可以轻松地在任何系统上运行。
3.1. 下载 Concourse
使用 wget 从GitHub下载Concourse,请替换 $VERSION 为实际版本号:
$ wget https://github.com/concourse/concourse/releases/download/v$VERSION/concourse-$VERSION-linux-amd64.tgz
然后解压
$ tar -xzf concourse-*-linux-amd64.tgz
解压后的目录结构:
$ tree concourse/
concourse/
├── bin
│ ├── bandwidth
│ ├── bridge
│ ├── concourse
│ ├── containerd
│ ├── containerd-shim
│ ├── containerd-shim-runc-v1
│ ├── containerd-shim-runc-v2
│ ├── containerd-stress
│ ├── ctr
│ ├── dhcp
│ ├── dummy
│ ├── firewall
│ ├── gdn
│ ├── host-device
│ ├── host-local
│ ├── init
│ ├── ipvlan
│ ├── loopback
│ ├── macvlan
│ ├── portmap
│ ├── ptp
│ ├── runc
│ ├── sbr
│ ├── static
│ ├── tap
│ ├── tuning
│ ├── vlan
│ └── vrf
├── fly-assets
│ ├── fly-darwin-amd64.tgz
│ ├── fly-linux-amd64.tgz
│ └── fly-windows-amd64.zip
└── resource-types
[...]
17 directories, 70 files
concourse/bin/ 目录中除了 concourse 可执行文件外,还包含了其他辅助工具。concourse/fly-assets/ 包含了适用于不同平台的 fly 包。resource-types 目录包含了用于不同外部集成(如 git 和 s3)的相关资源类型。
3.2. 部署 concourse 和 fly
现在,我们有了 concourse 可执行文件。
然而,作为主要的配置驱动程序,**fly 也是 Concourse 包的一部分**。所以,我们也部署它:
$ tar -xzf concourse/fly-assets/fly-linux-amd64.tgz
$ chmod +x fly
在这里,我们解压fly。
为了方便使用,建议将 将 concourse/bin/ 和 fly 加到环境变量中去。
3.3. 密钥生成
Concourse 使用密钥进行通信和签名请求。要生成这些密钥,我们可以使用 concourse 的 generate-key 子命令:
$ concourse generate-key --type rsa --filename session_signing_key
wrote private key to ./session_signing.key
$ concourse generate-key --type ssh --filename tsa_host_key
wrote private key to ./tsa_host.key
$ concourse generate-key --type ssh --filename worker_key
wrote private key to ./worker.key
因此,我们现在有三个主要的密钥。
3.4. PostgreSQL 节点
Concourse 使用 PostgreSQL 数据库存储数据:
$ apt-get install postgresql
为了为 Concourse 配置安装,我们应该创建一个特定的 PostgreSQL 用户和数据库:
$ su postgres --command "createuser -P dbaeldung"
Enter password for new role:
Enter it again:
$ su postgres --command "createdb --owner=dbaeldung concoursedb"
在这种情况下,我们使用 su 以 postgres 用户身份运行两个 [–command]s。特别是,我们使用 createuser 与名称 dbaeldung 进行数据库访问。之后,我们 createdb 具有相应所有者的 concoursedb 数据库。
3.5. 配置
由于 Concourse 至少有一个 web 节点和一个连接到它的 worker 节点,我们可以选择是否在同一系统或不同系统上运行两者。然而,每种节点类型都需要自己的参数,我们可以将它们设置为全局 shell 变量或命令行参数。
尽管我们在设置中使用相对路径,但通常最好使用绝对路径。
我们可能需要的绝大多数选项也可以从 https://concourse-ci.org/docker-compose.yml 的 Docker Compose 配置文件中获得。此外,我们可以检查 concouse web –help 和 concourse worker –help 以获取完整列表。
3.6. 配置和启动 web 节点
让我们从 web 节点配置开始:
$ export CONCOURSE_POSTGRES_HOST=127.0.0.1
$ export CONCOURSE_POSTGRES_USER=dbaeldung
$ export CONCOURSE_POSTGRES_PASSWORD=PASSWORD
$ export CONCOURSE_POSTGRES_DATABASE=concoursedb
$ export CONCOURSE_EXTERNAL_URL=http://192.168.6.66:8080
$ export CONCOURSE_ADD_LOCAL_USER=ccbaeldung:PASSWORD
$ export CONCOURSE_MAIN_TEAM_LOCAL_USER=ccbaeldung
$ export CONCOURSE_SESSION_SIGNING_KEY=session_signing_key
$ export CONCOURSE_TSA_HOST_KEY=tsa_host_key
$ export CONCOURSE_TSA_AUTHORIZED_KEYS=authorized_worker_keys
在这里,我们设置预配置的 PostgreSQL 凭证和数据库名称,以及预期的连接 URL。此外,**我们添加一个本地管理用户 ccbaeldung,并将其设置为默认团队 main 的主要用户**。
最后,我们设置会话和 TSA 主机密钥,以及授权密钥文件。这样,web 节点就可以识别自己并设置会话。此外,它可以根据授权密钥决定哪个 worker 可以连接。
所以,让我们运行 web 节点:
$ concourse web
我们应该看到一些没有错误的 JSON 输出,这表明节点已准备好为工人提供服务。当然,大脑需要肌肉。
3.7. 配置和启动 worker 节点
现在,我们转向 worker 节点配置:
$ export CONCOURSE_TSA_HOST=192.168.6.66:8080
$ export CONCOURSE_EXTERNAL_URL=http://192.168.6.66:8080
$ export CONCOURSE_TSA_PUBLIC_KEY=tsa_host_key.pub
$ export CONCOURSE_TSA_WORKER_PRIVATE_KEY=worker_key
$ export CONCOURSE_WORK_DIR=<WORKER_PATH>
当然,每个 worker 只需要知道 web 节点套接字和 URL、其公共 TSA 主机密钥以及要使用的 worker 标识密钥。此外,worker 需要一个本地暂存路径来工作。它为每个步骤存储新的容器,并且必须具有正确的权限。
因此,我们应该能够运行 worker:
$ concourse worker
在这种情况下,我们分别运行 web 和 worker 节点。当守护进程在不同节点上时,这尤其重要。然而,还有另一种选择,主要用于测试。
3.8. 使用 quickstart
为了方便起见,concourse 的 quickstart 选项同时运行 web 和 worker 节点:
$ export CONCOURSE_POSTGRES_HOST=127.0.0.1
$ export CONCOURSE_POSTGRES_USER=dbaeldung
$ export CONCOURSE_POSTGRES_PASSWORD=PASSWORD
$ export CONCOURSE_POSTGRES_DATABASE=concoursedb
$ export CONCOURSE_TSA_HOST=192.168.6.66:8080
$ export CONCOURSE_EXTERNAL_URL=http://192.168.6.66:8080
$ export CONCOURSE_ADD_LOCAL_USER=ccbaeldung:PASSWORD
$ export CONCOURSE_MAIN_TEAM_LOCAL_USER=ccbaeldung
$ export CONCOURSE_WORKER_WORK_DIR=<WORKER_PATH>
$ concourse quickstart
值得注意的是,我们需要设置 CONCOURSE_WORKER_WORK_DIR 作为 quickstart 的 worker 路径,因为 quickstart 的参数名与 concourse 不同 (–worker-work-dir). 然而,由于自动设置,在这种情况下关键配置不是必要的。
然而,不建议在生产环境中使用 quickstart。
无论哪种方式,我们都应该有一个活动的 Web 界面和 worker。
4. 通过 Docker 部署 Concourse
或者,我们可以通过其 Docker 镜像部署 Concourse:
$ curl --remote-name https://concourse-ci.org/docker-compose.yml
$ docker compose up --detach
在这里,我们首先使用 curl 从官方 Concourse 网站获取容器 Docker Compose 文件,并将其与相同名称的 docker-compose.yaml 文件一起本地化。之后,**我们使用 compose 子命令和 docker-compose.yaml 文件来初始化和启动新的 [–detach]ed 容器实例**。
如果我们想通过网络访问而不是仅通过 localhost,我们可以将 CONCOURSE_EXTERNAL_URL 变量更改为指向我们选择的配置 IP 地址或主机名。
此时,应该有两个容器在运行:
- concourse/concourse at 0.0.0.0:8080->8080/tcp
- postgres at 5432/tcp
进一步,我们应该能够从 Web 浏览器访问新的容器部署 http://<HOSTNAME_OR_IP_ADDRESS>:8080。事实上,我们使用这种访问来获取与我们 [arch]itecture 和 platform 相关的相关 Fly 包:
$ curl 'http://xost:8080/api/v1/cli?arch=amd64&platform=linux' --output fly
一旦我们有了 fly 可执行文件,我们可以像以前一样部署它。
无论我们的设置机制如何,我们都应该能够访问 192.168.6.66:8080 或 xost:8080 分别,以我们的 CONCOURSE_MAIN_TEAM_LOCAL_USER 登录,并检查 Concourse 的状态。
5. 演示
为了了解 Concourse 如何帮助我们,让我们通过一个简短的示例。自然,所有步骤都涉及 fly 或 Concourse Web UI。
5.1. 登录
有几种方法可以通过 fly 客户端登录并注册一个目标 web 节点。
例如,我们可以向 –concourse-url 发出 login 子命令,并选择一个目标名称:
$ fly --target=baeltarget login --concourse-url=http://192.168.6.66:8080
logging in to team 'main'
在浏览器中导航到以下 URL:
http://192.168.6.66:8080/login?fly_port=10666
or enter token manually (input hidden):
target saved
访问 URL 并登录后,我们会得到一个令牌,我们可以将其复制回来,以便在给定名称下保存目标。
或者,我们可以通过命令行提供凭据:
$ fly --target=baeltarget login --concourse-url=http://192.168.6.66:8080 --username=ccbaeldung --password=PASSWORD
logging in to team 'main'
target saved
其他选项涉及发送客户端证书。
无论如何,我们应该有一个准备好的目标,其中有一个 worker:
$ fly --target=baeltarget workers
name containers platform tags team state version age
xost 0 linux none none running 2.5 16m56s
一旦我们保存了目标,请求应该很简单。
5.2. 创建Pipeline
与 Docker Compose 类似,Concourse 中的Pipeline只是具有自定义模式的 YAML 文本文件:
$ fly --target=baeltarget set-pipeline --pipeline=baelpipe --config=baelpipe.yaml
jobs:
job job1 has been added:
+ name: job1
+ plan:
+ - config:
+ image_resource:
+ name: ""
+ source:
+ repository: perl
+ type: registry-image
+ platform: linux
+ run:
+ args:
+ - -e
+ - printf "Perl script running...";
+ path: /usr/local/bin/perl
+ task: task1
pipeline name: baelpipe
apply configuration? [yN]: y
pipeline created!
you can view your pipeline here: http://192.168.6.66:8080/teams/main/pipelines/baelpipe
the pipeline is currently paused. to unpause, either:
- run the unpause-pipeline command:
fly -t baeltarget unpause-pipeline -p baelpipe
- click play next to the pipeline in the web ui
在这里,*我们通过其 [–config]uration 文件 baelpipe.yaml 使用 set-pipeline 创建一个新的 –pipeline 名称 baelpipe*。
Pipeline本身只有一个作业 job1 和一个任务 task1。后者设置了一个 perl Docker 镜像并运行一个特定的 Perl 命令。
我们可以看到,一个新的Pipeline默认是暂停的。所以,让我们暂停 baelpipe:
$ fly --target=baeltarget unpause-pipeline --pipeline=baelpipe
unpause 'baelpipe'
准备好Pipeline后,我们可以运行它。
5.3. 运行Pipeline作业
要运行Pipeline,我们可以使用 fly CLI 或 Web UI。
由于 UI 通常更容易并且两者都显示相同的输出,让我们通过命令行完成:
$ fly --target=baeltarget trigger-job --job baelpipe/job1 --watch
started baelpipe/job1 #1
initializing
initializing check: image
selected worker: xost
selected worker: xost
fetching perl@sha256:2fee8a8abdceb3666f59249fd10674ddeadbeefd1b70c04e519bc089d7c21447
1b13d4e1a46e [========================================] 47.3MiB/47.3MiB
1c74667957fc [========================================] 22.9MiB/22.9MiB
30d855666954 [========================================] 61.2MiB/61.2MiB
ad6669181616 [======================================] 201.3MiB/201.3MiB
0ee2b666f83c [==============================================] 136b/136b
69d0a6652e22 [========================================] 15.1MiB/15.1MiB
1d9deafd59b5 [==============================================] 132b/132b
selected worker: xost
running /usr/local/bin/perl -e printf "Perl script running...";
Perl script running...succeeded
因此,我们触发一个 build。每个 build 都是作业的单独运行。
或者,我们可以访问 http://192.168.6.66:8080/teams/main/pipelines/baelpipe/jobs/job1 在 Web UI 中并检查作业及其状态。
5.4. fly 管理
自然,fly 可以协助管理许多其他对象:
- targets
- workers
- teams
- volumes
- pipelines
- jobs
- builds
- cache
- containers
由于其全面的文档,尽管它的多功能性,工具是相当容易使用的。
6. 总结
在这篇文章中,我们深入研究了 Concourse,一个Pipeline管理系统。
总之,在许多用于连续过程自动化的工具中,Concourse 以其简单的部署选项和简约但完整的特性集脱颖而出。