天天看点

一键部署 SpringCloud 微服务,yyds!

作者:老诚不bug

一键部署springcloud微服务,需要用到 Jenkins K8S Docker等工具,自行安装即可。

本文使用jenkins部署,流程如下图

一键部署 SpringCloud 微服务,yyds!
  • 开发者将代码push到git
  • 运维人员通过jenkins部署,自动到git上pull代码
  • 通过maven构建代码
  • 将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry
  • 通过k8s发起 发布/更新 服务 操作

其中 2~5步骤都会在jenkins中进行操作

1、开发者将代码PUSH到Git

这一步本文不做详细描述

2、通过Jenkins部署,自动到Git上PULL代码

这里需要用到Jenkins 的 pipeline插件

2.1、 配置SSH-KEY

因为jenkins需要pull git上的代码,正常来说,代码都是私有的,git clone操作的时候会需要密码,就不能完成自动化操作了。这里使用SSH-KEY 的方式,让git clone操作无需密码就能完成克隆

2.1.1、生成/添加SSH公钥

在jenkins所在环境里执行

ssh-keygen -t ed25519 -C "[email protected]"  
           

注意:这里的 [email protected] 只是生成的 sshkey 的名称,并不约束或要求具体命名为某个邮箱

现网的大部分教程均讲解的使用邮箱生成,其一开始的初衷仅仅是为了便于辨识所以使用了邮箱

按照提示完成三次回车,即可生成 ssh key。通过查看 ~/.ssh/id_ed25519.pub 文件内容,获取到你的 public key

一键部署 SpringCloud 微服务,yyds!

得到公钥 public key 内容

cat ~/.ssh/id_ed25519.pub
           

复制备用

2.1.2、将公钥配置到git平台

git平台可以是github,gitee,也可以是自己搭建的gitlab等

我这里使用gitee

通过仓库主页 「管理」->「部署公钥管理」->「添加部署公钥」 ,添加生成的 public key 添加到仓库中。

一键部署 SpringCloud 微服务,yyds!

添加成功后,到jenkins所在环境运行

ssh -T [email protected]
           
一键部署 SpringCloud 微服务,yyds!

首次使用需要确认并添加主机到本机SSH可信列表。若返回 Hi XXX! You’ve successfully authenticated, but Gitee.com does not provide shell access. 内容,则证明添加成功

2.1.3、测试

复制你项目的SSH链接

一键部署 SpringCloud 微服务,yyds!

在jenkins所在环境

执行git clone [email protected]:xxxx.git

一键部署 SpringCloud 微服务,yyds!

2.2、配置Jenkins的pipeline 自动clone代码

2.2.1、Jenkins创建任务

新建任务

一键部署 SpringCloud 微服务,yyds!

选择流水线 确定

一键部署 SpringCloud 微服务,yyds!

这里勾选参数化构建,选择字符参数,用于输入构建代码的版本

一键部署 SpringCloud 微服务,yyds!

在这里插入图片描述

默认值填master,根据自身项目实际填写

一键部署 SpringCloud 微服务,yyds!

拉到最下面的流水线,写pipeline脚本,如果不知道怎么写,可以点击流水线语法进行参考

一键部署 SpringCloud 微服务,yyds!

这是我的脚本, REPOSITORY 填写项目的ssh地址,REPOSITORY_VERSION是刚刚配置的构建参数

pipeline {
    agent any
    
    environment {
        REPOSITORY="[email protected]:xxxxxx/cloud-demo.git"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
    }
}
           

保存

2.2.2、测试拉代码流程

返回Jenkins 首页,选择刚刚创建的项目

一键部署 SpringCloud 微服务,yyds!

在这里插入图片描述

点击右边的运行按钮

一键部署 SpringCloud 微服务,yyds!

输入代码分支版本

点击开始构建

一键部署 SpringCloud 微服务,yyds!

在这里插入图片描述

看到这里就是已经构建成功了

一键部署 SpringCloud 微服务,yyds!

根据日志提示的目录,可以看到目录下已经有代码了

3、通过maven构建代码

3.1、maven插件安装

因为这里使用到了maven,jenkins需要先安装maven工具

3.2、maven构建项目

补充pipeline脚本

pipeline {
    agent any
    
    environment {
        REPOSITORY="[email protected]:xxxxxx/cloud-demo.git"
        MODULE="cloud-demo-m-test-dubbo-service"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && mvn -U -am clean package"
            }
        }
    }
}
           

这里补充了stage('编译代码') {} 部分,用于maven编译。具体编译脚本需要根据自己项目实际,这个是我项目的编译必须步骤。

