zoukankan      html  css  js  c++  java
  • 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
    最后通过浏览器访问即可:

  • 相关阅读:
    索引有什么用?
    数据类型的优化策略?
    MySQL的锁策略有什么?
    行锁
    Innodb_lock_waits
    Innodb_locks表
    软件安装笔记
    Spring Boot学习笔记
    AI学习总结
    笔试面试题总结
  • 原文地址:https://www.cnblogs.com/abner123/p/13190592.html
Copyright © 2011-2022 走看看