1 概述

项目前期部署都是手动部署,所以相关工具基本都已经安装,主要使用的工具有:

使用Gitlab管理代码
使用Maven打包
使用Docker构建镜像(已经有相关的DockerFile文件)
在阿里云kubernetes上部署。

所以,在这次自动化部署过程中,需要做的是安装Jenkins并完成相关配置,然后通过流水线脚本(Pipeline Script)将整个部署过程粘合起来。

因此本文不涉及Maven和Docker等工具的安装部署,仅记录部署过程中Jenkins相关配置和流水线脚本设计。

2 部署Jenkins

1)安装包下载:Jenkins下载地址:Download | Jenkins
在这里插入图片描述
2)将文件上传到安装目录下,然后路径切换到该目录下,进行安装

rpm -ivh jenkins-2.386-1.1.noarch.rpm

3)在/etc/init.d/jenkins文件中配置JDK信息,保证有 $JAVA_HOME/bin/java信息即可在这里插入图片描述

3)启动程序

systemctl start Jenkins

注意:Jenkins默认的端口是8080,如果存在端口冲突,可以在启动前修改 /etc/sysconfig/jenkins文件中JENKINS_PORT信息
在这里插入图片描述

4)在浏览器中访问,可以正常打开即部署成功。然后通过提示信息,查看初始密码,复制进去即可登录,然后选择安装推荐插件,或者自定义要安装的插件,或者直接跳过插件安装均可。本次安装采用的是安装推荐插件。

其他说明:

  • 注意根据不同的系统下载不同的版本,Linux版本查看和版本关系可网上搜索
  • 部署Jenkins也可以通过Docker方式,但在 RedHat 系列(RHEL、CentOS、Fedora 等)的 Linux 通过Docker部署Jenkins后,在Jenkins脚本中运行 docker命令时会因为 SELinux 而报错 docker: not found(有资料说可以通过安装selinux-dockersock 【GitLab地址】解决,但是我安装后还是报错,因此就放弃了使用docker部署Jenkins)。另外使用Docker部署Jenkins,因为容器内无法直接访问本机的资源,需要提前规划好资源挂载,然后在Docker中做好环境变量配置,或者在Docker容器内重新部署新的工具,如Maven。总之使用Docker部署Jenkins会遇到较多问题,建议对Docker不熟悉的话,不要使用Docker进行部署。
  • 在部署完成后,启动Jenkins后没有找到初始密码文件,于是把Jenkins卸载后,重新进行了部署。【可参考文章】。
  • 本文的部署过程较为简略,不同的环境部署中可能会遇到不同的问题,可以通过查阅其他的资料解决。【可参考文章

3 配置Jenkins

3.1 配置Gitlab的免密访问

1. 首先在Jenkins部署的服务器上生成密钥:
因为jenkins是使用jenkins用户运行的,使用root用户生成ssh密钥的话会可能会导致Jenkins没有访问权限导致出现 stderr: Host key verification failed的问题,所以先切换到jenkins用户下,生成ssh密钥

su -s /bin/bash jenkins
ssh-keygen -t rsa

2. 复制生成的公钥到Gitlab
使用命令cat .ssh/id_rsa.pub,查看公钥内容,并将内容复制过去,点击Add key完成新增。
在这里插入图片描述
3. 复制私钥到Jenkins
使用命令cat .ssh/id_rsa,查看私钥内容,并将内容复制到Jenkins的凭据中,见下图。注意复制私钥的内容要完整,需要包含前后-------的两行内容
在这里插入图片描述
在这里插入图片描述

ID可手动填写,也可不填写,不填写时系统会自动生成。
Username即凭据名称,可手动填写,也可不填写,系统默认是登录用户名。

4. 以上配置完成后,还需要一个步骤,避免Jenkins第一次访问Gitlab失败。这里有2个方法可以,选择其一即可。

  • 第一个方法:
    在linux上手动访问一下Gitlab,使用命令见下
git ls-remote -h git@####.git HEAD

注意:git@####.git为自己仓库地址,第一次运行时提示yes/no 输入yes即可*

  • 第二个方法:

修改Jenkins的安全配置,在Manage Jenkins >> Configure Global Security 找到Git Host Key Verification Configuration,修改为No verification。保存
在这里插入图片描述

3.2 配置对阿里云k8s的访问

1. 登录阿里云,打开对应集群详情页面,切到【连接信息】,复制凭证信息。在本地新建一个空txt文件,粘贴进去,保存,修改文件名称为kubectl.conf。
在这里插入图片描述
2. 在Jenkins中配置凭证。选择上传刚才的kubectl.conf文件,ID这里自定义了一个名称。
在这里插入图片描述

3.3 添加Jenkins全局变量

1. 添加JAVA_HOME
在这里插入图片描述

2. 添加M2_HOME
在这里插入图片描述
3. 添加PATH+EXTRA
在这里插入图片描述

3.4 全局工具配置Maven

使用指定的settings.xml文件
在这里插入图片描述

4 创建Job和编写脚本

4.1 创建Job

新建任务-填写任务名称,选择流水线-点击确认
在这里插入图片描述

4.2 编写脚本

1)脚本框架构建

根据当前项目部署过程,先把脚本基本框架写好。每一个具体的项目可能不一样,根据实际的情况写。

