Jenkins部署实践

Jenkins是款流行的CI自动化平台,使用JAVA语言构建,就其定时任务(Build Trigger)而言是传统Crontab理念的拓展,因其部署简单应用比较广泛。

Installation

1. JDK/JRE

Jenkins使用Java构建因此需要JDK/JRE环境部署,Jenkins往往需要对应的Java运行库,因此有可能无法匹配系统发行版Repo默认提供的Java版本,需要直接到Oracle网站下载32/64位对应系统的tar包自行部署到Server

JDK 8u151 Download Page: http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

因服务器系统为64Ubuntu,选择下载jdk-8u151-linux-x64.tar.gz并移至服务器,执行以下命令部署Java环境。

cd /usr/local/java
tar -zxvf jdk-8u151-linux-x64.tar.gz
export JAVA_HOME=/usr/local/java/jdk1.8.0_151
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH
which java
java -version

2. Jenkins Master

访问页面https://jenkins.io/download/下载Jenkins主控程序,与添加Repo安装相比个人更加喜欢直接执行war包的部署方式,在上述页面复制Generic Java Package(.war)的下载链接,随后执行下述命令,可以新建Jenkins的专属服务用户用于启动Jenkins程序,也可以图方便直接使用root账户,这样无需考虑文件系统读写权限配置。

wget http://mirrors.jenkins.io/war/latest/jenkins.war
java -jar jenkins.war

Jenkins的初次启动会在~/.jenkins/路径下部署相应的程序文件并生成初始管理员密码回显在程序log中。

..............
Jenkins initial setup is required. An admin user has been created and a password generated.
Please use the following password to proceed to installation:

b186ed1354ee428db55b2101797fcf83

This may also be found at: /root/.jenkins/secrets/initialAdminPassword
...............

使用地址http://<ip>:8080访问Jenkins GUI

这里写图片描述

使用回显的管理员初始密码继续进入到Jenkins初始插件安装页面,一般选择Install Suggested Plugins,随后进入插件安装状态页面。

这里写图片描述

插件安装完成后在接下来的页面中设置Admin用户名和密码,至此Jenkins Master安装完毕。

这里写图片描述

3. Jenkins Slave/Node

Jenkins支持分布式网络架构,进入Manage Jenkins - Manage Nodes页面,可以看到Jenkins安装完毕后仅有Master自身一台Server在列表中用于承担Build Job

这里写图片描述

可以添加其他Server作为JenkinsSlave/Node承接任务分担Master负载,点击左侧侧边栏New Node在页面Node Name中给Node命名。

这里写图片描述

点击OK后进入Node Configure,主要需要调整的配置项有# of executorsRemote root directoryLaunch method

这里写图片描述

其中Launch method最为重要用来指定在Node远端启动slave.jar程序的方法,因Linux服务器应用的广泛性所以较为通用基于SSH协议的两种Launch方法注释如下:

Launch agent via execution of command on the master:

Starts an agent by having Jenkins execute a command from the master. Use this when the master is capable of remotely executing a process on another machine, e.g. via SSH or RSH.

Launch slave agents via SSH:

Starts a slave by sending commands over a secure SSH connection. The slave needs to be reachable from the master, and you will have to supply an account that can log in on the target machine. No root privileges are required.

a.Launch slave agents via SSH

该方法无需提前将slave.jar部署到Node服务器,仅需配置Node服务器IPLogin Credentials(常用用户名+密码),Jenkins会自动调用sftp传送slave.jarNode并完成该Jar包的启动。

选择Launch slave agents via SSH方法并填入正确的Node Host IP 如下图所示。

这里写图片描述

Credential需点击add在弹出的页面框中填入对应的用户名和密码。

这里写图片描述

随后点击下方save保存Node配置自动返回到Node列表,可以看到新添Node状态为offline

这里写图片描述

点击Node名称在弹出的页面中点击Launch Agent按钮。

这里写图片描述

Jenkins启动slave.jar程序流程如下:

[12/05/17 23:02:25] [SSH] Opening SSH connection to 192.168.19.136:22.
[12/05/17 23:02:25] [SSH] SSH host key matches key in Known Hosts file. Connection will be allowed.
[12/05/17 23:02:25] [SSH] Authentication successful.
[12/05/17 23:02:26] [SSH] The remote user's environment is:
.......
[12/05/17 23:02:26] [SSH] Checking java version of java
[12/05/17 23:02:26] [SSH] java -version returned 1.8.0_151.
[12/05/17 23:02:26] [SSH] Starting sftp client.
[12/05/17 23:02:26] [SSH] Copying latest slave.jar...
[12/05/17 23:02:26] [SSH] Copied 745,674 bytes.
Expanded the channel window size to 4MB
[12/05/17 23:02:26] [SSH] Starting slave process: cd "/root/tmp" && java  -jar slave.jar
<===[JENKINS REMOTING CAPACITY]===>channel started
Remoting version: 3.14
This is a Unix agent
Evacuated stdout
Agent successfully connected and online
......

b.Launch agent via execution of command on the master

该方法需要手动部署slave.jarNode并且需要建立MasterNode SSH的免密验证用于Jenkins最终执行ssh <Node_IP> java -jar /xx/slave.jar以在Node上启动slave程序。

