基于Fabric8将SpringBoot工程快速构建镜像并发布到k8s详细教程

前言

在当下风靡的云计算生态中,Docker从发布开始就引领这容器化技术的潮流,Docker非常适合管理单个容器。但是如果我们的分布式应用系统是由多个容器组成的,随着系统地迭代演化,使用越来越多的容器和容器化应用程序,并处于高并发、高可用等考虑将其划分为数百个部分,很可能会导致管理和编排变得非常困难。我们迫切需要对容器实施分组,以便跨所有容器提供网络、存储、安全、遥测等服务,于是,Kubernetes 应运而生。

Kubernetes 介绍

Kubernetes,又称为 k8s或者简称为 “kube” ,是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。也就是说,您可以将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助您轻松高效地管理这些集群。而且,这些集群可跨公共云、私有云或混合云部署主机。因此,对于要求快速扩展的云原生应用而言(例如借助 Apache Kafka 进行的实时数据流处理),Kubernetes 是理想的托管平台。

传统将SpringBoot应用发布到K8s的方式

由于k8s的技术不断趋向成熟,逐渐成为应用管理的主流,就SpringBoot应用来说,如何实现将应用发布到k8s平台需要以下几个步骤:

image-20200718225935393

在这几个步骤中需要团队具备构建Docker镜像能力以及k8s配置能力,实施起来比较麻烦,而且需要另外去管理docker配置以及k8s的配置,对于开发或者负责上线的同事来说,发布应用不是一键就能搞定的事情,都说我们要搞敏捷、我们要搞DevOps、持续集成,Docker以及k8s都是好技术,但是过于麻烦且不简单的步骤,确实是大部分公司或者项目想转型DevOps的门槛。 后来jenkins的出现,自动化流水线的出现让我不禁想起了第一次工业革命,确实提高了生产力,我们终于不用再每次sshsftpdocker buildkubectl apply

惊呆!

有了第一次依赖脚本自动化执行的工业革命, 是不是就够了?

还不够

我们需要进一步降低SpringBoot工程构建Docker的配置以及k8s配置的难度,让就算是一个不怎么会docker镜像构建以及k8s应用构建的开发者也能快速实现将工程一句命令发布上去,这个时代,我称之为“第二次工业革命”。

这个时代的关键工具就是----Fabric8

Fabric8介绍

Fabric是我这个搞区块链的天天对着的单词,偶尔在github逛一下就遇到与他相似八九分的朋友Fabric8。

Fabric8是什么?

fabric8是一个开源集成开发平台,为基于KubernetesJenkins的微服务提供持续发布

使用fabric可以很方便的通过Continuous Delivery pipelines创建、编译、部署和测试微服务,然后通过Continuous Improvement和ChatOps运行和管理他们。

Fabric8微服务平台提供:

正文介绍

本文接下来将基于fabric8提供的maven plugin将springboot应用通过pom.xml文件配置快速发布到k8s上。

实践

环境准备

系统环境/依赖 版本 备注
Ubuntu16.04 16.04 开发/编译环境系统
Java 1.8
SpringBoot 2.1
Maven 3.3.9
k8s 1.16.1
fabric8-maven-plugin 4.0.0 https://github.com/fabric8io/fabric8-maven-plugin
docker 18.04

工程配置

首先fabric8-maven-plugin作为一个maven插件,对应用的代码是无引入性的,所以基本所有springboot工程应用都可直接在POM里面添加maven插件配置即可实现将应用一句命令发布到k8s。

接下来会讲到fabric8-maven-plugin默认配置方式基于xml配置方式外部文件配置方式 帮助我们一句命令将Springboot应用直接发布到k8s。

默认配置方式