3.3、测试拉代码流程+构建项目过程

重复2.2.2步骤,查看运行结果

一键部署 SpringCloud 微服务,yyds!

构建成功

4、将maven构建后的jar打包成docker镜像 并 push docker镜像到docker registry

在jenkins环境下

创建目录用于存放脚本文件

mkdir /usr/local/project/.env/cloud-demo-m-test-dubbo-service/ -p
           

这个目录下存放4个文件

  • build.sh
  • Dockerfile
  • application.properties
  • bootstrap.properties

application.properties 和 bootstrap.properties 是springcloud的配置文件,内容根据自己项目情况

buils.sh 文件内容

#!/usr/bin/env bash

REPOSITORY_VERSION=$1
GIT_REVISION=`git log -1 --pretty=format:"%h"`
TIME=`date "+%Y.%m.%d.%H.%M"`
IMAGE_NAME=192.168.31.100:5000/cloud-demo/cloud-demo-m-test-dubbo-service
IMAGE_TAG=${REPOSITORY_VERSION}-${GIT_REVISION}-${TIME}

docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .

docker push ${IMAGE_NAME}:${IMAGE_TAG}

echo "${IMAGE_NAME}:${IMAGE_TAG}" > IMAGE
## 内容说明
REPOSITORY_VERSION 是需要传入的参数,传项目git分支名,用于打标签使用
GIT_REVISION 是获取当前git的提交版本 如 c9c8525,线上问题可以根据这个版本查找具体代码问题
TIME 年.月.日.时.分  记录打包时间,也用于打标签使用
IMAGE_NAME 镜像名,这里前缀包含了192.168.31.100:5000 是因为我打包之后会push到192.168.31.100:5000,其他服务器可以到这里来pull镜像
docker build -t ${IMAGE_NAME}:${IMAGE_TAG} . 构建镜像
docker push ${IMAGE_NAME}:${IMAGE_TAG}  推送镜像
echo "${IMAGE_NAME}:${IMAGE_TAG}" > IMAGE  把镜像名:镜像标签 输出到IMAGE文件里,方便后续步骤获取
           

Dockerfile 文件内容

FROM openjdk:8u342-jdk
MAINTAINER yanger [email protected]

COPY target/cloud-demo-m-test-dubbo-service-1.0-SNAPSHOT.jar /cloud-demo-m-test-dubbo-service.jar
COPY application.properties /application.properties
COPY bootstrap.properties /bootstrap.properties
ENTRYPOINT ["java", "-jar", "/cloud-demo-m-test-dubbo-service.jar"]
## 内容说明
FROM openjdk:8u342-jdk 使用openjdk:8u342-jdk 作为基础镜像
COPY 文件到镜像
ENTRYPOINT ["java", "-jar", "/cloud-demo-m-test-dubbo-service.jar"] 启动时运行 java -jar /cloud-demo-m-test-dubbo-service.jar
           

这里用到了docker registry 如果还没有registry 请先启动,可以用docker的方式启动

docker run -d -p 5000:5000 --name registry registry
           

build.sh文件需要可执行权限

chmod 755 build.sh
           

补充pipeline脚本

pipeline {
    agent any
    
    environment {
        REPOSITORY="[email protected]:xxxxxx/cloud-demo.git"
        SCRIPT_PATH="/usr/local/project/.env/cloud-demo-m-test-dubbo-service/"
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && /usr/local/maven/bin/mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && /usr/local/maven/bin/mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && /usr/local/maven/bin/mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && /usr/local/maven/bin/mvn -U -am clean package"
            }
        }

        stage('构建镜像') {
            steps {
                echo "start build image"
                sh "cp ${SCRIPT_PATH}/build.sh cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/Dockerfile cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/application.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/bootstrap.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/ && ./build.sh ${REPOSITORY_VERSION}"
            }
        }

    }
}
           

补充了stage(‘构建镜像’){} 内容和 environment 部分加了个参数 SCRIPT_PATH

SCRIPT_PATH参数是上面创建的文件夹路径

stage(‘构建镜像’){}这一步是复制相应文件到项目目录下,并且执行build.sh脚本

测试

一键部署 SpringCloud 微服务,yyds!

可以看到镜像已经打包好,并且已经push到registry了

浏览器访问http://192.168.31.100:5000/v2/cloud-demo/cloud-demo-m-test-dubbo-service/tags/list

可以看到registry有cloud-demo/cloud-demo-m-test-dubbo-service:master-7012e1d-2023.05.01.10.16这个镜像