选择Launch agent via execution of command on the master方法,Launch Command中填入执行命令或者执行脚本,只需保证ssh <Node_IP> java -jar /xx/slave.jar命令能最终执行即可。

这里写图片描述

点击下方save并执行Launch AgentJenkins处理流程如下:

[12/05/17 23:21:37] Launching agent
$ ssh root@192.168.19.131 java -jar /home/ce/tmp/slave.jar
<===[JENKINS REMOTING CAPACITY]===>channel started
Slave.jar version: 3.10.2
This is a Unix agent
Evacuated stdout
Agent successfully connected and online

c. ssh免密认证

root@ce-virtual-machine:~# ssh-keygen -t rsa

root@ce-virtual-machine:~# ll ~/.ssh/
total 24
drwx------ 2 root root 4096 Dec  5 23:24 ./
drwx------ 9 root root 4096 Dec  5 21:57 ../
-rw-r--r-- 1 root root  408 Dec  5 15:26 authorized_keys
-rw------- 1 root root 1675 Dec  5 23:24 id_rsa
-rw-r--r-- 1 root root  408 Dec  5 23:24 id_rsa.pub
-rw-r--r-- 1 root root  222 Dec  5 12:31 known_hosts

root@ce-virtual-machine:~# scp ~/.ssh/id_rsa.pub [email protected]:~/.ssh/authorized_keys

Jenkins Build Job

Jenkins Master/Slave部署完成后开始创建Build Job,点击首页New Item进入创建Job页面。

这里写图片描述

Jenkins提供的Job类型按照执行机制大体可以分为Shell-LikePipeline两类,其中PipelineJenkins主推的Job方式,其语法比较适合流程构建并且Jenkins对此构建信息回显提供许多原生支持,可参考https://jenkins.io/doc/pipeline/tour/hello-world/;相比之下应用Shell-Like构建自由风格的Job方式略显原始,但执行更加灵活,在此选择Freestyle Project构建进入如下配置界面。

这里写图片描述

主要配置Build Step, 点击Add build step选择Execute Shell,即可在弹出的Command栏内编写Shell脚本,该脚本会在Trigger Build后依据Jenkins调度在MasterNode上执行。

这里写图片描述

Jenkins还原生支持参数传递,如上图所示的环境变量外在General勾选This project is parameterized并添加相应的变量即可在Shell中调用。

这里写图片描述

shell中添加echo $var1; echo $var2后点击save,然后在页面点击Build with Parameters确认后开始构建,Console Output如下所示。

Started by user ce
Building remotely on test in workspace /root/tmp/workspace/test
[test] $ /bin/sh -xe /tmp/jenkins1445066970670239291.sh
+ echo Start Jenkins Build
Start Jenkins Build
+ pwd
/root/tmp/workspace/test
+ uptime
 14:39:12 up  7:09,  1 user,  load average: 0.01, 0.06, 0.08
+ echo Test Variable 1
Test Variable 1
+ echo Test Variable 2
Test Variable 2
+ echo Simple Build Completed
Simple Build Completed
Finished: SUCCESS

Jenkins CLI

关于CLI可参考https://jenkins.io/doc/book/managing/cli/Jenkins提供了SSH交互接口以及封装HTTP APIJenkins-cli.jarCLI的配置栏在Manage Jenkins - Jenkins CLI

PS: Interactive Scripting

1.实现交互式脚本主要依赖于STDIN接收命令,例如Shell中的read命令,一般使用read -p "Pls input" var等待并将用户敲入的字符串(以回车键结束)赋值给变量var,在实际应用中往往后续程序会检测该变量是否空值如果为空则将默认值赋值于变量,这样可以实现用户通过直接回车使用默认值。

#!/bin/bash
read -p "Input para1 [hello]: " para1
[[ $para1 ]] || para1="hello"
echo $para1
read -p "Input para2 [world]: " para2
[[ $para2 ]] || para2="world"
echo $para2

2.因为交互式脚本的存在就引发出如何让交互式脚本自动化的问题,一般可以使用管道实现,例如实现上例脚本自动化的命令如下。

ce@ce-virtual-machine:~/tmp$ echo -e  "\n\n" | bash ss.sh 
hello
world
ce@ce-virtual-machine:~/tmp$ echo -e  "test\ntest\n" | bash ss.sh 
test
test
ce@ce-virtual-machine:~/tmp$ cat input.data 
test1
test2
ce@ce-virtual-machine:~/tmp$ bash ss.sh < input.data 
test1
test2

3.但是对于sshsu/sudo等因安全性禁止从STDIN读入数据的命令就无法使用管道实现自动输入,为此使用expect工具。

#!/bin/bash
auto_login_ssh () {
expect -c "set timeout -1;
                spawn -noecho ssh -o StrictHostKeyChecking=no $2;
                expect *assword:*;
        send -- $1\r;
        expect *\$*;
        send ifconfig\n;
        send $3\n;
        send exit\n;
        expect eof;
"
}

auto_login_ssh 123 bruce@192.168.19.136 'ls\ -al'

4.对于SSH远程命令免密执行大多通过配置远端信任实现,即将本机公匙填入远端authorized_keys内可实现本机到远端的免密登录。

猜你喜欢

转载自blog.csdn.net/melancholy123/article/details/78724750