preface
In the current cloud computing ecosystem, Docker has been leading the trend of containerization technology since its release. Docker is very suitable for managing individual containers. However, if our distributed application system is composed of multiple containers, it is likely to become very difficult to manage and orchestrate as the system iteratively evolves, with more and more containers and containerized applications, and divided into hundreds of parts for high concurrency, high availability, and other considerations. Kubernetes was born of the urgent need to group containers to provide networking, storage, security, telemetry, and more across all containers.
Kubernetes is introduced
Kubernetes, also known as K8S or simply “Kube”, is an open source platform that automatically implements Linux container operations. It helps users avoid many of the manual deployment and scaling of the application containerization process. That is, you can bring together groups of hosts running Linux containers, and Kubernetes helps you manage these clusters easily and efficiently. Furthermore, these clusters can deploy hosts across public, private, or hybrid clouds. Therefore, Kubernetes is the ideal hosting platform for cloud-native applications that require rapid scaling, such as real-time data stream processing with Apache Kafka.
The traditional way of publishing SpringBoot applications to K8s
As K8S technology continues to mature and gradually become the mainstream of application management, how to release the application to K8S platform for SpringBoot applications requires the following steps:
In these steps, the team needs to have the ability to build Docker image and K8S configuration, which is difficult to implement, and it needs to manage Docker configuration and K8S configuration in addition. For colleagues who are responsible for development or online, releasing applications is not something that can be done with one click. We say we want to do Agile, we want to do DevOps, continuous integration, Docker and K8S are all good technologies, but the cumbersome and difficult steps are really the threshold for most companies or projects to transition to DevOps. Later, the emergence of Jenkins and automated assembly line reminded me of the first industrial revolution, which really improved productivity. Finally, we no longer need SSH, SFTP, Docker build, Kubectl apply…
Is it enough to have the first industrial revolution that relies on automated script execution?
We need to further reduce the difficulty of SpringBoot project to build Docker configuration and K8S configuration, so that even a developer who is not good at Docker image construction and K8S application construction can quickly realize the project command to release, this era, I call “the second industrial revolution”.
The key tool of this era is —-Fabric8
Fabric8 introduction
Fabric is a word that I, a blockchain guy, talk about every day, and I stumble across my friend Fabric8 on Github.
What is Fabric8?
Fabric8 is an open source integrated development platform for continuous release of Microservices based on Kubernetes and Jenkins.
Fabric makes it easy to create, compile, deploy and test micro services through Continuous Delivery Pipelines, then run and manage them through Continuous Improvement and ChatOps.
Fabric8 microservices platform provides:
-
Developer Console, a rich Web application, provides a single page to create, edit, compile, deploy, and test microservices.
-
Continuous Integration and Continous Delivery using Jenkins with a Jenkins Workflow Library faster and more reliable Delivery software.
-
Management, manage Logging, Metrics, ChatOps, Chaos Monkey, manage Java Containers using Hawtio and Jolokia.
-
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
Help Java applications use Kubernetes
- Maven Plugin for working with Kubernetes ,
This is our main course today
- Integration and System Testing of Kubernetes resources easily inside JUnit with Arquillian
- Java Libraries and support for CDI extensions for working with Kubernetes.
- Maven Plugin for working with Kubernetes ,
The text introduce
The next step in this article is to quickly publish springboot applications to K8S via a POm. XML file configuration based on the Maven plugin provided by Fabric8.
practice
Environment to prepare
System environment/dependencies | version | note |
---|---|---|
Ubuntu16.04 | 16.04 | Develop/compile the environment system |
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 |
Project configuration
Fabric8-maven-plugin is a maven plugin that is non-invasive to application code, so any SpringBoot project application can directly add maven plugin configuration to the POM to publish application commands to K8S.
The fabric8-Maven-Plugin default configuration, XML-based configuration, and external file configuration help us publish Springboot applications directly to K8S with one command.
Default Configuration mode
The default configuration, as the name implies, does not do any customization. The implementation is as follows:
- Edit the 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>
Copy the code
-
Publish applications to K8S
So what I would normally do is
mvn fabric8:deploy Copy the code
Then build the image and publish the application to K8S.
Below is the main log for MVN execution
[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. The jar [INFO] - [INFO] Sofa -ark-maven-plugin:1.1.1:repackage (default-cli) @test -- [INFO] [INFO] -- Spring - the 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. The jar to / root/m2 / repository/com/testdemo/test / 2.0.2 RELEASE/test - 2.0.2. The 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. The 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. The 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. The 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] ------------------------------------------------------------------------Copy the code
Fabric8 :deploy contains the following steps:
XML configuration and execute MVN command. Execute MVN command can be done on Jenkins. And Fabric8 comes with three base images:
The mirror of | describe |
---|---|
fabric8/java-alpine-openjdk8-jdk | Based on apline system with java8 basic image |
fabric8/java-jboss-openjdk8-jdk | Based on jboss system with java8 basic image |
fabric8/java-centos-openjdk8-jdk | Based on centos system with Java8 basic image |
The default is to use the first image, the other two and the custom base images can be customized by configuration later.
Based on XML configuration
The configuration mode based on XML is mainly to realize the construction of Docker image and the customization of K8S deployment configuration (Deployment, service, configmap). As mentioned above, how to build my own image as the base image of the application
The implementation is as follows:
<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>
<! -- Custom configuration -->
<configuration>
<enricher>
<config>
<! -- k8s service config change service open type to NodePort -->
<fmp-service>
<type>NodePort</type>
</fmp-service>
</config>
</enricher>
<images>
<image>
<! -- Custom mirror name -->
<name>lps/${project.artifactId}:${project.version}</name>
<build>
<! -- Custom base image -->
<from>registry.lps.com/fabric-base-jdk8</from>
<! -- Customize file publishing, such as publishing the project a-jarWithdepences.jar to the mirror directory /deployment / -->
<assembly>
<descriptor>assembly.xml</descriptor>
<targetDir>/deployments</targetDir>
</assembly>
</build>
</image>
</images>
</configuration>
</plugin>
Copy the code
Maven.fabric8.io /#xml-config…
Configuration based on external files
External based profiles are external configurations using YAML configurations located in the SRC /main/fabric8 directory.
The main project catalogue is as follows
├ ─ ─README.md├ ─ ─pom.xml└ ─ ─src├ ─ ─main│ └ ─ ─java│ └ ─ ─resource│ └ ─ ─fabric8├ ─ ─service.yml├ ─ ─deployment.yml├ ─ ─configmap.yml
Copy the code
Fabric8-maven-plugin: configmap (k8S) : fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin: fabric8-maven-plugin Generate the configuration according to the parameters defined by the file (the plug-in itself has default configuration, the custom configuration only needs to modify the custom part and the rest will be generated automatically)
The template is as follows:
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
Copy the code
You need to configure volumes, Containers, and serviceAccont. Other configurations are generated using the default template.
Configuration customization can be achieved in this way, which can be combined with the XML approach.
Fabric8 MVN command summary
fabric8:build
Build the mirror
Use:
mvn fabric8:build
Copy the code
fabric8:push
Push the mirror
Use:
mvn fabric8:push
Copy the code
To push to a private repository, you need to configure the repository URL password in Maven’s configuration file settings. XML
example
<?xml version="1.0"? >
<settings>
<profiles>
<profile>
<id>mydocker</id>
<properties>
<! Docker host/ repository address set by environment variable -->
<docker.registry>${env.DOCKER_REGISTRY}</docker.registry>
<docker.url>${env.DOCKER_HOST}</docker.url>
</properties>
</profile>
</profiles>
<! -- Set username and password -->
<servers>
<server>
<id>mydocker</id>
<username>jolokia</username>
<password>jolokia</password>
</server>
</servers>
<activeProfiles>
<activeProfile>mydocker</activeProfile>
</activeProfiles>
</settings>
Copy the code
fabric8:deploy
Publish applications to K8S
1. Set environment variables
export KUBERNETES_TRUST_CERTIFICATES=true \
&& export KUBERNETES_MASTER=${KUBERNETES_MASTER} \
&& export FABRIC8_PROFILES=kubernetes \
&& export DOCKER_HOST=${DOCKER_HOST} \
&& export KUBERNETES_NAMESPACE=${KUBERNETES_NAMESPACE} \
Copy the code
- ${KUBERNETES_MASTER} : specifies the API address of the master in the K8S network, for example, http://localhost:6443
- ${DOCKER_HOST}: indicates the DOCKER service address, for example, http://localhost:2375
- ${KUBERNETES_NAMESPACE} : specifies the namespace of the K8S where applications are published, for example, test
2. Run commands
mvn fabric8:deploy
Copy the code
fabric8:resource
K8s configuration files are generated from custom YML files in the SRC /main/fabric8 directory to verify that the generated YML is valid for custom configuration
mvn fabric8:resource
Copy the code
conclusion
Fabric8-maven-plugin is probably one of the best solutions for publishing Springboot projects to K8S. It greatly reduces the difficulty of building configurations and even implements a single command from a Springboot project to a service running on K8S, so I highly recommend it.
If there is a better plan, welcome everyone in the comments to small push a wave.