七、kubernetes实战案例之基于jenkins与gitlab实现容器代码升级及回滚
代码更新流程 1.开发上传代码gitlab 2.运维在jenkins job中发起更新,(拉代码,编译等),生成代码并在经过脚本之类工具把代码复制到k8s_master中有dockerfile文件夹 3.在k8s_master中dockerfile并打镜像,并上传到harbor。 4.镜像版本更新 ,在jenkins job 对k8s_master 进行操作(kubectl set images ) 5.k8s_node 对harbor镜像摘取进行升级 1.安装jenkins:(本例使用的是rpm) K8S方式:https://www.cnblogs.com/Yuanbangchen/p/17283264.html rpm方式:https://www.cnblogs.com/Yuanbangchen/p/17061384.html 2.安装gitlab:(本例使用的是rpm) K8S方式:https://www.cnblogs.com/Yuanbangchen/p/17317495.html rpm方式:https://www.cnblogs.com/Yuanbangchen/p/17061368.html
3.1生成jenkins服务器的root用户的公钥e。 [root@localhost7I ~]# mkdir /data/gitdata/magedu/ -p #git克隆目录。 [root@localhost7I ~]# ssh-keygen [root@localhost7I ~]# cat /root/.ssh/ id_rsa id_rsa.pub
把jenkins公钥添加到gitlabs配置中, (git是基于ssh公钥实现代码自动clone)。
3.2把jenkins服务器的root用户的公钥 复制 到k8s主机上, 脚本要使用到。 [root@localhost7I magedu]# ssh-copy-id 192.168.80.120 4.gitlab web端操作 创建一个项目 创建组(magedu) 和 创建项目(myapp),并创建一个index.html首页。
测试: [root@localhost7I ]# git clone git@192.168.80.190:magedu/myapp.git 正克隆到 'web1'... remote: Enumerating objects: 3, done. remote: Counting objects: 100% (3/3), done. remote: Total 3 (delta 0), reused 0 (delta 0) 接收对象中: 100% (3/3), done. [root@localhost7I magedu]# cat myapp/ .git/ index.html [root@localhost7I magedu]# cat myapp/index.html gitlab app v1
编写第二版本并推送到gitlab
[root@localhost7I myapp]# cd magedu/
[root@localhost7I myapp]# echo " gitlab app v2 ">> myapp/index.html
[root@localhost7I myapp]# git add index.html
[root@localhost7I myapp]# git commit -m "v2"
[root@localhost7I myapp1]# git push
5.1脚本选项参数使用的插件 active choices plug-in Build With Parameters Persistent Parameter 5.2创建一个自由风格的项目并设置相关配置,并添加"选项参数"2个。
5.jenkins服务器上的脚本 ,需要执行权限。jenkins程序最好使用root启动
[root@localhost7I linux39]#chmod +x /root/linux39/linux39.sh
[root@localhost7I linux39]# cat /root/linux39/linux39.sh
#!/bin/bash #!/bin/bash #Author: ZhangShiJie #Date: 2018-10-24 #Version: v1 #记录脚本开始执行时间 starttime=`date +'%Y-%m-%d %H:%M:%S'` #变量 SHELL_DIR="/data/scripts" SHELL_NAME="$0" #k8s master地址,这里没有做master的判断。 K8S_CONTROLLER1="192.168.80.120" K8S_CONTROLLER2="172.31.7.202" DATE=`date +%Y-%m-%d_%H_%M_%S` #部署或回滚 METHOD=$1 #mater分支或develop分支 Branch=$2 #字符串为空,空true; 不空false if test -z $Branch;then Branch=develop fi function Code_Clone(){ #gitlab项目地址 Git_URL="git@192.168.80.190:magedu/myapp.git" #取myapp的文件名 DIR_NAME=`echo ${Git_URL} |awk -F "/" '{print $2}' | awk -F "." '{print $1}'` DATA_DIR="/data/gitdata/magedu" Git_Dir="${DATA_DIR}/${DIR_NAME}" cd ${DATA_DIR} && echo "即将清空上一版本代码并获取当前分支最新代码" && sleep 1 && rm -rf ${DIR_NAME} echo "即将开始从分支${Branch} 获取代码" && sleep 1 git clone -b ${Branch} ${Git_URL} echo "分支${Branch} 克隆完成,即将进行代码编译!" && sleep 1 #cd ${Git_Dir} && mvn clean package #echo "代码编译完成,即将开始将IP地址等信息替换为测试环境" ##################################################### sleep 1 cd ${Git_Dir} tar czf ${DIR_NAME}.tar.gz ./* echo "${DIR_NAME}服务代码编译,即将执行代码压缩文件文件copy" } #将打包好的压缩文件拷贝到k8s 控制端服务器 function Copy_File(){ echo "压缩文件打包完成,即将拷贝到k8s 控制端服务器${K8S_CONTROLLER1}" && sleep 1 #会把原来的项目覆盖 scp ${Git_Dir}/${DIR_NAME}.tar.gz root@${K8S_CONTROLLER1}:/root/k8s-data/dockerfile/linux39/tomcat-app1 echo "压缩文件拷贝完成,服务器${K8S_CONTROLLER1}即将开始制作Docker 镜像!" && sleep 1 } #到控制端执行脚本制作并上传镜像 function Make_Image(){ echo "开始制作Docker镜像并上传到Harbor服务器" && sleep 1 ssh root@${K8S_CONTROLLER1} "cd /root/k8s-data/dockerfile/linux39/tomcat-app1 && bash build-command.sh ${DATE}" echo "Docker镜像制作完成并已经上传到harbor服务器" && sleep 1 } #到控制端更新k8s yaml文件中的镜像版本号,从而保持yaml文件中的镜像版本号和k8s中版本号一致 function Update_k8s_yaml(){ echo "即将更新k8s yaml文件中镜像版本" && sleep 1 ssh root@${K8S_CONTROLLER1} "cd /root/k8s-data/yaml/linux39/tomcat-app1 && sed -i 's/image: harbor.zzhz.com.*/image: harbor.zzhz.com\/linux39\/tomcat-app1:${DATE}/g' tomcat-app1.yaml" echo "k8s yaml文件镜像版本更新完成,即将开始更新容器中镜像版本" && sleep 1 } #到控制端更新k8s中容器的版本号,有两种更新办法,一是指定镜像版本更新,二是apply执行修改过的yaml文件 function Update_k8s_container(){ #第一种方法 ssh root@${K8S_CONTROLLER1} "kubectl set image deployment/linux39-tomcat-app1-deployment linux39-tomcat-app1-container=harbor.zzhz.com/linux39/tomcat-app1:${DATE} -n linux39" #第二种方法,推荐使用第一种 #ssh root@${K8S_CONTROLLER1} "cd /root/k8s-data/yaml/linux39/tomcat-app1 && kubectl apply -f tomcat-app1.yam --record" echo "k8s 镜像更新完成" && sleep 1 echo "当前业务镜像版本: harbor.zzhz.com/linux39/tomcat-app1:${DATE}" #计算脚本累计执行时间,如果不需要的话可以去掉下面四行 endtime=`date +'%Y-%m-%d %H:%M:%S'` start_seconds=$(date --date="$starttime" +%s); end_seconds=$(date --date="$endtime" +%s); echo "本次业务镜像更新总计耗时:"$((end_seconds-start_seconds))"s" } #基于k8s 内置版本管理回滚到上一个版本,如果指定版本怎么写? function rollback_last_version(){ echo "即将回滚之上一个版本" ssh root@${K8S_CONTROLLER1} "kubectl rollout undo deployment/linux39-tomcat-app1-deployment -n linux39" sleep 1 echo "已执行回滚至上一个版本" } #使用帮助 usage(){ echo "部署使用方法为 ${SHELL_DIR}/${SHELL_NAME} deploy " echo "回滚到上一版本使用方法为 ${SHELL_DIR}/${SHELL_NAME} rollback_last_version" } #主函数 main(){ case ${METHOD} in deploy) #部署 Code_Clone; Copy_File; Make_Image; Update_k8s_yaml; Update_k8s_container; ;; rollback_last_version)#回滚 rollback_last_version; ;; *) usage; esac; } main $1 $2 $3
6.tomcat服务配置。 参考文档第9步。 https://www.cnblogs.com/Yuanbangchen/p/17264215.html [root@localhost7C tomcat-app1]# cat tomcat-app1.yaml kind: Deployment #apiVersion: extensions/v1beta1 apiVersion: apps/v1 metadata: labels: app: linux39-tomcat-app1-deployment-label name: linux39-tomcat-app1-deployment namespace: linux39 spec: replicas: 1 selector: matchLabels: app: linux39-tomcat-app1-selector template: metadata: labels: app: linux39-tomcat-app1-selector spec: containers: - name: linux39-tomcat-app1-container image: harbor.zzhz.com/linux39/tomcat-app1:2023-04-14_17_05_39 #command: ["/apps/tomcat/bin/run_tomcat.sh"] #imagePullPolicy: IfNotPresent imagePullPolicy: Always ports: - containerPort: 8080 protocol: TCP name: http env: - name: "password" value: "123456" - name: "age" value: "18" resources: limits: cpu: 1 memory: "512Mi" requests: cpu: 500m memory: "512Mi" volumeMounts: - name: linux39-images mountPath: /data/tomcat/webapps/myapp/images readOnly: false - name: linux39-static mountPath: /data/tomcat/webapps/myapp/static readOnly: false volumes: - name: linux39-images nfs: server: 192.168.80.110 path: /data/linux39/images - name: linux39-static nfs: server: 192.168.80.110 path: /data/linux39/static #nodeSelector: # project: linux39 --- kind: Service apiVersion: v1 metadata: labels: app: linux39-tomcat-app1-service-label name: linux39-tomcat-app1-service namespace: linux39 spec: type: NodePort ports: - name: http port: 80 protocol: TCP targetPort: 8080 nodePort: 30003 selector: app: linux39-tomcat-app1-selector
测试:
[root@localhost7A ]# curl 192.168.80.160:30003/myapp/index.html
gitlab app v1
gitlab app v2
7.测试:编写第三版本并推送到gitlab
[root@localhost7I myapp]# cd magedu/
[root@localhost7I myapp]# echo " gitlab app v3 ">> myapp/index.html
[root@localhost7I myapp]# git add index.html
[root@localhost7I myapp]# git commit -m "v3"
[root@localhost7I myapp1]# git push
在jenkins上部署
测试结果
[root@localhost7A harbor]# curl 192.168.80.160:30003/myapp/index.html
gitlab app v1
gitlab app v2 gitlab app v3
8.测试:再次编写第四版本并推送到gitlab. jenkins同上操作。 [root@localhost7I myapp]# cd magedu/ [root@localhost7I myapp]# echo " gitlab app v3 ">> myapp/index.html [root@localhost7I myapp]# git add index.html [root@localhost7I myapp]# git commit -m "v3" [root@localhost7I myapp1]# git push 测试 [root@localhost7A harbor]# curl 192.168.80.160:30003/myapp/index.html gitlab app v1 gitlab app v2 gitlab app v3 gitlab app v4
在jenkins回滚上一版本。
测试
[root@localhost7A harbor]# curl 192.168.80.160:30003/myapp/index.html
gitlab app v1
gitlab app v2
gitlab app v3