5、通过k8s发起 发布/更新 服务 操作

5.1、配置构建K8S资源的描述文件

在 /usr/local/project/.env/cloud-demo-m-test-dubbo-service/ 目录新增文件 cloud-demo-m-test-dubbo-service.yaml

文件内容

apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: cloud-demo-m-test-dubbo-service
  name: cloud-demo-m-test-dubbo-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cloud-demo-m-test-dubbo-service
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: cloud-demo-m-test-dubbo-service
    spec:
      containers:
      - image: IMAGE_AND_TAG
        name: cloud-demo-m-test-dubbo-service
        resources: {}
        volumeMounts: 
        - name: log-path
          mountPath: /logs
      volumes: 
      - name: log-path
        hostPath: 
          path: /root/k8s/cloud-demo-m-test-dubbo-service/logs
status: {}

---

apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: cloud-demo-m-test-dubbo-service
  name: cloud-demo-m-test-dubbo-service
spec:
  ports:
  - port: 20881
    protocol: TCP
    targetPort: 20881
  selector:
    app: cloud-demo-m-test-dubbo-service
  type: NodePort
status:
  loadBalancer: {}
           

这个文件是构建K8S资源的描述文件,创建deployment 和service,暴露端口20881,挂载/logs目录到主机

其中 IMAGE_AND_TAG 是需要替换为相应 容器名:容器标签 的

5.2、完善jenkins步骤

pipeline {
    agent any
    
    environment {
        REPOSITORY="[email protected]:xxxxxx/cloud-demo.git"
        SCRIPT_PATH="/usr/local/project/.env/cloud-demo-m-test-dubbo-service"
        IMAGE=""
    }
    
    stages {
        stage('拉代码') {
            steps {
                echo "start fetch code from git:${REPOSITORY}"
                deleteDir()
                git branch: "${REPOSITORY_VERSION}", url: "${REPOSITORY}"
            }
        }
        
        stage('编译代码') {
            steps {
                echo "start compile"
                sh "cd cloud-demo-project && /usr/local/maven/bin/mvn -U clean install"
                echo "compile project ................................"
                sh "cd cloud-demo-dependencies && /usr/local/maven/bin/mvn -U clean install"
                echo "compile dependencies ................................"
                sh "cd cloud-demo-common && /usr/local/maven/bin/mvn -U clean install"
                echo "compile common ................................"
                sh "cd cloud-demo-m-test && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test ................................"
                sh "cd cloud-demo-m-test/cloud-demo-m-test-common && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-api ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-api && /usr/local/maven/bin/mvn -U -am clean install"
                echo "compile m-test-dubbo-service ................................"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service && /usr/local/maven/bin/mvn -U -am clean package"
            }
        }

        stage('构建镜像') {
            steps {
                echo "start build image"
                sh "cp ${SCRIPT_PATH}/build.sh cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/Dockerfile cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/application.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cp ${SCRIPT_PATH}/bootstrap.properties cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "cd cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/ && ./build.sh ${REPOSITORY_VERSION}"
            }
        }

        stage('发布') {
            steps {
                echo "start deploy"
                script {
                    IMAGE = readFile "cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/IMAGE"
                    IMAGE = IMAGE.trim()
                    if (IMAGE == "") {
                        throw new Exception("获取镜像名文件失败,请重试")
                    }
                }
                echo "IMAGE: -- ${IMAGE}"
                sh "cp ${SCRIPT_PATH}/cloud-demo-m-test-dubbo-service.yaml cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/"
                sh "sed -i \"s#IMAGE_AND_TAG#${IMAGE}#g\" cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/cloud-demo-m-test-dubbo-service.yaml"
                sh "kubectl apply -f cloud-demo-m-test/dubbo/cloud-demo-m-test-dubbo-service/cloud-demo-m-test-dubbo-service.yaml"
            }
        }
    }
}
           

添加了 stage('发布') {} 部分

  • 通过读取IMAGE文件,获取镜像名:镜像标签
  • 如果获取不到镜像名:镜像标签,抛出异常
  • 将cloud-demo-m-test-dubbo-service.yaml文件复制到工作目录
  • 用镜像名:镜像标签 替换掉 IMAGE_AND_TAG
  • 使用kubectl命令发布/更新服务

5.3、测试

在jenkins上构建项目

一键部署 SpringCloud 微服务,yyds!

在K8S master服务器上,执行

kubectl get all
           
一键部署 SpringCloud 微服务,yyds!

搞定

来源:https://mp.weixin.qq.com/s/HXj5YvANMIpceaspBWjmgg

继续阅读