pipeline {

	agent any

	stages {
		stage('0.前置构建'){
			steps {
				script{
					echo "前置构建"
				}
			}	
		}
			
		stage('1.拉取代码'){
			steps {
				sh """
					echo "拉取代码"
				"""			
			}
		}
		
		stage('2.编译程序'){
			steps {
				sh """
					echo "编译程序"
				"""
			}      
		}
		
		stage('3.镜像打包上传'){
			steps {
				script{
					sh """
						echo "镜像打包上传"
					"""
				}
			}
		}
		
		stage('4.发布'){
			steps {
				script{
					sh """
						echo "部署程序"
					"""
				}			
			}
		}
	}			
}
2)前置工作

一般项目设计合理,从拉取代码开始就可以了,我们的这个项目因为一些原因,需要有一个前置构建,但是又不是每一次都是必须的,这里需要添加一个参数,进行控制,另外前置构建,需要另建一个Job,完成拉取和编译代码工作。这里前置构建我起名叫pre-build,依然采用流水线方式构建。脚本结构如下:

pipeline {

    agent any

    stages {
		
        stage('1.拉取代码'){
            steps {
                cleanWs()
				checkout scmGit(branches: [[name: '*/master']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'parentProject']], userRemoteConfigs: [[credentialsId: 'Gitlab', url: 'git@git.***.com.cn:test/parentProject.git']])
				checkout scmGit(branches: [[name: '*/dev']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'childProject1']], userRemoteConfigs: [[credentialsId: 'Gitlab', url: 'git@git.***.com.cn:test/childProject1.git']])							
            }
        }
			
		stage('2.编译程序'){
            steps {
				sh """
					cd ${WORKSPACE}/parentProject/
                    mvn clean install
                """
            }      
        }
    }
}

执行一下构建,成功。
在这里插入图片描述

3)stage0中配置的参数

返回当前Job的配置页面,完成stage0的配置项,首选勾选【参数化构建】,选择布尔值参数,然后填写名称,勾选指定默认值,并进行友好的描述说明,保存。
在这里插入图片描述
在这里插入图片描述

4)完善stage0的脚本
pipeline {

    agent any
	
	parameters {
        booleanParam(name:"pre-build", defaultValue:"true", description:"是否进行前置构建:勾选为是,不勾选为否,默认为是")
    }
		
	stages {
		stage('0.前置构建'){
			steps {
				script{
					if (pre-build){
						build job: "pre-build"
					}
				}	
			}	
		}
				
		stage('1.拉取代码'){
			steps {
				sh """
					echo "拉取代码"
				"""			
			}
		}
			
		stage('2.编译程序'){
			steps {
				sh """
					echo "编译程序"
				"""
			}      
		}
			
		stage('3.镜像打包上传'){
			steps {
				script{
					sh """
						echo "镜像打包上传"
					"""
				}
			}
		}
		
		stage('4.发布'){
			steps {
				script{
					sh """
						echo "部署程序"
					"""
				}			
			}
		}
	}			
}

构建一下,成功。

5)完善stage1的脚本

首先是清空工作空间,然后拉取代码

stage('1.拉取代码'){
	steps {
		cleanWs()
		checkout scmGit(branches: [[name: '*/dev']], extensions: [[$class: 'RelativeTargetDirectory', relativeTargetDir: 'childProject3']], userRemoteConfigs: [[credentialsId: 'Gitlab', url: 'git@git.***.com.cn:test/childProject3.git']])
	}
}

构建一下,成功。

6)完善stage2的脚本

进行编译打包。

stage('2.编译程序'){
	steps {
		sh '''
			cd ${WORKSPACE}/childProject3/
			mvn clean install
		'''
	}      
}
7)完善stage3的脚本。
stage('3.镜像打包上传'){
	steps {
		script{
			DateTime=sh(returnStdout: true, script: 'date "+%Y%m%d%H%M"').trim()
			sh """
				chmod 777 ${WORKSPACE}/childProject3/*
				./buildAndPush.sh dokerfileName tagName-${DateTime}
			"""
		}
	}
}

其中buildAndPush.sh完成Docker构建和镜像推送,文件内容为

# bulid和push

docker build -f Dockerfile-$1 -t $1:$2 .

docker login -u 'robot' -p 'hjsafhjjjdkk' http://harbor.***.com.cn
docker tag $1:$2 harbor.***.com.cn/test/$1:$2
docker push harbor.***.com.cn/test/$1:$2

# 清理本地镜像
docker rmi $1:$2
docker rmi harbor.***.com.cn/test/$1:$2

因为本项目之前已经存在脚本和Dockerfile,所以直接沿用了,其他项目中,如果可以直接使用命令进行镜像打包和上传,可采用如下命令:

docker  build   -t  harbor***.com.cn/test/imageName: tagName-${DateTime} .  && docker push  harbor.***.com.cn/test/ imageName: tagName-${DateTime}
8)完善stage4的脚本
stage('4.发布'){
	steps {
		script{
			withKubeConfig(caCertificate: '', clusterName: '', contextName: '', credentialsId: 'k8s-config', namespace: 'nameSpaceofchildProject3', restrictKubeConfigAccess: false, serverUrl: 'https://***:6443'){
			sh """
			kubectl set image deployment/childProject3 childProject3=harbor***.com.cn/test/imageName: tagName-${DateTime}  -n nameSpaceofchildProject3
			kubectl rollout status deployment/childProject3 -n nameSpaceofchildProject3
			"""
			}			
		}
	}
}

脚本中的 nameSpaceofchildProject3 可以从阿里云上【集群列表】-【应用管理】,搜索相呼应的名称,查看命名空间
在这里插入图片描述

4.3 优化脚本

通过添加一些参数,把脚本变得更为通用一些,可以更为方便的复用到其他工程上。如

String server_name= env.JOB_NAME.toLowerCase()
String dockerbuild_filename = "###"
String tag_name = "###"

可根据项目的实际情况进行设置。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