Jenkinsfile、Dockerfile、deploy.yml完整CI/CD流程参考

Dockerfile

#基础镜像:仓库是java,tag是8
FROM openjdk:8-jdk

##此处是打包的jar包名称,不带.jar后缀
ENV API_NAME=dubbo-provide-service
##工作目录
ENV WORK_DIR=/app/service/$API_NAME
##临时目录,如果不指定该目录可能会导致Springboot项目启动报错
ENV TMP_DIR=$WORK_DIR/temp
##完整jar包名称
ENV JAR_NAME=$API_NAME\.jar

##同步时区
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
##创建配置中心容灾文件路径
RUN mkdir -p /opt/data
##创建工作目录
RUN mkdir -p $WORK_DIR
##创建日志目录
RUN mkdir -p $WORK_DIR/logs
##创建临时目录,否则Springboot项目可能会启动失败
RUN mkdir -p $TMP_DIR

#指定工作目录
WORKDIR $WORK_DIR

# 复制jar文件到路径
COPY target/$JAR_NAME $WORK_DIR/$JAR_NAME

#挂载文件,配置中心的setting配置(废弃,使用configmap,当然,此方式也可以,configmap更加灵活而已)
#VOLUME /opt/settings/

#容器对外暴露8080端口
#EXPOSE 8080


#容器启动后需要执行的命令,注意:此处的POD_IP为pod的ip,需要在容器创建的时候指定,否则会造成注册地址错误
ENTRYPOINT ["/bin/sh","-c","java -Dfile.encoding=utf8 -jar -Djava.io.tmpdir=$TMP_DIR -DUBBO_IP_TO_REGISTRY=${POD_IP} -DDUBBO_IP_TO_BIND=${POD_IP} $JAR_NAME"]

##注意:一定不能加 " >/dev/null 2>&1 & " ,否则会造成启动失败,以下是错误示范
##ENTRYPOINT ["/bin/sh","-c","java -Dfile.encoding=utf8 -jar -Djava.io.tmpdir=$TMP_DIR -DUBBO_IP_TO_REGISTRY=${POD_IP} -DDUBBO_IP_TO_BIND=${POD_IP} $JAR_NAME >/dev/null 2>&1 &"]


deploy.yml

##注意:此文件中所有变量,全部取值于Jenkinsfile中environment中的配置值,可自行进行替换

## 创建Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: $APP_NAME
  name: $APP_NAME
  ## 修改此值,改成自己项目的namespace
  namespace: $APP_NAME
spec:
  ## 单位:秒
  progressDeadlineSeconds: 600
  ## 修改此值,部署副本数量
  replicas: 2
  ## 修改此值或者关闭配置,我们做的回滚操作并不是没有代价的,代价就是旧版本的 ReplicaSet 会被保留,但是不会继续提供服务了。当我们执行回滚操作的时候,就直接使用旧版本的 ReplicaSet。这个配置就是控制保留多少个版本的 ReplicaSet
  #revisionHistoryLimit: 1
  selector:
    matchLabels:
      app: $APP_NAME
    ## 定义升级策略,可选值,RollingUpdate(滚动升级,默认),Recreate(先将旧 Pod 下线,再启动新 Pod)
  strategy:
    rollingUpdate:
      ## 在升级过程中,最多可以创建多少个 Pod。也就是说每次滚动的步长。该值不能为0。
      maxSurge: 50%
      ## 在升级过程中,最多不可用的 pod 的数量。该值不能为0。
      maxUnavailable: 50%
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: $APP_NAME
    spec:
      ## 创建数据卷
      volumes:
        - name: apollo-server-configmap
          configMap:
            ## 修改此值,ConfigMap 的key值,此值配置路径是:kubesphere的dashboard中的配置-保密字典配置-配置字典
            name: apollo-server-config
            ## 默认情况下用于创建文件的模式位。取值范围在0到0777之间。默认值为0644
            defaultMode: 420
      imagePullSecrets:
        ## 修改此处,docker镜像仓库地址和用户名密码配置,此值配置路径是:kubesphere的dashboard中的配置-保密字典
        - name: docker-registry
      containers:
        - env:
            ## 配置pod的ip,使用命令  echo ${POD_IP}   即可输出pod的ip,Dockerfile的中ENTRYPOINT使用此值
            - name: POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            ## 配置宿主机ip,使用命令  echo ${HOST_IP}   即可输出宿主机的ip
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.hostIP
          ## 配置镜像以及版本
          image: $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$PACKAGE_ENV-$BUILD_NUMBER
          ## 死循环命令,开启后,则pod必定启动成功,,此时可进入到pod内手动执行java -jar命令启动服务,可用于排查问题
          ## command: ["/bin/bash", "-ce", "tail -f /dev/null"]
          ## 镜像的拉取策略,可选值,Always(默认,每次pod启动都去远程pull镜像),IfNotPresent(如果本地没有,就去远程 pull 镜像),Never(只去本地获取镜像)
          imagePullPolicy: Always
          name: $APP_NAME
          ports:
            ## 修改此值,端口
            - containerPort: 8880
              protocol: TCP
          resources:
            ## 修改此值,分配资源大小
            limits:
              cpu: 100m
              memory: 200Mi
          ##容器的终止日志文件
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          volumeMounts:
            ## 此值与spec.template.spec.volumes[0].name的值相同
            - name: apollo-server-configmap
              readOnly: true
              ## 设置配置中心环境文件挂载路径
              mountPath: /opt/settings
      ## dns 策略
      # Default:和宿主机的DNS完全一致
      # ClusterFirst:把集群的DNS写入到Pod的DNS配置,但是如果设置了HostNetwork=true,就会强制设置为Default
      # ClusterFirstWithHostNet: 把集群的DNS写入到Pod的DNS配置,不管是否设置HostNetwork
      # None: 忽略所有的DNS配置,一般来说,设置了None之后会自己手动再设置dnsConfig
      dnsPolicy: ClusterFirst
      ## pod 重启策略
      # always: 容器失效时,自动重启容器
      # OnFailure: 容器终止运行,且退出码不为0时候重启
      # Never: 不重启
      restartPolicy: Always
      ## 优雅重启配置,新pod启动等待此值后再kill老的pod,单位:秒
      terminationGracePeriodSeconds: 30

