为 Jenkins 配置构建从节点

/ 0评 / 0

You know, for Builds.

最近配置了 Archiva 作为公开 Maven 仓库。但是这同时导致了一个问题——我的小服务器最终是承受不住了。一旦开始任何构建,接下来的十分钟服务器就会失去响应。在失去响应这段时间,即使构建成功完成,由于 Archiva 没有分到时间片,Jenkins 也无法向 Archiva 部署成品导致构建失败。(由于等待超时,Nginx 会返回 502, 这也会在 Jenkins 的构建日志中出现。)

那么看来是要部署从节点进行构建,让主节点只负责调度的结构了——这也是 Jenkins 原本的用法。

好在 Jenkins 在设计上的支持,配置从节点并不麻烦。(因为 Jenkins 可以直接通过 SSH 自行设置从节点,而不需要你手动为每个节点写配置文件。不过从从技术上而言密钥也算是配置文件的一种?)

接下来的配置中,以 master $> 打头的为主节点命令行;以 agent $> 打头的为从节点命令行。

创建用户

无论怎样,请不要当 Root 敢死队!为应用程序分配最小必要权限非常重要,至少当应用程序爆出漏洞的时候,你不需要担心这个程序会危害系统的其他部分。

agent $> sudo useradd -d <Jenkins 工作目录> jenkins
agent $> sudo passwd jenkins # 随机密码即可
agent $> sudo -u jenkins -i # 打开 shell 备用

Jenkins 工作目录的典型值是 /var/lib/jenkins, 当然你也可以设置到其他位置。

注意这里必须允许 jenkins 登录,所以没有 chsh 环节。虽然一般而言应用程序账户是不允许登录的,但是考虑到 jenkins 需要执行构建命令,而构建命令又依赖于用户环境,所以需要允许以 jenkins 账户登录。这也是为什么有非常多的熊孩子在试 SSH 密码的时候就对着这些用户名试的原因。

创建 SSH 密钥对

Jenkins 不允许使用密码登录,这是个好事,因为密码登录比起密钥登录不安全太多了。所以我们需要为从机创建 SSH 密钥对。

如果你有多个从机,那么所有从机都可以使用同一个密钥对。如果你觉得这样不安全的话,试问一个密钥泄漏出去了,一群密钥还远么?当然可以说一群密钥需要挨个试才能确定哪个密钥对应哪个从机,但是攻击者可能会聪明到使用脚本干这个事情。况且这是 Jenkins 的密钥,不是开发密钥,所以「不小心上传到 GitHub 还开源了」这种事情就不应该存在吧。总之,不要让密钥泄漏!

在主机上执行命令创建 SSH 密钥对:

master $> ssh-keygen

得到 .ssh/id_rsa.ssh/id_rsa.pub (或者你自己选择的其他文件名). 然后将密钥部署到从节点上:

master $> ssh-copy-id -i ~/.ssh/id_rsa jenkins@<agent-server> 

如果你选择手动复制粘贴公钥的话,创建并编辑 .ssh/authorized_keys:

master $> cat ~/.ssh/id_rsa.pub
ssh-rsa AAA... # 复制输出内容
agent $> mkdir -p ~/.ssh
agent $> vim ~/.ssh/authorized_keys
# 粘贴并保存
agent $> chmod 600 ~/.ssh/authorized_keys
agent $> chmod 700 ~/.ssh
# 设置权限,否则 sshd 会拒绝读取目录,导致之后会出现莫名其妙的 server rejected (1) private key

完成后,测试是否能用该密钥登录。测试同时会产生 .ssh/known_hosts, 将这个文件复制到 Jenkins 的 SSH 配置下并设置正确的权限:

master $> ssh jenkins@<agent-server>
master $> export JENKINS_HOME=/var/lib/jenkins # 此处改成主机上的安装的对应的值
master $> sudo mkdir -p $JENKINS_HOME/.ssh
master $> sudo cp .ssh/known_hosts $JENKINS_HOME/.ssh/
master $> sudo chown -R jenkins $JENKINS_HOME/.ssh
master $> sudo chmod 600 $JENKINS_HOME/.ssh/known_hosts
master $> sudo chmod 700 $JENKINS_HOME/.ssh

之后你可能会希望 jenkins 用户只能通过密钥方式登录,此处不再赘述。

添加从节点

登录 Jenkins, 转到 Manage Jenkins - Manage Nodes and Clouds - New Node 打开创建节点向导;输入新节点的名字并选择 Permanent Agent.

之后会进入详细设定,需要关心的设置项有:

# of executors

这一项决定同时有多少个任务可以运行在该节点上。一般设置为节点的 CPU 核心数,但也可以超设。

Remote root directory

远程根目录,填从机的 jenkins 用户根目录即可。

Labels

从节点标签,这个在之后决定从节点的负载分配方式时需要用。

Usage

负载分配模式,默认为「尽可能使用该节点」。也可选择「仅当标签表达式匹配时使用」。

Launch method

启动方式。此处选择 Launch agent via SSH, 并在 Host 处填写从机地址,在 Credential 处选择 Add 打开凭据添加窗格,Kind 选择 SSH Uesrname with private key 并填写名称、从机的用户名等,在 Private key 处选择 Enter directly 并将主机上的 ~/.ssh/id_rsa 的内容(即私钥)粘贴进去。完成后在 Credential 下拉框选择刚刚添加的凭据。

Availablity

可用性,控制何时启动从节点,默认值为「尽可能一直在线」。也可以选择「定时启用」或者「当有构建任务时启用」。

完成以上配置后保存即可。Jenkins 会自动开始登录远程主机并配置从节点。当从节点配置成功时,其会显示在左侧的 Build executors 栏内并提示 Idle.

禁用主节点构建

仍在 Nodes and Clouds 菜单内,选择 master 节点,并将 # of executors 项设置为 0 并保存。此时任何新的任务将不会再由 master 构建。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

Your comments will be submitted to a human moderator and will only be shown publicly after approval. The moderator reserves the full right to not approve any comment without reason. Please be civil.