zoukankan      html  css  js  c++  java
  • Jenkins+K8S自动化集成和部署微服务

    前言

    最近在学习如何使用jenkins结合阿里云k8s自动化集成和部署springcloud微服务和前端next.js项目,现在记录下来分享给大家,文章有什么不妥的地方,希望大佬们批评指正。

    DevOps CI/CD 流程

    面向对象

    • 熟练使用vue或者react
    • 熟练使用SpringCloud微服务
    • 熟练使用docker容器
    • 熟练使用jenkins自动化运维工具
    • 熟练使用k8s(deployment、service、ingress)

    准备工作

    1、购买阿里云ACK集群(或者自行搭建)

    我购买的是阿里云ACK托管版,创建集群地址

    注意:创建ACK集群不收费,收费的是里面的NAT网关、SLB负载均衡、ECS服务器等

    2、安装gitlab

    这里我之前写了一篇阿里云ECS搭建gitlab,安装gitlab地址

    3、安装jenkins

    这里我之前写了一篇阿里云ECS搭建jenkins,安装jenkins地址

    4、安装docker

    使用官网推荐yum 安装比较方便,安装如下:

    sudo yum install -y yum-utils \

    device-mapper-persistent-data \

    lvm2

    sudo yum-config-manager \

    --add-repo \

    https://download.docker.com/linux/centos/docker-ce.repo

     

    sudo yum install docker-ce docker-ce-cli containerd.io

    系统架构

    Next.js 前端开发

    Next.js项目:

    服务:react+next.js

     

    服务端口:3000

     

    K8S:Deployment+Server+Ingress

     

    Pod名:demo-webapp

     

    Dockerfile

    FROM node:12

     

    # 设置工作路径。所有的路径都会关联WORKDIR

    WORKDIR /usr/src/app

     

    # 安装依赖

    COPY package*.json ./

    RUN npm install

     

    # 拷贝源文件

    COPY . .

     

    # 构建应用

    RUN npm run build

     

    # 运行应用

    CMD [ "npm", "start" ]

    SpringCloud微服务开发

    1、服务发现:SpringCloud Eureka

     

    微服务名:demo-eureka-server

     

    微服务端口:8761

     

    K8S:Deployment+Service+Ingress(因为要通过网址查看服务注册情况,所以要添加ingress)

     

    Pod名:demo-eureka-server

    2、服务配置:SpringCloud Config

     

    微服务名:demo-config-server

     

    微服务端口:8888

     

    K8S:Deployment+Service

     

    Pod名:demo-config-server

    3、服务认证和授权:SpringSecurity + Oauth2

     

    微服务名:demo-auth-service

     

    微服务端口:8901

     

    K8S:Deployment+Service

     

    Pod名:demo-auth-service

    4、服务网关:SpringCloud Zuul

     

    微服务名:demo-auth-service

     

    微服务端口:5555

     

    K8S:Deployment+Service+Ingress(服务网关是所有服务对外唯一入口,所以要配置ingress)

     

    Pod名:demo-auth-service

    5、编写Dockerfile、K8S yaml

    为了方便起见,上面的微服务名和Pod名都设置相同名称,具体的服务开发过程这里就暂时忽略,后面有时间再写篇搭建企业级微服务的文章吧,相关微服务的目录结构如下所示:

    注意:不同服务之间Dockerfile和k8s yaml文件大同小异,我们以Eureka为例:

    Eureka Dockerfile:

     

    FROM openjdk:8-jdk-alpine
    MAINTAINER "zhangwei"<zhangwei900808@126.com>
    RUN mkdir -p /usr/local/configsvr
    ARG JAR_FILE
    ADD ${JAR_FILE} /usr/local/configsvr/app.jar
    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/usr/local/configsvr/app.jar"]
    EXPOSE 8888

     

    Eureka K8S Yaml:

     

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/configuration-snippet: |
          rewrite ^/eureka/css/(.*)$ /eureka/eureka/css/$1 redirect;
          rewrite ^/eureka/js/(.*)$ /eureka/eureka/js/$1 redirect;
        nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
        nginx.ingress.kubernetes.io/rewrite-target: /$2
        nginx.ingress.kubernetes.io/service-weight: ''
      generation: 4
      name: <podname>-ingress
      namespace: default
    spec:
      rules:
      - host: baidu.com
        http:
          paths:
          - backend:
              serviceName: <podname>-svc
              servicePort: 8761
            path: /eureka(/|$)(.*)
            pathType: ImplementationSpecific
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: <podname>-svc
      namespace: default
    spec:
      externalTrafficPolicy: Local
      ports:
      - nodePort: 31061
        port: 8761
        protocol: TCP
        targetPort: 8761
      selector:
        app: <podname>
      sessionAffinity: None
      type: NodePort
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: '1'
      generation: 1
      labels:
        app: <podname>
      name: <podname>
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: <podname>
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: <podname>
        spec:
          containers:
          - env:
            - name: LANG
              value: C.UTF-8
            - name: JAVA_HOME
              value: /usr/lib/jvm/java-1.8-openjdk
            image: <imagename>
            imagePullPolicy: IfNotPresent
            name: <podname>
            ports:
            - containerPort: 8761
              protocol: TCP
            resources:
              requests:
                cpu: 250m
                memory: 512Mi
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30
    

     

      注意:不同的策服务bootstrap.yml和application.yml文件还是有所区别,比如下面这些:

    demo-auth-service、demo-zuul-server 配置bootstrap.yml文件添加SpringCloud Config地址:

     

    spring:
      application:
        name: authservice
      cloud:
        config:
          enabled: true
          # config的Server名
          uri: http://demo-config-server-svc:8888
    

     

    demo-auth-service、demo-zuul-server、demo-config-server 配置application.yml文件添加Eureka地址:

     

    eureka:
      instance:
        preferIpAddress: true
        hostname: demo-eureka-server-svc
      client:
        register-with-eureka: true
        fetch-registry: true
        service-url:
          # eureka的Server名
          defaultZone: http://demo-eureka-server-svc:8761/eureka/
    

     

      

     

    Git工作流

    按照Git工作流,一般我们可以分为:开发环境(develop)、测试环境(release)、预生产环境(uat)和生产环境(prop),对应的分支分别是:dev、test、release、master,因此不同阶段提交的代码所属分支也不相同,且dockerfile、jenkins pipline、k8s yaml文件也不相同,这个要注意下。

    Jenkins DevOps CI/CD

    1、视图规范

    jenkins可以按照git工作流添加:测试视图、预生产视图、生产视图,如下所示:

    2、创建流水线任务


    我们先创建流水线任务并编写pipline script脚本来创建CI/CD流水线步骤

    3、编写前端的pipline script

    先编写环境变量

     

    environment {
      GIT_REPOSITORY="前端代码仓库地址"
      K8S_YAML="k8s yaml文件所在目录"
      DOCKER_USERNAME="docker 仓库用户名"
      DOCKER_PWD="docker仓库密码"
      ALIYUN_DOCKER_HOST = '阿里云docker仓库域名'
      ALIYUN_DOCKER_NAMESPACE="阿里云docker仓库命名空间"
      ALIYUN_DOCKER_REPOSITORY_NAME="阿里云docker仓库命名空间下的仓库名"
    }
    

     

      

     

    步骤一:克隆代码

     

    stage("Clone") {
        steps {
            echo "1.Clone Stage"
             // 删除文件夹
            deleteDir()
            // 测试分支,jenkins-gitlab-ssh-hash是ssh密钥,替换成自己的就好
            git branch: 'test', credentialsId: 'jenkins-gitlab-ssh-hash', url: "${GIT_REPOSITORY}"
            script {
                // 获取git提交的hash值做为docker镜像tag
                GIT_TAG = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                // 组装成完整地址
                DOCKER_REPOSITORY = "${ALIYUN_DOCKER_HOST}/${ALIYUN_DOCKER_NAMESPACE}/${ALIYUN_DOCKER_REPOSITORY_NAME}"
                DOCKER_REPOSITORY_TAG = "${DOCKER_REPOSITORY}:${GIT_TAG}"
            }
        }
    }

      

    步骤二:代码测试

    stage("Test") {
        steps {
            echo "2.Test Stage"
        }
    }

      

    步骤三:制作docker镜像

    stage("Build") {
        steps {
            echo "3.Build Docker Image Stage"
            sh "docker build -t ${DOCKER_REPOSITORY_TAG} -f docker/Dockerfile ."
        }
    }

      

    步骤四:推送docker镜像

    stage("Push") {
        steps {
            echo "4.Push Docker Image Stage"
            //推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
            sh "docker login --username=${DOCKER_USERNAME} --password=${DOCKER_PWD} ${ALIYUN_DOCKER_HOST}"
    
            // 开始推送镜像到阿里云docker镜像仓库
            sh "docker push ${DOCKER_REPOSITORY_TAG}"
            // 删除jenkins生成的image
            sh '''
                docker images | grep seaurl | awk '{print $3}' | xargs docker rmi -f
            '''
        }
    }

      

    步骤五:k8s部署docker镜像

    stage("Deploy") {
        steps {
            echo "5.发布镜像"
            // 使用sed替换k8s yaml文件中的<imagename>和<podname>
            sh "sed -i 's#<imagename>#${DOCKER_REPOSITORY_TAG}#g;s#<podname>#${POD_NAME}#g' ${K8S_YAML}"
            // 执行应用k8s yaml
            sh "kubectl apply -f ${K8S_YAML}"
        }
    }

      

    sed 语法大家可以自行百度,这里我使用的是#分隔,而没有使用/分隔,原因是分隔的字符中包含/,所以不能再用。

    首先,我们来看看前端k8s yaml文件

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt-prod-http01
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
        nginx.ingress.kubernetes.io/service-weight: ''
      generation: 3
      name: <podname>-ingress
      namespace: default
    spec:
      rules:
        - host: baidu.com
          http:
            paths:
              - backend:
                  serviceName: <podname>-svc
                  servicePort: 3000
                path: /
                pathType: ImplementationSpecific
      tls:
        - hosts:
            - baidu.com
          secretName: <podname>-ingress
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: <podname>-svc
      namespace: default
    spec:
      ports:
        - port: 3000
          protocol: TCP
          targetPort: 3000
      selector:
        app: <podname>
      sessionAffinity: None
      type: ClusterIP
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: '1'
      generation: 1
      labels:
        app: <podname>
      name: <podname>
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: <podname>
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app:<podname>
        spec:
          containers:
            - image: <imagename>
              imagePullPolicy: IfNotPresent
              name: <podname>
              resources:
                requests:
                  cpu: 250m
                  memory: 512Mi

      

    上面的yaml文件中包含:deployment、service和ingress,ingress中配置了tls,因此可以使用https来访问域名,并且配置了nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'所以可以自动将http 跳转到https,其中里面的<podname>和<imagename>是要被sed替换成真实名称和地址。

    完整的pipline script脚本:

    pipeline {
        agent any
        environment {
          GIT_REPOSITORY="前端代码仓库地址"
          K8S_YAML="k8s yaml文件所在目录"
          DOCKER_USERNAME="docker 仓库用户名"
          DOCKER_PWD="docker仓库密码"
          ALIYUN_DOCKER_HOST = '阿里云docker仓库域名'
          ALIYUN_DOCKER_NAMESPACE="阿里云docker仓库命名空间"
          ALIYUN_DOCKER_REPOSITORY_NAME="阿里云docker仓库命名空间下的仓库名"
        }
        stages {
            stage("Clone") {
                steps {
                    echo "1.Clone Stage"
                     // 删除文件夹
                    deleteDir()
                    // 测试分支,jenkins-gitlab-ssh-hash是ssh密钥,替换成自己的就好
                    git branch: 'test', credentialsId: 'jenkins-gitlab-ssh-hash', url: "${GIT_REPOSITORY}"
                    script {
                        // 获取git提交的hash值做为docker镜像tag
                        GIT_TAG = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                        // 组装成完整地址
                        DOCKER_REPOSITORY = "${ALIYUN_DOCKER_HOST}/${ALIYUN_DOCKER_NAMESPACE}/${ALIYUN_DOCKER_REPOSITORY_NAME}"
                        DOCKER_REPOSITORY_TAG = "${DOCKER_REPOSITORY}:${GIT_TAG}"
                    }
                }
            }
            stage("Test") {
                steps {
                    echo "2.Test Stage"
                }
            }
            stage("Build") {
                steps {
                    echo "3.Build Docker Image Stage"
                    sh "docker build -t ${DOCKER_REPOSITORY_TAG} -f docker/Dockerfile ."
                }
            }
            stage("Push") {
                steps {
                    echo "4.Push Docker Image Stage"
                    //推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
                    sh "docker login --username=${DOCKER_USERNAME} --password=${DOCKER_PWD} ${ALIYUN_DOCKER_HOST}"
            
                    // 开始推送镜像到阿里云docker镜像仓库
                    sh "docker push ${DOCKER_REPOSITORY_TAG}"
                    // 删除jenkins生成的image
                    sh '''
                        docker images | grep seaurl | awk '{print $3}' | xargs docker rmi -f
                    '''
                }
            }
            stage("Deploy") {
                steps {
                    echo "5.发布镜像"
                    // 使用sed替换k8s yaml文件中的<imagename>和<podname>
                    sh "sed -i 's#<imagename>#${DOCKER_REPOSITORY_TAG}#g;s#<podname>#${POD_NAME}#g' ${K8S_YAML}"
                    // 执行应用k8s yaml
                    sh "kubectl apply -f ${K8S_YAML}"
                }
            }
        }
    }

      

    点击立即构建,如下所示:

    4、编写微服务的pipline script

    先编写环境变量

    environment {
        GIT_REPOSITORY="代码仓库地址"
        MODULE_NAME="maven 模块名"
        POD_NAME="k8s pod name"
        K8S_YAML="${MODULE_NAME}/src/main/k8s/eurekasvr.yaml"
        DOCKER_USERNAME="docker 仓库用户名"
        DOCKER_PWD="docker仓库密码"
        ALIYUN_DOCKER_HOST = 阿里云docker仓库域名'
        ALIYUN_DOCKER_NAMESPACE="阿里云docker仓库命名空间"
        ALIYUN_DOCKER_REPOSITORY_NAME="阿里云docker仓库命名空间下的仓库名"
    }

      

    步骤一:克隆代码

    stage("Clone") {
        steps {
            echo "1.Clone Stage"
             // 删除文件夹
            deleteDir()
            // 测试分支,jenkins-gitlab-ssh-hash是ssh密钥,替换成自己的就好
            git branch: 'test', credentialsId: 'jenkins-gitlab-ssh-hash', url: "${GIT_REPOSITORY}"
            script {
                // 获取git提交的hash值做为docker镜像tag
                GIT_TAG = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                // 组装成完整地址
                DOCKER_REPOSITORY = "${ALIYUN_DOCKER_HOST}/${ALIYUN_DOCKER_NAMESPACE}/${ALIYUN_DOCKER_REPOSITORY_NAME}"
                DOCKER_REPOSITORY_TAG = "${DOCKER_REPOSITORY}:${GIT_TAG}"
            }
        }
    }

      

    步骤二:代码测试

    stage("Test") {
        steps {
            echo "2.Test Stage"
        }
    }

      

    步骤三:制作docker镜像

    stage("Build") {
        steps {
            echo "3.Build Server"
            sh "mvn -e -U -pl ${MODULE_NAME} -am clean package -Dmaven.test.skip=true dockerfile:build -Ddockerfile.tag=${GIT_TAG} -Ddockerfile.repository=${DOCKER_REPOSITORY}"
        }
    }

      

    这里说明一下,因为我们使用的是maven 多模块所以打包编译的时候要分模块来打包,所以要使用-pl指定模块名,然后我们pom.xml中使用了dockerfile-maven-plugin,如下所示:

    <build>
        <plugins>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>dockerfile-maven-plugin</artifactId>
                <version>1.4.10</version>
                <configuration>
                    <!--  指定dockerfile所在目录-->
                    <dockerfile>src/main/docker/Dockerfile</dockerfile>
                    <buildArgs>
                        <!--提供参数向Dockerfile传递-->
                        <JAR_FILE>target/${project.build.finalName}.jar</JAR_FILE>
                    </buildArgs>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

      

    步骤四:推送docker镜像

     stage("Push") {
        steps {
            echo "4.Push Docker Image Stage"
            //推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
            sh "docker login --username=${DOCKER_USERNAME} --password=${DOCKER_PWD} ${ALIYUN_DOCKER_HOST}"
    
            // 开始推送镜像到阿里云docker镜像仓库
            sh "docker push ${DOCKER_REPOSITORY_TAG}"
            // 删除jenkins生成的image
            sh '''
                docker images | grep seaurl | awk '{print $3}' | xargs docker rmi -f
            '''
        }
    }
            

      

    步骤五:k8s部署docker镜像

    stage("Deploy") {
        steps {
            echo "5.发布镜像"
            // 使用sed替换k8s yaml文件中的<imagename>和<podname>
            sh "sed -i 's#<imagename>#${DOCKER_REPOSITORY_TAG}#g;s#<podname>#${POD_NAME}#g' ${K8S_YAML}"
            // 执行应用k8s yaml
            sh "kubectl apply -f ${K8S_YAML}"
        }
    }

      

    sed 语法大家可以自行百度,这里我使用的是#分隔,而没有使用/分隔,原因是分隔的字符中包含/,所以不能再用。

    首先,我们来看看Eureka k8s yaml文件

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        nginx.ingress.kubernetes.io/configuration-snippet: |
          rewrite ^/eureka/css/(.*)$ /eureka/eureka/css/$1 redirect;
          rewrite ^/eureka/js/(.*)$ /eureka/eureka/js/$1 redirect;
        nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'
        nginx.ingress.kubernetes.io/rewrite-target: /$2
        nginx.ingress.kubernetes.io/service-weight: ''
      generation: 4
      name: <podname>-ingress
      namespace: default
    spec:
      rules:
      - host: baidu.com
        http:
          paths:
          - backend:
              serviceName: <podname>-svc
              servicePort: 8761
            path: /eureka(/|$)(.*)
            pathType: ImplementationSpecific
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: <podname>-svc
      namespace: default
    spec:
      externalTrafficPolicy: Local
      ports:
      - nodePort: 31061
        port: 8761
        protocol: TCP
        targetPort: 8761
      selector:
        app: <podname>
      sessionAffinity: None
      type: NodePort
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      annotations:
        deployment.kubernetes.io/revision: '1'
      generation: 1
      labels:
        app: <podname>
      name: <podname>
      namespace: default
    spec:
      progressDeadlineSeconds: 600
      replicas: 1
      revisionHistoryLimit: 10
      selector:
        matchLabels:
          app: <podname>
      strategy:
        rollingUpdate:
          maxSurge: 25%
          maxUnavailable: 25%
        type: RollingUpdate
      template:
        metadata:
          labels:
            app: <podname>
        spec:
          containers:
          - env:
            - name: LANG
              value: C.UTF-8
            - name: JAVA_HOME
              value: /usr/lib/jvm/java-1.8-openjdk
            image: <imagename>
            imagePullPolicy: IfNotPresent
            name: <podname>
            ports:
            - containerPort: 8761
              protocol: TCP
            resources:
              requests:
                cpu: 250m
                memory: 512Mi
            terminationMessagePath: /dev/termination-log
            terminationMessagePolicy: File
          dnsPolicy: ClusterFirst
          restartPolicy: Always
          schedulerName: default-scheduler
          securityContext: {}
          terminationGracePeriodSeconds: 30

      

    上面的yaml文件中包含:deployment、service和ingress,ingress中配置了tls,因此可以使用https来访问域名,并且配置了nginx.ingress.kubernetes.io/force-ssl-redirect: 'true'所以可以自动将http 跳转到https,其中里面的<podname>和<imagename>是要被sed替换成真实名称和地址。

    完整的pipline script脚本:

    pipeline {
        agent any
        environment {
            GIT_REPOSITORY="代码仓库地址"
            MODULE_NAME="maven 模块名"
            POD_NAME="k8s pod name"
            K8S_YAML="${MODULE_NAME}/src/main/k8s/eurekasvr.yaml"
            DOCKER_USERNAME="docker 仓库用户名"
            DOCKER_PWD="docker仓库密码"
            ALIYUN_DOCKER_HOST = 阿里云docker仓库域名'
            ALIYUN_DOCKER_NAMESPACE="阿里云docker仓库命名空间"
            ALIYUN_DOCKER_REPOSITORY_NAME="阿里云docker仓库命名空间下的仓库名"
        }
        stages {
            stage("Clone") {
                steps {
                    echo "1.Clone Stage"
                    // 删除文件夹
                    deleteDir()
                    git branch: 'test',credentialsId: '1297dda3-e592-4e70-8fb0-087a26c08db0', url: "${GIT_REPOSITORY}"
                    script {
                        // 获取git代码tag为docker仓库tag
                        // GIT_TAG = sh(returnStdout: true,script: 'git describe --tags --always').trim()
                        // 获取git提交hash做为docker仓库tag
                        GIT_TAG = sh(returnStdout: true, script: 'git rev-parse --short HEAD').trim()
                        DOCKER_REPOSITORY = "${ALIYUN_DOCKER_HOST}/${ALIYUN_DOCKER_NAMESPACE}/${ALIYUN_DOCKER_REPOSITORY_NAME}"
                        // docker 阿里镜像仓库
                        DOCKER_REPOSITORY_TAG = "${DOCKER_REPOSITORY}:${GIT_TAG}"
                    }
                }
            }
            stage("Test") {
                steps {
                    echo "2.Test Stage"
                }
            }
            stage("Build") {
                steps {
                    echo "3.Build Server"
                    sh "mvn -e -U -pl ${MODULE_NAME} -am clean package -Dmaven.test.skip=true dockerfile:build -Ddockerfile.tag=${GIT_TAG} -Ddockerfile.repository=${DOCKER_REPOSITORY}"
                }
            }
             stage("Push") {
                steps {
                    echo "4.Push Docker Image Stage"
                    //推送Docker镜像,username 跟 password 为 阿里云容器镜像服务的账号密码
                    sh "docker login --username=${DOCKER_USERNAME} --password=${DOCKER_PWD} ${ALIYUN_DOCKER_HOST}"
            
                    // 开始推送镜像到阿里云docker镜像仓库
                    sh "docker push ${DOCKER_REPOSITORY_TAG}"
                    // 删除jenkins生成的image
                    sh '''
                        docker images | grep seaurl | awk '{print $3}' | xargs docker rmi -f
                    '''
                }
            }
            stage("Deploy") {
                steps {
                    echo "5.发布镜像"
                    sh "sed -i 's#<dockerrepository>#${DOCKER_REPOSITORY_TAG}#g;s#<podname>#${POD_NAME}#g' ${K8S_YAML}"
                    sh "kubectl apply -f ${K8S_YAML}"
                }
            }
        }
    }
    

     

      

    点击立即构建,如下所示:

    查看k8s是否成功

    可以通过命令

    kubectl get deploy

    kubectl get pod

    kubectl get svc

    kubectl get ingress

    还可以查看pod日志,对其成功或失败进行分析:

    kubectl logs podname

    访问Eureka

    postman访问微服务接口地址

    可以通过postman接口访问对外的zuul地址,查看是否可以认证通过:

    浏览器访问Web页面地址

    可以通过next.js的部署地址,查看是否部署成功:

    总结

    1、jenkins pipline script脚本和Dockerfile写法网上各式各样,大家找到一个符合标准的就好
    2、kubectl apply -f 的作用是:如果没有创建deployment就会创建,否则就更新
    3、微服务k8s yaml文件中Service要设置type: NodePort否则,微服务间不能通信
    4、jenkins 编译微服务的maven模块要用到-pl 和 dockerfile-maven-plugin
    5、微服务如果要用k8s ingress要设置https,以及http自动跳转到https

    引用

    JenkinsPipeline部署一个Kubernetes 应用
    采用jenkins pipeline实现自动构建并部署至k8s
    Configuring-CI-CD-on-Kubernetes-with-Jenkins
    spring-k8s
    jenkins pipeline
    自动构建并部署至k8s
    微服务实战(一)基于OAUTH2.0统一认证授权的微服务基础架构
    使用cert-manager申请免费的HTTPS证书
    SPRINGBOOT利用SPRING.PROFILES.ACTIVE=@SPRING.ACTIVE@不同环境下灵活切换配置文件
    https://kuboard.cn/learning/k8s-practice/ocp/eureka-server.html#%E6%9F%A5%E7%9C%8B%E9%83%A8%E7%BD%B2%E7%BB%93%E6%9E%9C
    kubernetes部署微服务spring cloud的简单例子
    k8s-nginx-ingress eureka二级路径转发的问题

    转自:https://segmentfault.com/a/1190000040119257?utm_source=tag-newest

  • 相关阅读:
    二、java基本语法
    LINQ入门教程之各种标准查询操作符(一)
    LINQ入门教程之各种标准查询操作符(二)
    读《穷爸爸 富爸爸》有想
    考考你的逻辑推理能力
    读《自控力》有感
    读大数据有感
    django.core.exceptions.AppRegistryNotReady: Models aren't loaded yet.的解决办法
    RabbitMQ入门
    ubuntu安装mysql可视化工具MySQL-workbench及简单操作
  • 原文地址:https://www.cnblogs.com/zcyy/p/15662300.html
Copyright © 2011-2022 走看看