默认配置方式顾名思义就是不作任何自定义处理,实现如下:

  1. 编辑pom.xml
 <plugin>
      <groupId>io.fabric8</groupId>
      <artifactId>fabric8-maven-plugin</artifactId>
      <version>${fabric8.maven.plugin.version}</version>
      <executions>
          <execution>
             <goals>
                <goal>resource</goal>
                <goal>build</goal>
                </goals>
            </execution>
     </executions>
                             
    </plugin>

  1. 发布应用到k8s

    一般我的操作就是

    mvn fabric8:deploy
    

    然后构建镜像发布应用到k8s就搞完了。

    下面是mvn执行的主要日志

    [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ test ---
    [INFO] Building jar: /home/lps/servers/jenkins/workspace/test-pipe1/target/test-2.0.2.RELEASE.jar
    [INFO] 
    [INFO] --- sofa-ark-maven-plugin:1.1.1:repackage (default-cli) @ test ---
    [INFO] 
    [INFO] --- spring-boot-maven-plugin:1.4.2.RELEASE:repackage (default) @ test ---
    [INFO] 
    [INFO] --- fabric8-maven-plugin:4.3.1:build (default) @ test ---
    [INFO] F8: Pulling from java-alpine-openjdk8-jdk
    [INFO] F8: Digest: sha256:e8a8e8f5fcd3b545c48ade9ab5716e9414c6f60a60f07a388ff9fafbd
    [INFO] F8: Status: Downloaded newer image for registry.testdemo.com/java-alpine-openjdk8-jdk:latest
    [INFO] F8: Pulled registry.testdemo.com/java-alpine-openjdk8-jdk:latest in 588 milliseconds
    [INFO] Reading assembly descriptor: /home/lps/servers/jenkins/workspace/test-pipe1/src/main/docker/assembly.xml
    [INFO] Copying files to /home/lps/servers/jenkins/workspace/test-pipe1/target/docker/testdemo/test/2.0.2.RELEASE/build/maven
    [INFO] Building tar: /home/lps/servers/jenkins/workspace/test-pipe1/target/docker/testdemo/test/2.0.2.RELEASE/tmp/docker-build.tar
    [INFO] F8: [testdemo/test:2.0.2.RELEASE]: Created docker-build.tar in 2 seconds 
    [INFO] F8: [testdemo/test:2.0.2.RELEASE]: Built image sha256:486a1
    [INFO] 
    [INFO] --- maven-install-plugin:2.4:install (default-install) @ test ---
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/test-2.0.2.RELEASE.jar to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE.jar
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/pom.xml to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE.pom
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/classes/META-INF/fabric8/kubernetes.yml to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-kubernetes.yml
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/classes/META-INF/fabric8/openshift.yml to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-openshift.yml
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/test-2.0.2.RELEASE-sources.jar to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-sources.jar
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/classes/META-INF/fabric8/kubernetes.yml to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-kubernetes.yml
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/classes/META-INF/fabric8/openshift.yml to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-openshift.yml
    [INFO] Installing /home/lps/servers/jenkins/workspace/test-pipe1/target/test-2.0.2.RELEASE-sources.jar to /root/.m2/repository/com/testdemo/test/2.0.2.RELEASE/test-2.0.2.RELEASE-sources.jar
    [INFO] 
    [INFO] <<< fabric8-maven-plugin:4.3.1:deploy (default-cli) < install @ test <<<
    [INFO] 
    [INFO] 
    [INFO] --- fabric8-maven-plugin:4.3.1:deploy (default-cli) @ test ---
    [INFO] F8: Using Kubernetes at https://localhost:6443/ in namespace baas-test with manifest /home/lps/servers/jenkins/workspace/test-pipe1/target/classes/META-INF/fabric8/kubernetes.yml 
    [INFO] F8: Using namespace: baas-test
    [INFO] F8: Using namespace: baas-test
    [INFO] F8: Updating a Service from kubernetes.yml
    [INFO] F8: Updated Service: target/fabric8/applyJson/baas-test/service-test.json
    [INFO] F8: Using namespace: baas-test
    [INFO] F8: Updating ConfigMap from kubernetes.yml
    [INFO] F8: Updated ConfigMap: target/fabric8/applyJson/baas-test/configmap-test-config.json
    [INFO] F8: Using namespace: baas-test
    [INFO] F8: Updating Deployment from kubernetes.yml
    [INFO] F8: Updated Deployment: target/fabric8/applyJson/baas-test/deployment-test.json
    [WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
    [INFO] F8: HINT: Use the command `kubectl get pods -w` to watch your pods start up
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    
    

    从上面日志看到一个fabric8:deploy其实有以下几步操作:

    image-20200718234641209

以上就是默认配置的具体操作,就两步,配置pom.xml跟执行mvn命令,执行mvn命令可以放到jenkins上面做也是很方便的。而且fabric8他自带3种基础镜像,分别是:

镜像名 描述
fabric8/java-alpine-openjdk8-jdk 基于apline系统带java8的基础镜像
fabric8/java-jboss-openjdk8-jdk 基于jboss系统带java8的基础镜像
fabric8/java-centos-openjdk8-jdk 基于centos系统带java8的基础镜像

默认是使用第一个镜像,其他两个以及自定义基础镜像可以通过后面的配置自定义化。

基于xml配置方式

基于xml的配置方式,主要是实现docker镜像构建以及k8s发布配置(deployment、service、configmap)的自定义化,就像上面有提到的怎样将我自己的镜像作为应用构建基础镜像

实现如下:

 <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>fabric8-maven-plugin</artifactId>
                <version>${fabric8.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>resource</goal>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
     <!-- 自定义配置 -->
                <configuration>
                    <enricher>
                        <config>
                            <!-- k8s service 配置 将service开放类型改成NodePort  -->
                            <fmp-service>
                                <type>NodePort</type>
                            </fmp-service>
                        </config>
                    </enricher>
                    <images>
                        <image>
                            <!-- 自定义镜像名 -->
                            <name>lps/${project.artifactId}:${project.version}</name>
						
                            <build>
                                <!-- 自定义基础镜像-->
                                <from>registry.lps.com/fabric-base-jdk8</from>
                                <!-- 自定义文件发布 比如将项目 a-jarwithdepences.jar发布到镜像目录/deployment / -->
                                <assembly>
                                    <descriptor>assembly.xml</descriptor>
                                    <targetDir>/deployments</targetDir>
                                </assembly>

                            </build>
                        </image>
                    </images>

                </configuration>
            </plugin>

上面提供了几种比较常用的配置,更多的xml配置可以参考:https://maven.fabric8.io/#xml-configuration

基于外部文件配置方式

基于外部配置文件是使用位于src/main/fabric8目录中的YAML配置的外部配置 。

主要工程目录如下


├── README.md
├── pom.xml
└── src
    ├── main
    │   └── java 
    │   └── resource
    │   └── fabric8
             ├── service.yml 
             ├── deployment.yml 
             ├── configmap.yml 

主要是src/main/fabric8 目录下三个文件主要对应k8s的deployment、service、configmap的配置,fabric8-maven-plugin会在构建的时候自动读取这个目录的文件,根据文件自定义的参数生成配置(插件本身有默认配置,自定义配置只需要修改自定义部分其余部分会自动生成)

模板如下:

deployment.yml

spec:
  replicas: 1
  template:
    spec:
      volumes:
        - name: config
          gitRepo:
            repository: 'https://github.com/jstrachan/sample-springboot-config.git'
            revision: 667ee4db6bc842b127825351e5c9bae5a4fb2147
            directory: .
      containers:
        - volumeMounts:
            - name: config
              mountPath: /app/config
          env:
            - name: KUBERNETES_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
      serviceAccount: ribbon

上面自定义了volumes、container以及serviceAccont的配置,其余的配置会按照默认模板生成。

通过这种方式可以实现配置自定义化,这种方式可以与xml的方式同时结合使用。

fabric8 mvn命令总结

fabric8:build

构建镜像

使用:

mvn  fabric8:build

fabric8:push

推送镜像

使用:

mvn  fabric8:push

推送到私有仓库,需要在maven的配置文件settings.xml 配置仓库url密码

例子

<?xml version="1.0"?>
<settings>

  <profiles>
    <profile>
      <id>mydocker</id>
      <properties>
          <!-- 配置docker host/仓库地址 通过环境变量获取-->
        <docker.registry>${env.DOCKER_REGISTRY}</docker.registry>
        <docker.url>${env.DOCKER_HOST}</docker.url>
      </properties>
    </profile>
  </profiles>
<!-- 配置用户名密码 -->
   <servers>
       <server>
           <id>mydocker</id>
           <username>jolokia</username>
           <password>jolokia</password>
       </server>
        
  </servers>

  <activeProfiles>
    <activeProfile>mydocker</activeProfile>
  </activeProfiles>
</settings>

fabric8:deploy

发布应用到k8s

1.设置环境变量

export KUBERNETES_TRUST_CERTIFICATES=true \
&& export KUBERNETES_MASTER=${KUBERNETES_MASTER} \
&& export FABRIC8_PROFILES=kubernetes \ 
&& export DOCKER_HOST=${DOCKER_HOST} \
&& export KUBERNETES_NAMESPACE=${KUBERNETES_NAMESPACE} \
  • ${KUBERNETES_MASTER} : k8s网络中master的API地址 如:http://localhost:6443
  • ${DOCKER_HOST}: DOCKER 服务地址 如:http://localhost:2375
  • ${KUBERNETES_NAMESPACE}: 发布应用所在k8s的namespace 如:test

2.执行命令

 mvn fabric8:deploy

fabric8:resource

根据src/main/fabric8 目录的自定义yml文件生成k8s配置文件, 一般用于验证生成的yml有没有起效自定义配置

 mvn fabric8:resource

总结

fabric8-maven-plugin应该是目前springboot工程发布到k8s的最好方案之一,它极大地降低构建配置的难度,甚至实现一句命令就可以实现从一个springboot工程到一个运行在k8s上面的服务,所以我是十分推荐它的。

如果有更好的方案,欢迎大家在评论给小的推一波。

猜你喜欢

转载自blog.csdn.net/qq_28540443/article/details/107437916