项目前期部署都是手动部署,所以相关工具基本都已经安装,主要使用的工具有:
使用Gitlab管理代码
使用Maven打包
使用Docker构建镜像(已经有相关的DockerFile文件)
在阿里云kubernetes上部署。
所以,在这次自动化部署过程中,需要做的是安装Jenkins并完成相关配置,然后通过流水线脚本(Pipeline Script)将整个部署过程粘合起来。
因此本文不涉及Maven和Docker等工具的安装部署,仅记录部署过程中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)在浏览器中访问,可以正常打开即部署成功。然后通过提示信息,查看初始密码,复制进去即可登录,然后选择安装推荐插件,或者自定义要安装的插件,或者直接跳过插件安装均可。本次安装采用的是安装推荐插件。
其他说明:
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个方法可以,选择其一即可。
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。保存
1. 登录阿里云,打开对应集群详情页面,切到【连接信息】,复制凭证信息。在本地新建一个空txt文件,粘贴进去,保存,修改文件名称为kubectl.conf。
2. 在Jenkins中配置凭证。选择上传刚才的kubectl.conf文件,ID这里自定义了一个名称。
根据当前项目部署过程,先把脚本基本框架写好。每一个具体的项目可能不一样,根据实际的情况写。
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 "部署程序"
"""
}
}
}
}
}
一般项目设计合理,从拉取代码开始就可以了,我们的这个项目因为一些原因,需要有一个前置构建,但是又不是每一次都是必须的,这里需要添加一个参数,进行控制,另外前置构建,需要另建一个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
"""
}
}
}
}
返回当前Job的配置页面,完成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 "部署程序"
"""
}
}
}
}
}
构建一下,成功。
首先是清空工作空间,然后拉取代码
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']])
}
}
构建一下,成功。
进行编译打包。
stage('2.编译程序'){
steps {
sh '''
cd ${WORKSPACE}/childProject3/
mvn clean install
'''
}
}
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}
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
"""
}
}
}
}
通过添加一些参数,把脚本变得更为通用一些,可以更为方便的复用到其他工程上。如
String server_name= env.JOB_NAME.toLowerCase()
String dockerbuild_filename = "###"
String tag_name = "###"
可根据项目的实际情况进行设置。