## 创建service
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: service-$APP_NAME
  name: service-$APP_NAME
  ## 修改此值,改成自己项目的namespace
  namespace: $APP_NAME
spec:
  ports:
    ## 修改此值,端口
    - name: http
      port: 8880
      protocol: TCP
      targetPort: 8880
  selector:
    app: $APP_NAME
  ## 负载策略,可选值,None(随机),ClientIP(固定ip)
  ## 注意:选ClientIP时,应当增加此配置spec.sessionAffinityConfig.clientIP.timeoutSeconds(默认值为 10800 秒,即 3 小时)
  sessionAffinity: None
  ## 修改此值,service类型,可选值,ClusterIP,NodePort
  type: NodePort

Jenkinsfile

pipeline {
  agent {
    node {
      label 'maven'
    }

  }
  stages {
    stage('clone code') {
      agent none
      steps {
        container('maven') {
          sh 'pwd'
          git(url: 'https://git.xxx.com/dubbo-demo.git', credentialsId: 'gitlab-dubbo-demo', changelog: true, poll: false)
          sh 'ls -al'
        }

      }
    }

    stage('package') {
      steps {
        container('maven') {
          sh 'mvn clean package -Dmaven.test.skip=true -f ./dubbo-consumer/pom.xml'
          sh 'ls -al ./dubbo-consumer/target'
        }

      }
    }

    stage('build docker img') {
      agent none
      steps {
        container('maven') {
          sh 'docker build -t dubbo-consumer:latest -f ./dubbo-consumer/Dockerfile ./dubbo-consumer'
          sh 'docker images | grep dubbo'
        }

      }
    }

    stage('push latest') {
      agent none
      steps {
        container('maven') {
          withCredentials([usernamePassword(credentialsId : 'docker-registry' ,passwordVariable : 'DOCKER_PWD_VAR' ,usernameVariable : 'DOCKER_USER_VAR' ,)]) {
            sh 'echo "$DOCKER_PWD_VAR" | docker login $REGISTRY -u "$DOCKER_USER_VAR" --password-stdin'
            sh 'docker tag $APP_NAME:latest $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$PACKAGE_ENV-$BUILD_NUMBER'
            sh 'docker push $REGISTRY/$DOCKERHUB_NAMESPACE/$APP_NAME:$PACKAGE_ENV-$BUILD_NUMBER'
          }

        }

      }
    }

    stage('deploy') {
      agent none
      steps {
        kubernetesDeploy(enableConfigSubstitution: true, deleteResource: false, kubeconfigId: "$KUBECONFIG_CREDENTIAL_ID", configs: 'dubbo-consumer/deploy.yml')
      }
    }

  }
  environment {
    DOCKER_CREDENTIAL_ID = 'dockerhub-id'
    GITHUB_CREDENTIAL_ID = 'github-id'
    GITHUB_ACCOUNT = 'kubesphere'
    // 修改此值,devops的kubeconfig
    KUBECONFIG_CREDENTIAL_ID = 'demo-kubeconfig'
    // 修改此值,公司镜像仓库地址
    REGISTRY = 'artifacts.xxx.com/xxb-docker-private'
    // 修改此值,公司镜像仓库目录
    DOCKERHUB_NAMESPACE = 'dubbo-test'
    // 修改此值,项目名称
    APP_NAME = 'dubbo-consumer'
    // 修改此值,打包版本的环境,可选值,SNAPSHOT,RELEASE
    PACKAGE_ENV = 'SNAPSHOT'
  }
  parameters {
    string(name: 'TAG_NAME', defaultValue: '', description: '')
  }
}

你可能感兴趣的:(k8s,java,dubbo,kubernetes,jenkins,docker)