Concourse CI是一个现代的,可扩展的持续集成系统,旨在通过可组合的语法自动化测试管道。由于早期CI系统的成功,Concourse旨在简化管道管理过程并消除“雪花”服务器,以便测试服务器与其处理的代码一样受到监管。
在本教程中,我们将演示如何在Ubuntu 16.04服务器上安装Concourse CI。我们将配置PostgreSQL数据库作为后端,下载并安装Concourse二进制文件,然后配置Web和worker进程以允许我们构建和执行持续集成管道。
要完成本教程,您需要一台至少具有1 GB RAM的Ubuntu服务器,拥有sudo权限的非root用户。没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后在购买服务器。
在我们下载Concourse CI二进制文件之前,我们应该在我们的服务器上设置一个PostgreSQL实例。Concourse将使用PostgreSQL数据库来存储其管道数据。
首先,更新本地程序包索引以刷新可用文件的本地视图。然后,从Ubuntu的默认存储库安装postgresql
和postgresql-contrib
包:
$ sudo apt-get update
$ sudo apt-get install postgresql postgresql-contrib
安装数据库软件后,我们将创建一个专用的PostgreSQL用户concourse
用于管理数据库系统中的Concourse数据。要创建此用户,我们将使用sudo
作为postgres
系统用户,该用户具有对数据库系统的管理访问权限:
$ sudo -u postgres createuser concourse
默认情况下,Concourse尝试连接到名为atc
的数据库。Concourse称其主要网络和API请求为“ATC”,代表“空中交通管制”。我们可以创建此数据库并为concourse数据库用户分配所有权以提供适当的访问权限:
$ sudo -u postgres createdb --owner=concourse atc
有了我们的数据库,我们就可以下载并安装Concourse CI二进制文件了。
Concourse在其网站和GitHub上提供了针对Linux平台的已编译可执行文件的链接。
在Concourse CI下载页面很容易找到它们。在“ 下载”部分的“ Concourse Binaries”部分下,右键单击并复制Linux平台下载的链接位置。保持此页面打开,因为我们待会会用到它。
在服务器上,切换到/tmp
目录,然后使用curl
下载您复制的链接:
$ cd /tmp
$ curl -LO copied_URL_for_concourse_binary
接下来,我们将下载最新的fly
命令行客户端。返回Concourse CI下载页面,在“ 下载”部分的“ Fly 二进制文件”部分下,右键单击并复制Linux平台下载的链接位置。
在服务器上,再次使用curl
下载复制的链接/tmp
:
$ cd /tmp
$ curl -LO copied_URL_for_fly_binary
如果下载请求导致错误,则文件将包含HTTP错误消息而不是二进制程序。键入以下命令检查文件是否为二进制可执行文件:
file *linux_amd64 | grep executable
concourse_linux_amd64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=3f24eae5da950594d8d1aaea7631bc20883afba3, not stripped
fly_linux_amd64: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, not stripped
以上输出表明文件是可执行文件。我们可以为文件添加可执行权限,删除_linux_amd64
后缀,并通过键入以下内容将它们移动到/usr/local/bin
目录:
$ chmod +x concourse* fly*
$ sudo mv concourse* /usr/local/bin/concourse
$ sudo mv fly* /usr/local/bin/fly
询问每个程序的版本将作为一个小的检查,以确保一切正常运行:
$ cd ~
$ concourse --version
$ fly --version
3.0.1
3.0.1
既然我们的二进制文件已经到位,我们就可以开始配置Concourse了。
接下来,我们可以开始整理Concourse将用于启动的配置和密钥。
在开始之前,创建一个配置目录,我们可以保存所有相关文件:
$ sudo mkdir /etc/concourse
我们现在可以生成加密密钥并创建定义Concourse配置的文件。
Concourse由一些相关组件组成,这些组件都需要能够彼此安全地通信。
ATC是处理网络和API请求,并协调管道的主要枢纽。Worker管理容器以运行管道中定义的CI/ CD任务。TSA是一个自定义的SSH服务器,和ATC安全注册workers。
即使我们将在单个服务器上运行所有这些组件,workers和TSA也希望能够安全地进行通信。为了满足这种期望,我们将创建三组密钥:
由于这些组件将在每个组件启动时自动使用,因此我们需要在没有密码的情况下创建这些密钥。我们可以通过输入以下内容在/etc/concours
e目录中创建每个密钥对:
$ sudo ssh-keygen -t rsa -q -N '' -f /etc/concourse/tsa_host_key
$ sudo ssh-keygen -t rsa -q -N '' -f /etc/concourse/worker_key
$ sudo ssh-keygen -t rsa -q -N '' -f /etc/concourse/session_signing_key
如果我们检查汇合目录,我们可以看到现在有三个公钥和三个私钥
ls -l /etc/concourse
total 24
-rw------- 1 root root 1679 May 11 17:19 session_signing_key
-rw-r--r-- 1 root root 394 May 11 17:19 session_signing_key.pub
-rw------- 1 root root 1679 May 11 17:19 tsa_host_key
-rw-r--r-- 1 root root 394 May 11 17:19 tsa_host_key.pub
-rw------- 1 root root 1675 May 11 17:19 worker_key
-rw-r--r-- 1 root root 394 May 11 17:19 worker_key.pub
TSA将通过检查授权密钥文件来决定哪些workers有权连接到系统。我们需要使用我们生成的workers公钥预先填充授权密钥文件,以便它可以成功连接。
由于这是我们唯一的worker,我们可以将文件复制到:
$ sudo cp /etc/concourse/worker_key.pub /etc/concourse/authorized_worker_keys
现在我们有了关键文件和授权workers的初始文件,我们可以创建定义Concourse配置的文件。
Concourse二进制文件本身不从配置文件中读取。但是,它可以从进程启动时传入的环境变量中获取配置值。
稍后,我们将创建systemd
单元文件来定义和管理我们的Concourse服务。单元文件可以从文件中读取环境变量,并在启动时将它们传递给进程。我们将创建一个文件,用于定义Concourse web流程的变量,它启动ATC和TSA组件,以及Concourse worker流程的另一个文件。
键入以下内容为web
流程创建并打开文件:
$ sudo nano /etc/concourse/web_environment
在内部,我们将定义ATC和TSA组件所需的环境变量。每个变量都以CONCOURSE_
开头。
首先,我们将定义一些我们不需要修改的静态值。这些变量将定义私有TSA和会话密钥的位置,定义授权工作者的文件以及PostgreSQL socket 位置:
/ etc /concourse/ web_environment
# These values can be used as-is
CONCOURSE_SESSION_SIGNING_KEY=/etc/concourse/session_signing_key
CONCOURSE_TSA_HOST_KEY=/etc/concourse/tsa_host_key
CONCOURSE_TSA_AUTHORIZED_KEYS=/etc/concourse/authorized_worker_keys
CONCOURSE_POSTGRES_SOCKET=/var/run/postgresql
接下来,我们将设置一些需要更改以匹配环境的变量。该CONCOURSE_EXTERNAL_URL
定义该服务将绑定到的IP地址和端口。将其设置为服务器的公共IP地址和端口8080。
我们还将为main团队设置用户名和密码,该团队用作Concourse管理组。您可以在此处选择您想要的任何用户名和密码。您可以随时通过修改这些值并重新启动服务来更改管理凭据:
/ etc /concourse/ web_environment
# These values can be used as-is
CONCOURSE_SESSION_SIGNING_KEY=/etc/concourse/session_signing_key
CONCOURSE_TSA_HOST_KEY=/etc/concourse/tsa_host_key
CONCOURSE_TSA_AUTHORIZED_KEYS=/etc/concourse/authorized_worker_keys
CONCOURSE_POSTGRES_SOCKET=/var/run/postgresql
# Change these values to match your environment
CONCOURSE_BASIC_AUTH_USERNAME=sammy
CONCOURSE_BASIC_AUTH_PASSWORD=theshark
CONCOURSE_EXTERNAL_URL=http://servers_public_IP:8080
完成后保存并关闭文件。
接下来,为worker进程创建一个环境文件:
sudo nano /etc/concourse/worker_environment
在内部,我们将定义worker私钥的位置,TSA的公钥以及worker存储其文件的目录。我们还将设置可以到达TSA的地址,在我们的例子中将是本地主机。您可以使用以下值而无需修改:
/ etc /concourse/ worker_environment
# These values can be used as-is
CONCOURSE_WORK_DIR=/var/lib/concourse
CONCOURSE_TSA_WORKER_PRIVATE_KEY=/etc/concourse/worker_key
CONCOURSE_TSA_PUBLIC_KEY=/etc/concourse/tsa_host_key.pub
CONCOURSE_TSA_HOST=127.0.0.1:2222
完成后保存并关闭文件。
在我们继续之前,我们应该创建一个专门的Linux用户来运行Concourse web流程。这将允许我们以有限的权限启动面向Web的服务。
由于PostgreSQL默认处理身份验证的方式,因此用户名与我们之前创建的PostgreSQL用户名相匹配非常重要。通过键入以下内容创建一个concourse系统用户和组:
$ sudo adduser --system --group concourse
我们可以通过键入以下内容为新用户提供/etc/concourse
目录及其内容的所有权:
sudo chown -R concourse:concourse /etc/concourse
环境文件包含一些敏感数据,如CI服务器的管理用户名和密码。调整环境文件的权限,以便常规用户无法读取或修改这些文件中的值:
$ sudo chmod 600 /etc/concourse/*_environment
我们的配置资产现在由concourse系统用户拥有,对其他用户具有有限的权限。
我们现在准备定义将启动和管理应用程序进程的Concourse CI单元文件。我们将为web处理TSA和ATC组件的进程创建一个文件,为worker处理管道任务的容器的进程创建一个文件。
首先在/etc/systemd/system
文件中创建一个concourse-web.service
文件:
sudo nano /etc/systemd/system/concourse-web.service
在里面,粘贴以下内容:
/etc/systemd/system/concourse-web.service
[Unit]
Description=Concourse CI web process (ATC and TSA)
After=postgresql.service
[Service]
User=concourse
Restart=on-failure
EnvironmentFile=/etc/concourse/web_environment
ExecStart=/usr/local/bin/concourse web
[Install]
WantedBy=multi-user.target
文件的第一部分设置web
进程的单元描述,并指示在决定启动时应在PostgreSQL单元之后启动该单元。
[Service]
部分定义了服务的运行方式。我们将以我们之前配置的concourse用户身份运行服务,并告诉systemd如果我们失败则自动重启服务,如果流程因内存限制或类似问题而失效,就会起非常大的作用。我们加载之前定义的web_environment
文件来建立环境,然后通过调用concourse
web启动实际过程。
[Install]
部分告诉systemd如果我们将服务配置为在引导时启动,如何将单元绑定到系统启动顺序。
完成后保存并关闭文件。
接下来,打开一个类似的文件来定义worker进程:
$ sudo nano /etc/systemd/system/concourse-worker.service
在里面,粘贴以下内容:
/etc/systemd/system/concourse-worker.service
[Unit]
Description=Concourse CI worker process
After=concourse-web.service
[Service]
User=root
Restart=on-failure
EnvironmentFile=/etc/concourse/worker_environment
ExecStart=/usr/local/bin/concourse worker
[Install]
WantedBy=multi-user.target
该装置的功能与concourse-web装置相似。这一次,我们告诉系统在Concourse web过程开始后启动worker过程。worker进程以root用户身份运行,而不是因为concourse需要容器管理的管理权限。我们加载worker_environment
文件并使用concourse worker命令
启动该过程。
完成后保存并关闭文件。
有了我们的单元文件,我们现在可以允许通过防火墙访问并启动服务。
web进程将侦听端口8080上的连接,因此我们需要打开对ufw防火墙中该端口的访问:
$ sudo ufw allow 8080
worker进程使用的容器需要转发访问权限,以便他们可以正确访问Internet并解析DNS查询。我们可以输入以下命令来启用它
sudo ufw default allow routed
我们现在可以输入以下内容来启动我们
sudo systemctl start concourse-web concourse-worker
我们可以通过键入以下内容来检查两个服
$ sudo systemctl status concourse-web concourse-worker
● concourse-web.service - Concourse CI web process (ATC and TSA)
Loaded: loaded (/etc/systemd/system/concourse-web.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2017-05-11 20:18:16 UTC; 1min 40s ago
Main PID: 9954 (concourse)
Tasks: 7
Memory: 100.0M
CPU: 2.058s
CGroup: /system.slice/concourse-web.service
└─9954 /usr/local/bin/concourse web
May 11 20:19:51 testatc concourse[9954]: {"timestamp":"1494533991.818562269","source":"tsa","message":"tsa.connection.keepalive","log_level":1,"data":{"remote":"127.0.0.1:48764","session":"1","type":"keepalive"}}
. . .
● concourse-worker.service - Concourse CI worker process
Loaded: loaded (/etc/systemd/system/concourse-worker.service; disabled; vendor preset: enabled)
Active: active (running) since Thu 2017-05-11 20:18:16 UTC; 1min 39s ago
Main PID: 9960 (concourse)
Tasks: 9
Memory: 619.6M
CPU: 20.353s
CGroup: /system.slice/concourse-worker.service
└─9960 /usr/local/bin/concourse worker
May 11 20:19:12 testatc concourse[9960]: {"timestamp":"1494533952.909682751","source":"tsa","message":"tsa.connection.channel.forward-worker.heartbeat.start","log_level":1,"data":{"remote":"127.0.0.1:48764","session":"1.1.1.7","worker-address":"127.0.0.1:38993","worker-platform":"linux","worker-tags":""}}
. . .
检查两个服务是否都显示为“active (running)
”,并且日志行不包含任何明显错误。请特别注意web服务,以确保日志行不表示连接到数据库时出现问题。
如果服务成功启动,请启用它们,以便每次服务器启动时它们都会启动:
$ sudo systemctl enable concourse-web concourse-worker
现在Concourse服务正在运行,我们应该检查我们是否有访问权限。
首先,让我们检查一下我们是否可以使用fly命令行客户端访问Concourse服务。
我们必须使用login子命令我们在/etc/concourse/web_environment文件
中配置的管理用户名和密码登录。单个fly二进制文件可用于联系和管理多个Concourse服务器,因此该命令使用称为“目标”的概念作为不同服务器的别名。我们将调用目标“local”来登录本地Concourse服务器:
fly -t local login -c http://127.0.0.1:8080
系统将提示您输入main作为我们在web_environments
文件中设置的团队的用户名和密码。输入凭据后,应显示“目标已保存”:
logging in to team 'main'
username: sammy
password:
target saved
这表明我们能够成功登录。下一步,让我们通过键入以下内容来验证工作进程是否能够成功注册到TSA组件:
fly -t local workers
name containers platform tags team state version
concourse-server 0 linux none none running 1.0
fly
命令用于配置管道和管理Concourse CI服务。该fly help
命令提供有关其他命令的信息。
接下来,通过访问服务器的IP地址:8080,然后在Web浏览器中检查Web访问:
http://servers_public_IP:8080
您应该能够访问初始Concourse CI页面:
从这里,您可以选择将fly命令作为命令行客户端下载到本地计算机,方法是单击与您的平台对应的图像。这使您无需登录服务器即可管理CI环境。请记住提供服务器的公共IP地址,而不是第一次登录fly时的127.0.0.1
(在远程登录之前阅读下面有关加密的警告)。
如果单击右上角的登录链接,则可以登录Web界面。首先,您将被要求选择您的组。主要的组就是管理组,默认情况下是唯一可用的选择:
在下一页上,系统会要求您输入凭据。
警告:Concourse CI提供的Web界面和API网关默认不加密,因此您的用户名和密码将以纯文本形式提交给服务器。如果您计划将此安装用于评估以外的任何其他目的,请在登录前使用SSL保护Web界面。请按照我们关于为Concourse CI设置受SSL保护的Nginx反向代理的说明来配置安全访问。
输入您在web_environment文件中配置的凭据后,您将登录并返回到默认的占位符界面:
使用fly将管道配置提交到服务器后,此屏幕将替换为可监视管道活动的界面。
在本指南中,我们安装了PostgreSQL和Concourse二进制文件,设置了加密密钥,并配置了Concourse和网络访问。启动服务后,我们使用fly命令在本地登录并访问Web界面以确认功能。
要了解如何使用fly向Concourse服务器添加管道,请查看Concourse文档中的示例。
参考文献:《How To Install Concourse CI on Ubuntu 16.04》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。