背景
本博客用于记录Jenkins、Docker、K8S、Kurboard的整个安装过程和使用说明;方便博友和自己参考, 目标是以最小的时间成本完成一套系统的搭建。文章记录从无到有的环境搭建,以简单的Demo为例,启发式地介绍整个过程。
Demo的功能和特点如下:
【1】项目以简单的SpringBoot项目为例,并使用Maven构建, 支持jar包可运行;
【2】 由于云服务器为公网地址,所以没必要搭建Nexus仓库,直接使用aliyun仓库;
【3】公有云可直接访问Gitee,因此不搭建Gitlab, 直接使用Gitee代码仓库;
【4】使用Jenkins实现CI/CD, 提交代码后触发自动构建和部署;
【5】以容器化方式(Docker)运行,本地镜像仓库使用Harbor;
【6】 分布式运行,使用K8S镜像容器的编排,使用Kuboard作为控制面板;
1.环境准备:
已准备好3台云服务器(Centos8),规格分别是: 2核8G(230环境), 2核4G(21环境), 2核2G(151环境)
接下来准备服务器环境的搭建:230环境作为主节点,21和151作为从节点;
主节点功能:K8S主节点,Docker镜像仓库,Jenkins流水线;
所以需要的软件有:JDK, Git, Jenkins, Maven, Gradle, Docker, K8S主节点相关软件(包括calico), Kurboard等;
从节点:运行一些服务实例,且被主节点调度;
所需要的软件有:JDK, Docker, K8S从节点相关软件;
1.1 JDK环境安装
【1】在oracle的官网下载JDK8的安装包: https://www.oracle.com/java/technologies/downloads/#java8
#创建java安装目录
mkdir -p /usr/java
#解压缩文件到java安装目录
tar -zxvf jdk-8u333-linux-x64.tar.gz
【2】修改配置文件/etc/profile:
JAVA_HOME=/usr/java/jdk1.8.0_333/
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
执行source /etc/profile, 使得配置生效。
【3】确认JDK是否安装成功:
1.2 git安装
yum install git
查看安装情况
git功能也可以通过Jenkins提供的插件实现,因此不一定需要安装(后续gradle和maven不再单独安装);
1.3 Jenkins安装
本文使用yum方式进行安装,也可以使用war包或者Docker形式进行安装;
【1】配置Jenkins的repo源
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
【2】 通过yum命令安装Jenkins
yum -y install jenkins
【3】修改Jenkins的配置(/etc/init.d/jenkins),配置JDK路径
将实际的JDK地址添加到候选集合中;
或者使用软链接:
ln -s /usr/java/jdk1.8.0_333/bin/java /usr/bin/java
【4】修改 UpdateCenter.xml 的镜像地址,防止启动卡死
#配置文件默认地址: /var/lib/jenkins/hudson.model.UpdateCenter.xml
<sites>
<site>
<id>default</id>
<url>https://mirrors.tuna.tsinghua.edu.cn/jenkins/updates/update-center.json</url>
</site>
</sites>
【4】启动Jenkins
systemctl start jenkins
【5】根据提示输入指向文件的密钥后,执行安装推荐的插件:
1.4 Maven和Gradle
Maven和Gradle本质用于进行项目构建,jenkins提供的插件或者工具中具有该功能,因此环境上不进行安装,通过Jenkins自动下载;
Jenkins中对Maven的配置和使用如下所示:
【1】全局工具配置
配置settings文件(可使用默认配置):
配置Maven版本:
【2】在pipeline中引用该工具
pipeline{
agent any
tools{
maven 'mvn-3.8.6'
}
//...
}
Gradle的使用方式同Maven相同;
2. 案例介绍
本章节内容涉及如何使用Jenkins配置自动打包和部署至本机或远程服务器。
2.1 准备一个SpringBoot的Demo, 支持以jar包形式运行
地址如:https://gitee.com/EwenSeong/spring-application-demo.git
2.2 新建一个流水线任务
新建任务->选择流水线模式 && 输入任务名称后回车, 进入流水线配置页面;
忽略所有配置项,直接选择pipeline,并在流水线的定义中选择pipeline script
pipeline{
agent any
stages {
stage("pre"){
steps{
echo "starting pipeline"
echo "pre success"
}
}
stage("checkout") {
steps{
echo "checkout success"
}
}
stage("build"){
steps{
echo "project build success"
}
}
stage("deploy"){
steps{
echo "project deploy success"
}
}
}
}
上述的流水线提供一个框架:包括环境准备阶段、拉去代码阶段、编译阶段、部署阶段;并没有实现任何功能,后续会对该部分分别进行填充。
2.3 jenkins下载 [Generic Webhook Trigger 插件]
下载插件并重启jenkins后,进入SpringBootDemo任务的配置页面,在pipeline中会出现
勾选Generic Webhook Trigger后,填写token(自定义),用于身份验证:
2.4 进入Gitee: SpringBootDemo项目的管理页面(Gitlab设置页面)
添加WebHook的post链接和密钥:
#url模板为:
http://JENKINS_URL/generic-webhook-trigger/invoke
#需要将JENKINS_URL修改为Gitee或gitlab可以访问的地址
http://172.220.0.100/generic-webhook-trigger/invoke
#同时配置密钥为:sheng
#也可以直接将token配置在url中:
http://172.220.0.100/generic-webhook-trigger/invoke?token=sheng
2.5 在页面上进行测试,同时观察jenkins是否被触发
jenkins的流水线如下图所示:
严谨一点:读者可以再次测试: 提交代码,确认流水线被正常触发
至此:可以实现SpringbootDemo项目有代码提交时,自动触发流水线; 但是此时流水线的执行逻辑为空,接下来需要对内容进行补充;
2.6 添加流水线的执行逻辑添加
本章节内容涉及在流水线加入实际构建和部署步骤:
【1】配置凭证,git据此拉取Gitee代码
在系统管理->管理凭据中新增全局凭证:
Jenkins支持多种类型的凭证,也可以使用secret text以及ssh密钥对等形式,本文使用uname-password形式, 作用范围为全局:
用户名、密码配置Gitee或者Gitlab的登录账号、密码:
ID是自定义字段,全局唯一;后续可以根据该ID进行索引凭证;
配置完成后,如下图所示:
【2】配置checkout拉取代码
在pipeline的checkout阶段按如下进行配置:
stage("checkout") {
steps{
echo "starting checkout..."
script{
checkout $class:'GitSCM',
branches:[[name:"*/jenkins-test"]],
extensions:[],
userRemoteConfigs:[[
credentialsId:"gitee",
url:"https://gitee.com/EwenSeong/spring-application-demo.git"
]]
}
}
}
使用checkout下载远端仓库代码至本地,其中credentialsId的参数是上文配置凭证的ID;
运行完成后,进入工作目录查看项目:
一般任务的工作路径为:[JENKINS_WORKSPACE/JOB_NAME],默认代码会下载到该目录下:
如上图所示,基于Maven构建的SpringBootDemo项目已被下载到工作路径下;
【3】编译和构建
stage("build"){
steps{
sh "mvn clean package -Dmaven.test.skip=true"
}
}
此时触发构建,发现构建失败;因为环境上没有安装maven, 可以通过Tools工具引入mvn[前文已对Maven经过配置];在pipeline中添加tools配置:
tools{
maven 'mvn-3.8.6' #在全局工具配置时-配置maven时的name字段
}
此时触发构建:
发现构建成功;
【4】部署到本机运行
安装[Pipeline Utility Steps]插件,用于读取文件内容:
#【1】在pipeline外部添加环境变量初始化方法:
def initEnv() {
def pom = readMavenPom file: "${_POM_XML}"
_ARTIFACT = pom.artifactId
_VERSION = pom.version
_TARGET_FILE = _ARTIFACT + '-' + _VERSION + '.jar'
}
#【2】添加如下环境变量
environment {
_WORK_SPACE="${env.WORKSPACE}"
_POM_XML = "${_WORK_SPACE}/pom.xml"
_ARTIFACT = ""
_VERSION = ""
_TARGET_FILE = ""
_TARGET_PATH = "${_WORK_SPACE}/target"
_DEPLOY_PATH = "/usr/local/app"
}
#【3】在deploy中加入如下配置:
#预备阶段:读取pom文件,初始化环境配置
stage('prepare') {
steps {
initEnv()
}
}
#部署阶段:拷贝和(重启式)运行
stage('deploy') {
steps {
sh """
mkdir -p \${_DEPLOY_PATH}
echo \${_TARGET_FILE}
cp -fr \${_TARGET_PATH} \${_DEPLOY_PATH}
nohup java -jar \${_DEPLOY_PATH}/\${_TARGET_FILE} >> \${_DEPLOY_PATH}/app.log &
"""
}
}
【5】保持幂等性
流水线反复执行时会不断地创建进程,且由于端口冲突会导致后续进程无法启动,这是因为没考虑将原来的进程杀掉。
可以在deploy地部署前将原进程kill掉:
stage('deploy') {
steps {
sh """
rm -rf ${_DEPLOY_PATH}
PID=\$(ps -ef | grep ${_ARTIFACT} | grep -v grep | awk \'{print \$2}\')
echo \${PID}
if [ ! \${PID} ] ;then
echo "process \${_ARTIFACT} not exist"
else
echo "begin to kill process \${_ARTIFACT}"
kill -9 \$PID
fi
"""
//...
}
}
【6】部署到远程机器
另外,也可以通过[publish over ssh]插件部署到远程机器上:
step 1: 定义remote对象,设置name/host/user/password
step 2: 使用sshPut复制文件到远程
step 3: 使用sshCommand命令操作远程机器;
过程比较简单且生产环境一般不建议使用(后文介绍的使用K8S实现分布式部署),此处读者可自行实现。
2.7 使用Pipeline SCM
流水线构建可以使用 pipeline script 也可以使用 pipeline script from SCM, 后者好处是可以通过代码仓库进行集中维护,而不需要修改所有pipeline的脚本;[可以与项目放在一起,也可以单独新建一个项目用于存放构建相关脚本]
配置如下:
需要注意,Jenkinsfile名字需要与项目中的文件名相同,且位于项目根目录下。