在当下风靡的云计算生态中,Docker从发布开始就引领这容器化技术的潮流,Docker非常适合管理单个容器。但是如果我们的分布式应用系统是由多个容器组成的,随着系统地迭代演化,使用越来越多的容器和容器化应用程序,并处于高并发、高可用等考虑将其划分为数百个部分,很可能会导致管理和编排变得非常困难。我们迫切需要对容器实施分组,以便跨所有容器提供网络、存储、安全、遥测等服务,于是,Kubernetes 应运而生。
Kubernetes,又称为 k8s或者简称为 “kube” ,是一种可自动实施 Linux 容器操作的开源平台。它可以帮助用户省去应用容器化过程的许多手动部署和扩展操作。也就是说,您可以将运行 Linux 容器的多组主机聚集在一起,由 Kubernetes 帮助您轻松高效地管理这些集群。而且,这些集群可跨公共云、私有云或混合云部署主机。因此,对于要求快速扩展的云原生应用而言(例如借助 Apache Kafka 进行的实时数据流处理),Kubernetes 是理想的托管平台。
由于k8s的技术不断趋向成熟,逐渐成为应用管理的主流,就SpringBoot应用来说,如何实现将应用发布到k8s平台需要以下几个步骤:
在这几个步骤中需要团队具备构建Docker镜像能力以及k8s配置能力,实施起来比较麻烦,而且需要另外去管理docker配置以及k8s的配置,对于开发或者负责上线的同事来说,发布应用不是一键就能搞定的事情,都说我们要搞敏捷、我们要搞DevOps、持续集成, Docker以及k8s都是好技术,但是过于麻烦且不简单的步骤,确实是大部分公司或者项目想转型DevOps的门槛。
后来 jenkins
的出现,自动化流水线的出现让我不禁想起了 第一次工业革命
,确实提高了生产力,我们终于不用再每次 ssh
、 sftp
、 docker build
、 kubectl apply
...
有了第一次依赖脚本自动化执行的 工业革命
, 是不是就够了?
我们需要进一步降低SpringBoot工程构建Docker的配置以及k8s配置的难度,让就算是一个不怎么会docker镜像构建以及k8s应用构建的开发者也能快速实现将工程一句命令发布上去,这个时代,我称之为“第二次工业革命”。
这个时代的关键工具就是---- Fabric8
Fabric是我这个搞区块链的天天对着的单词,偶尔在github逛一下就遇到与他相似八九分的朋友Fabric8。
fabric8是一个开源 集成开发平台 ,为基于 Kubernetes 和 Jenkins 的微服务提供 持续发布 。
使用fabric可以很方便的通过 Continuous Delivery pipelines 创建、编译、部署和测试微服务,然后通过Continuous Improvement和 ChatOps 运行和管理他们。
Fabric8微服务平台 提供:
Developer Console ,是一个 富web应用 ,提供一个单页面来创建、编辑、编译、部署和测试微服务。
Continuous Integration and Continous Delivery ,使用 Jenkins with a Jenkins Workflow Library 更快和更可靠的交付软件。
Management ,集中式管理 Logging 、 Metrics , ChatOps 、 Chaos Monkey ,使用 Hawtio 和 Jolokia 管理Java Containers。
Integration Integration Platform As A Service with deep visualisation of your Apache Camel integration services, an API Registry to view of all your RESTful and SOAP APIs and Fabric8 MQ provides Messaging As A Service based on Apache ActiveMQ 。
Java Tools
帮助Java应用使用Kubernetes
这个就是我们今天的主菜
本文接下来将基于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 | github.com/fabric8io/f… |
docker | 18.04 |
首先fabric8-maven-plugin作为一个maven插件,对应用的代码是无引入性的,所以基本所有springboot工程应用都可直接在POM里面添加maven插件配置即可实现将应用一句命令发布到k8s。
接下来会讲到fabric8-maven-plugin 默认配置方式 、 基于xml配置方式 、 外部文件配置方式 帮助我们一句命令将Springboot应用直接发布到k8s。
默认配置方式顾名思义就是不作任何自定义处理,实现如下:
<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> 复制代码
发布应用到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其实有以下几步操作:
以上就是默认配置的具体操作,就两步,配置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的配置方式,主要是实现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配置可以参考: maven.fabric8.io/#xml-config…
基于外部配置文件是使用位于 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的方式同时结合使用。
构建镜像
使用:
mvn fabric8:build 复制代码
推送镜像
使用:
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> 复制代码
发布应用到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} / 复制代码
2.执行命令
mvn fabric8:deploy 复制代码
根据 src/main/fabric8
目录的自定义yml文件生成k8s配置文件, 一般用于验证生成的yml有没有起效自定义配置
mvn fabric8:resource 复制代码