Jenkins+K8S流水线自动化部署Java程序
一、首先需要搭建好k8s集群以及在k8s集群中部署好Jenkins,这里就不做详细介绍如何搭建k8s集群和在k8s集群中部署Jenkins,(具体过程可以参考之前文章进行部署)
1、这里我使用公有GitHub作为代码仓库,首先需要将GitHub代码仓库以及harbor镜像仓库账户和密码在Jenkins添加上;(我这里是之前已经添加上了,如果没有点击凭据进行添加即可)
、
2、我们需要将代码上传到代码仓库,这里我使用rocketMQ-console为例,
1.我们先将源码克隆本地:
git clone https://github.com/apache/rocketmq-externals.git
2.进入源码目录
[root@k8s-master]# cd /usr/local/src/rocketmq-externals
[root@k8s-master rocketmq-externals]# ll -a
里面有一个.git隐藏文件:
3.进入.git文件编辑config配置文件:vim config
4.将源码上传到你自己GitHub仓库中;
git remote add origin https://github.com/houyi199208/rocketmq-console.git
git push -u origin master 这里master是分支
git push origin --tag 或者打tag号
执行完成后登陆自己代码仓库查看是否上有相关源码
3、上面工作做好后我们接下在Jenkins上面创建第一个Java项目流水线
注意:
如果没有参数化构建选项,需要安装插件:
安装pipeline参数化构建插件
Jenkins中-->系统管理--->管理插件--->可选插件--->搜索extended choice parameter---->点击直接安装
4、编辑pipeline脚本
node("slave") { env.registry="192.168.111.161" //harbor地址 env.image="${registry}/${MODULE}/${APP_NAME}:${TAG}" //生成的镜像名称 if ( Operation == 'Deploy' ) { stage('Get code'){ checkout([$class: 'GitSCM', branches: [[name: "${TAG}"]], doGenerateSubAPP_NAMEConfigurations: false, userRemoteConfigs: [[credentialsId: 'github', url: ' https://github.com/houyi199208/rocketmq-console.git']]]) //根据TAG号拉取代码 } stage('Build code') { sh "pwd" sh "mvn clean package -Dmaven.test.skip=true -f rocketmq-console/pom.xml" //编译代码 sh ''' cat >Dockerfile<<EOF FROM openjdk:8u232 RUN echo "ZONE=Asia/Shanghai" >/etc/timezone COPY rocketmq-console/target/${APP_NAME}-ng-1.0.0.jar /opt/app/${MODULE}/${APP_NAME}/ WORKDIR /opt/app/${MODULE}/${APP_NAME}/ ENTRYPOINT ["java","-jar","${APP_NAME}-ng-1.0.0.jar"] ''' //制作Dockerfile } stage('mk image & push image'){ withCredentials([usernamePassword(credentialsId: 'harbor', passwordVariable: 'harborpasswd', usernameVariable: 'harboruser')]) { sh "docker login ${env.registry} -u ${harboruser} -p ${harborpasswd}" sh "docker build -t ${registry}/${MODULE}/${APP_NAME}:${TAG} -f ./Dockerfile . && docker push ${registry}/${MODULE}/${APP_NAME}:${TAG}" } } stage('Deploy'){ sh "sed -e 's/APP_NAME/${APP_NAME}/g' -e 's/MODULE/${MODULE}/g' -e 's%IMAGE%${env.image}%g' -e 's/PORT/${PORT}/g' ../k8s/deploy-template.yml >../k8s/${MODULE}/${APP_NAME}-deploy.yml " //根据选项参数的值对部署文件进行替换 get_ns = sh returnStatus: true, script: "kubectl get ns ${MODULE}" echo "${get_ns}" if ( get_ns != 0 ){ sh "kubectl create ns ${MODULE}" } sh "kubectl apply -f ../k8s/${MODULE}/${APP_NAME}-deploy.yml --record=true" } }else if ( Operation == 'Rollback' ) { stage('Rollback Previous Version'){ sh "kubectl describe deployment ${APP_NAME} -n mq-console |grep -w 'Image:'" sh "kubectl rollout undo deployment ${APP_NAME} -n ${MODULE} " sh "kubectl describe deployment ${APP_NAME} -n mq-console |grep -w 'Image:'" } } }
5、后续准备工作
找到jenkins-slave的workspace目录,目录和文件是和pipeline配套的
[root@master workspace]# pwd
/data/jenkins-slave/workspace
[root@master workspace]# mkdir k8s && cd k8s
[root@master k8s]# mkdir mq-console #创建项目部署文件保存目录
[root@master k8s]# ls #deploy-template.yml是通用模板,修改后部署对应的项目
deploy-template.yml mq-console
[root@master k8s]# chmod o+w -R ./ #jenkins-slave默认用户是Jenkins,没有权限操作,后续创建的其他项目也需要关注权限问题,这个版本先用o+w解决
查看节点标签
[root@master k8s]# kubectl get node --show-labels
给调度的节点打标签
[root@master k8s]# kubectl label nodes node01 app=mq-console
6、模板文件(这里面所有的变量都是使用Jenkins上面定义的参数)
[root@master k8s]# cat deploy-template.yml
apiVersion: apps/v1 kind: Deployment metadata: name: APP_NAME namespace: MODULE spec: selector: matchLabels: app: APP_NAME replicas: 1 template: metadata: labels: aliyun.logs.APP_NAME: stdout app: APP_NAME spec: imagePullSecrets: - name: regsecret #拉取镜像的secret,不同名称空间需要单独创建 hostNetwork: true nodeSelector: app: test-MODULE terminationGracePeriodSeconds: 60 restartPolicy: Always containers: - name: APP_NAME image: IMAGE imagePullPolicy: IfNotPresent resources: requests: memory: "1Gi" cpu: "0.5" limits: memory: "2Gi" cpu: "8" env: - name: aliyun_logs_APP_NAME value: "stdout" livenessProbe: tcpSocket: port: PORT initialDelaySeconds: 120 periodSeconds: 20 successThreshold: 1 failureThreshold: 2 volumeMounts: - name: logs mountPath: /opt/logs/ - name: time mountPath: /etc/localtime volumes: - name: logs hostPath: path: /opt/logs/ #应用日志输出位置,根据应用进行调整,项目中规定的是/opt/logs,此次部署用不到,可以做参考 type: DirectoryOrCreate - name: time hostPath: path: /etc/localtime #挂载时区文件 --- apiVersion: v1 kind: Service metadata: name: APP_NAME labels: app: APP_NAME namespace: MODULE spec: selector: app: APP_NAME clusterIP: None # type: NodePort ports: - name: APP_NAME port: PORT targetPort: PORT # nodePort: PORT
7、以上部署没有问题就可以部署ingress了
[root@master mq]# cat mq-ingress.yaml
apiVersion: extensions/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx name: mq-ingess namespace: mq-console spec: rules: - host: mymq-ingress.com http: paths: - backend: serviceName: rocketmq-console servicePort: 8080 path: /
8、编辑完成ingress的yaml文件后执行:
[root@k8s-master k8s]# kubectl apply -f mq-ingress.yaml
[root@k8s-master k8s]# kubectl get ingress -nmq-console
NAME HOSTS ADDRESS PORTS AGE
mq-ingress mymq-ingress.com 192.168.111.163 80 142m
最后通过浏览器访问即可: