Jenkins-pipeline自动化上线k8s多副本
实验准备:
K8s集群:
10.0.0.135 k8s_master
10..0.0.136 k8s_node1
10.0.0.137 k8s_node2
Gitlab服务器:
10.0.0.139 gitlab
10.0.0.132 jenkins
注意需要一个镜像仓库,本次使用的是阿里云的私人仓库,设置为公开
这里采用的个人搭建的gitlab作为远程仓库,也可以使用别的代码仓库如gitee、github等。
实验要求:
- 保证k8s集群可用(如使用ansible调用kubectl)
- 保证jenkins服务器的插件安装完毕
- 保证gitlab仓库可以正常被拉取与推送
- 保证镜像仓库可以正常拉取镜像和正常推送镜像
- 防火墙以及SELINUX关闭
- 保证epel、base仓库可用
- 注意jenkins服务器的jdk以及maven打包工具已指定且可用
本次的pipeline使用的是脚本式,也可以整理思路后改用声明式
首先新建一个任务
随后调整丢弃旧的构建
我们部署的式参数化构建过程所以勾选参数化构建过程
调整倒叙
暂时保存,去模拟开发人员的项目推送
我们需要在jenkins服务器上下载一个git的客户端,使用它来推送我们的代码到代码仓库
前提是保证仓库以及可以正常的推送代码,以及部署过ssh,部署ssh的步骤略
Jenkins服务器操作:
> yum -y install git
为我们指定身份,方便后续上传代码
> git config —global user.name “tom”
> git config —global user.email “euphoria.com”
> git config —list
随后就可以拉取代码并上传啦
首先先拉取我们服务器的代码仓库:
> git clone git@www.gitlab.com:plat-sp/cloud-2.git
> cd clond-2 #切换进拉下来的仓库内
本次实验使用的是一个简单的实验项目包,如有所需联系作者
> cp -r /root/easy-springmvc-maven-master/ cloud-2/
如果你的仓库内有自述文件,会询问你是否覆盖,输入yes即可
随后开始推送代码:
> git add
> git commit -m “begin”
因为我们使用的是参数化构建过程,所以我们给推送的代码打个标签
> git tag “v1.0”
推送到主分支以及标签上,注意因为我使用的是gitlab所以我的主分支是main,如果主分支无法推送,尝试关闭仓库的保护主分支策略
> git push -u origin main
> git push -u origin v1.0
推送完毕后,我们尝试使用jenkins-pipeline进行脚本式的参数化构建
回到jenkins服务器的web页面上:
首先进入刚刚构建的任务内:
首次脚本内容如下:
node {
gitlab_url=”git@www.gitlab.com:plat-sp/cloud-2.git”
value = “==========================================================”
stage(‘拉取代码’){
print “${value}”
git branch: “main”, url: “${gitlab_url}”, credentialsId: “250”
sh “git checkout ${tag}”
}
}
注意我们是先定义了变量方便后续的使用,拉的是主分支的内容,但是紧接着我们切换到了我们构建是选择的标签,这样代码就会切换到我们切换的标签内的内容,注意我们的拉取代码网址为git@www.gitlab.com... 因为gitlab是我们自己构建的,所以我们需要让jenkins服务器能够识别到www.gitlab.com是来自与我们本地的哪个ip地址,所以jenkins服务器一定要做好本地解析否则无法正常的拉取代码。
随后点击保存 进行构建测试:
随后点击刚刚构建的任务,点击控制台输出查看输出信息:

接下来我们需要打包,并且制作一个tomcat镜像将打包后的war包放在tomcat的发布目录内,这里选择通过Dockerfile来实现这一点,我们在每一次推送的代码仓库内,放一个docker,因为每次jenkins生成一个工作区在/root/.jenkins/workspace/仓库名/ 下,我们在代码仓库内放一个dockerfile这样就可以直接在工作区进行镜像的制作,并把它发布到远程镜像仓库内去,具体操作如下:
Jenkins服务器操作:
> cd cloud-2/
编写Dockerfile文件:
> vim Dockerfile
FROM daocloud.io/library/tomcat:7.0.76-alpine
RUN rm -rf /usr/local/tomcat/webapps/*
ADD ./target/easy-springmvc-maven.war /usr/local/tomcat/webapps/
ENTRYPOINT [“/usr/local/tomcat/bin/catalina.sh”,”run”]
保存退出
随后进行代码包的上传:
> git add *
> git commit -m “dockerfile”
> git tag “v1.1”
> git push -u origin main
> git push -u origin v1.1
随后返回我们jenkins的web界面的配置任务界面,添加脚本:

显示success即为成功,
至于脚本内容就自己悟吧。
开玩笑的,脚本内容如下:
node {
gitlab_url=”git@www.gitlab.com:plat-sp/cloud-2.git”
value = “==========================================================”
dockerurl=”registry.cn-shanghai.aliyuncs.com”
dockername=”aliyun*“
dockerpass=”Zsk**“
stage(“拉取代码”){
print “${value}”
git branch: “main”, url: “${gitlab_url}”, credentialsId: “250”
sh “git checkout ${tag}”
}
stage(‘编译打包’){
print “${value}”
sh “mvn clean package”
}
stage(‘add images’){
sh ‘docker build -t tomcat:${tag} .’
}
stage(‘push images’){
sh “docker login —username=${dockername} —password=${dockerpass} ${dockerurl}”
sh “docker tag tomcat:${tag} registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag}”
sh “docker push registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag} && docker rmi tomcat:${tag} && docker rmi registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag}”
}
}
在上一次编写的脚本的基础上,我们多定义了几个变量,比如远程仓库的地址,远程仓库的用户名和密码等等,这些都是为了脚本的灵活性去定义的变量,实际上有没有都无所谓,只要注意后面的命令行即可,比如我们docker build 的时候是tomcat:${tag}也就是说,我们选择构建的是哪个版本,制作的版本就是什么版本,当然在推送时版本也是我们定义的变量的内容,然后推送我们的镜像时,除了登录和push操作外,注意删除镜像的操作,在每次推送完毕之后,将服务器上残留的镜像删除,这样不会影响以后的版本回滚问题。
当你完成了上面的工作并没有报错,那么接下来就是时候用到我们的k8s集群了,也就是说我们就要把代码推送到我们的k8s集群上了,首先我们的思路是远程更改k8s集群中每一个,tomcat pod的镜像,也就是说我们的k8s集群只负责拉取我们上传到远程仓库上的镜像即可,因为更新的内容已经被打包到镜像上了,个人认为这一步是比较简单的,但如果你的k8s集群出现了问题,那就会变得很复杂。
那么我们提到了远程控制k8s集群,这里可以使用两个办法,第一是ansible去远程调用kubectl命令,另一种是ssh调用,哪一种都可以,看你自己喜欢用哪一个了,本次实验采用的是ansible,具体操作如下:
Jenkins服务器操作:
安装ansible服务:
> yum -y install ansible
配置ansible主机列表:
> vim /etc/ansible/hosts
在末行添加
[k8s-master]
k8s_master
保存退出后
编辑本地解析:
> vim /etc/hosts
在末行添加:
10.0.0.135 k8s_master
保存退出
发送公钥给k8s_master
> ssh-copy-id k8s_master
进行测试:
> ansible k8s_master -m ping
在进行jenkins构建之前,推荐先试一下能否利用ansible远程调用kubectl的命令:
> ansible k8s_master -m shell -a “kubectl get node”
有正常回显即可进行接下来的操作。
来到k8s-master节点进行操作:
> mkdir tomcat
> cd tomcat/
> vim tomcat.yaml
—-
apiVersion: apps/v1
kind: Deployment
metadata:
name: tomcat-deployment
spec:
selector:
matchLabels:
app: tomcat
replicas: 2
template:
metadata:
labels:
app: tomcat
spec:
containers:
- name: tomcat
image: registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:v1.0
ports:
- containerPort: 8080
—-
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
type: NodePort
ports:
- port: 8080
nodePort: 30002
targetPort: 8080
selector:
app: tomcat
保存退出
在这里我们创建了一个deployment的多副本控制器,你也可以选择别的多副本控制器
我们pod指定的镜像我选择的是我们上传的远程仓库的镜像,所以远程仓库一定要设置为公开,私人后面会说到。
我们在创建deployment的同时也创建了一个svc用来暴露pod的8080端口到pod所在节点的30002端口上,用来浏览器访问实验。
随后把它创建出来:
> kubectl apply -f tomcat.yaml
随后查看pod 并等待镜像的拉取时我们到jenkins配置任务页面进行脚本的完善:
具体脚本内容如下:
node {
gitlab_url=”git@www.gitlab.com:plat-sp/cloud-2.git”
value = “==========================================================”
dockerurl=”registry.cn-shanghai.aliyuncs.com”
dockername=”aliyun3600985484”
dockerpass=”Zskaixin1314ba..”
NS=”default”
stage(“拉取代码”){
print “${value}”
git branch: “main”, url: “${gitlab_url}”, credentialsId: “250”
sh “git checkout ${tag}”
}
stage(‘编译打包’){
print “${value}”
sh “mvn clean package”
}
stage(‘add images’){
sh ‘docker build -t tomcat:${tag} .’
}
stage(‘push images’){
sh “docker login —username=${dockername} —password=${dockerpass} ${dockerurl}”
sh “docker tag tomcat:${tag} registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag}”
sh “docker push registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag} && docker rmi tomcat:${tag} && docker rmi registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag}”
}
stage(‘k8s-master deployment’){
sh “ansible ‘k8s_master’ -m shell -a ‘kubectl set image deployment tomcat-deployment tomcat=registry.cn-shanghai.aliyuncs.com/zhengshuo/tomcat:${tag} -n ${NS}’”
}
}
注意我们与上一次修改脚本只修改了一点内容,比如定义了一个命名空间的变量,然后把推送到k8s集群上的脚本步骤写上去了,我们具体的命令行就是kubectl set image 也就是更改我们deployment中pod的镜像为我们推送远程仓库上的那个镜像,因为版本也是使用了tag这个变量,我们编辑完毕之后,可以进行构建测试一下。
显示success即为成功,我们可以直接去修改源码推送一个新的标签然后看他会不会发生改变即可。
具体操作就是:
> git clone 克隆代码仓库
修改代码包里的内容后
> git add *
> git commit -m “描述信息”
> git tag “v1.3” #具体标签号自己定义即可
> git push -u origin v1.3 #推送到指定的标签上去
推送完代码后回到jenkins服务器的web页面,进行项目的构建选择刚刚推的标签进行构建
构建完毕后,对k8s的node节点进行访问,因为我们的svc指定的暴露端口号为node节点的30002端口,所以我们的浏览器直接去访问node节点的IP地址+30002即可,实际svc暴露的端口号自定义即可,前提是你修改的没有被占用。
这里我们进行了上面的操作,并进行了访问测试:

也可以进行几次不同版本的切换构建,看一下访问的内容有没有变化,如果有变化,代表实验完成。
补:
如果你的远程镜像仓库是私有的,或者不得不是私有的,那么暂时请参考以下链接:
https://www.jianshu.com/p/fd13c2762d81
https://kubernetes.io/docs/concepts/containers/images/
