5

Preface

Recently, I am learning how to use jenkins and Alibaba Cloud k8s to automatically integrate and deploy the springcloud microservice and front-end next.js project. Now I record it and share it with everyone. If there is anything wrong with the article, I hope the big guys can criticize and correct me.

DevOps CI/CD process

image.png

Object-oriented

  • Familiar with vue or react
  • Proficiency in using SpringCloud microservices
  • Proficiency in using docker containers
  • Proficiency in using jenkins automated operation and maintenance tools
  • Familiar with k8s (deployment, service, ingress)

Ready to work

1. Purchase Alibaba Cloud ACK cluster (or build it

I bought the Alibaba Cloud ACK hosting version, create a cluster address

Note: There is no charge for creating an ACK cluster. The charge is for the NAT gateway, SLB load balancing, ECS server, etc.

2. Install gitlab

Here I wrote an article on Alibaba Cloud ECS to build gitlab, install gitlab address

3. Install jenkins

Here I wrote an article on Alibaba Cloud ECS to build jenkins, install jenkins address

4. Install docker

Use official website recommended yum installation is more convenient, the installation is as follows:

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

system structure

image.png

Next.js front-end development

Next.js project:

服务: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" ]

image.png

SpringCloud microservice development

1. Service discovery: SpringCloud Eureka


微服务名:demo-eureka-server

微服务端口:8761,

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

Pod名:demo-eureka-server

2. Service configuration: SpringCloud Config


微服务名:demo-config-server

微服务端口:8888,

K8S:Deployment+Service

Pod名:demo-config-server

3. Service authentication and authorization: SpringSecurity + Oauth2


微服务名:demo-auth-service

微服务端口:8901,

K8S:Deployment+Service

Pod名:demo-auth-service

4. Service gateway: SpringCloud Zuul


微服务名:demo-auth-service

微服务端口:5555,

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

Pod名:demo-auth-service

5. Write Dockerfile, K8S yaml

For convenience, the above microservice name and Pod name are both set to the same name. The specific service development process is temporarily ignored here. I will write an article on building enterprise-level microservices later when I have time. The directory structure of related microservices is as follows :

image.png

Note: Dockerfile and k8s yaml files are similar between different services. Let’s take Eureka as an example:

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

Note: Bootstrap.yml and application.yml files are different for different policy services, such as the following:

In demo-auth-service, demo-zuul-server configuration bootstrap.yml file add SpringCloud Config address:

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

Add the Eureka address to the demo-auth-service, demo-zuul-server, demo-config-server configuration application.yml file:

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 workflow

According to the Git workflow, we can generally be divided into: development environment (develop), test environment (release), pre-production environment (uat) and production environment (prop), the corresponding branches are: dev, test, release, master, Therefore, the branches of the code submitted in different stages are not the same, and the dockerfile, jenkins pipline, and k8s yaml files are also different. Please pay attention to this.
image.png

Jenkins DevOps CI/CD

1. View specification

Jenkins can be added according to the git workflow: test view, pre-production view, production view, as shown below:
image.png

2. Create a pipeline task

image.png
We first create a pipeline task and write a pipline script script to create CI/CD pipeline steps

3. Write front-end pipline script

First write environment variables

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仓库命名空间下的仓库名"
}

Step 1: Clone the code

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}"
        }
    }
}

Step 2: Code Test

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

Step 3: Make docker image

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

Step 4: Push the docker image

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
        '''
    }
}

Step 5: k8s deploys docker image

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}"
    }
}

You can use Baidu for sed grammar yourself. Here I use # separation instead of / separation. The reason is that the separated character contains /, so it can't be used anymore.

First, let's take a look at the front-end k8s yaml file

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

The above yaml file contains: deployment, service, and ingress. Ingress is configured with tls, so you can use https to access the domain name, and configure nginx.ingress.kubernetes.io/force-ssl-redirect: 'true' so you can automatically jump http to https, where <podname> and <imagename are included > Is to be replaced by sed with the real name and address.

complete pipline script 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}"
            }
        }
    }
}

Click Build Now, as shown below:
image.png

4. Write a pipline script for microservices

First write environment variables

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仓库命名空间下的仓库名"
}

Step 1: Clone the code

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}"
        }
    }
}

Step 2: Code test

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

Step 3: Make docker image

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}"
    }
}

Here to explain, because we are using maven multi-modules, we need to package them in modules when compiling, so we need to use -pl to specify the module name, and then we use dockerfile-maven-plugin in pom.xml, as shown below:

<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>

Step 4: Push the docker image

 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
        '''
    }
}
        

Step 5: k8s deploys docker image

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}"
    }
}

You can use Baidu for sed grammar yourself. Here I use # separation instead of / separation. The reason is that the separated character contains /, so it can't be used anymore.

First, let's take a look at the Eureka k8s yaml file

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

The above yaml file contains: deployment, service and ingress. Ingress is configured with tls, so you can use https to access the domain name, and is configured with nginx.ingress.kubernetes.io/force-ssl-redirect: 'true' so you can automatically jump http to https, where <podname> and <imagename are included > Is to be replaced by sed with the real name and address.

complete pipline script 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}"
            }
        }
    }
}

Click Build Now, as shown below:
image.png

Check whether k8s is successful

You can pass the command

kubectl get deploy
kubectl get pod
kubectl get svc
kubectl get ingress

image.png

You can also view the pod log to analyze its success or failure:

kubectl logs podname

Visit Eureka

image.png

Postman access microservice interface address

You can access the external zuul address through the postman interface to see if it can be authenticated:
image.png

Browser access web page address

You can check whether the deployment is successful through the deployment address of next.js:
image.png

to sum up

1. Jenkins pipline script and Dockerfile are written in various ways on the Internet. Just find one that meets the standard.
2. The function of kubectl apply -f is: if deployment is not created, it will be created, otherwise it will be updated
3. The Service in the microservice k8s yaml file should be set to type: NodePort otherwise, the microservices cannot communicate
4. Jenkins uses -pl and dockerfile-maven-plugin to compile the maven module of microservices
5. If you want to use k8s ingress for microservices, you need to set https, and http will automatically jump to https

Quote

JenkinsPipeline deploys a Kubernetes application
uses jenkins pipeline to automatically build and deploy to k8s
Configuring-CI-CD-on-Kubernetes-with-Jenkins
spring-k8s
jenkins pipeline is automatically built and deployed to k8s
combat (1) Microservice infrastructure based on OAUTH2.0 unified authentication and authorization
Use cert-manager to apply for a free HTTPS certificate
SPRINGBOOT uses SPRING.PROFILES.ACTIVE=@SPRING.ACTIVE@ to switch configuration files flexibly in different environments
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 simple example of
k8s-nginx-ingress eureka secondary path forwarding problem


Awbeci
3.1k 声望212 粉丝

Awbeci