TomSpencerLondon / Spring-Kubernetes

Practice with Kubernetes and Spring

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Deploying Spring Boot to Kubernetes with Eclipse JKube and ConfigMaps

In this lesson, we will learn how to deploy a Spring Boot application to Kubernetes using the kubernetes-maven-plugin from the Eclipse JKube project. We will then learn how to inject configuration from a ConfigMap into our application using Spring Cloud Kubernetes Config. This link is useful for an overview of the process: https://kubebyexample.com/learning-paths/developing-spring-boot-kubernetes/lesson-4-deploying-spring-boot-kubernetes-eclipse

Here we use minikube as the Kubernetes distribution, but the same steps apply to any Kubernetes distribution.

We also require Java runtime version >= 17. Spring Boot 3 requires Java 17.

This is the repository backing the Spring Boot externalized Configuration lesson for the Developing with Spring Boot on Kubernetes learning path on kube by example.

This project was generated using start.spring.io. The HelloController and HelloControllerTests classes were added as a starting point for the lesson.

The completed solution for the lesson can be found on the solution branch of the repo.

Application overview

Run the application locally Let’s run the application locally to become familiar with it. Open a terminal to the project’s root directory and execute ./mvnw clean package spring-boot:run on Linux/macOS or mvnw.cmd clean package spring-boot:run on Windows. This will compile the application, run all the tests, and then expose the HTTP endpoints on port 8080.

Now, let’s try interacting with the endpoints by opening a browser window or using the curl command from another terminal. The following shows what the values of some of the endpoints should look like:

{
  "property": {
  "source": "Config resource 'class path resource [application.yml]' via location 'optional:classpath:/'",
  "value": "Hello"
  }
} 

NOTE: There is most likely more data in the http://localhost:8080/actuator/env/hello.greeting response. The output is trimmed for brevity.

The /actuator/env/hello.greeting endpoint is the Spring Boot Actuator Environment endpoint. It allows retrieving information about the entire environment or just a single property. This information includes the current value of a property and where it was resolved.

In our case, you can see that the current value of hello.greeting is Hello, and it was resolved from the application.yml file on the classpath, which originated in src/main/resources/application.yml.

Eclipse JKube

We need a way to deploy and test our application in a Kubernetes environment before committing our code into version control. We will use Eclipse JKube for this. This link gives more information on Eclipse JKube: https://www.eclipse.org/jkube/

We add the JKube kubernetes-maven-plugin to our project:

<profiles>
  <profile>
    <id>k8s</id>
    <properties>
      <jkube.enricher.jkube-namespace.namespace>${project.artifactId}</jkube.enricher.jkube-namespace.namespace>
      <jkube.generator.from>registry.access.redhat.com/ubi8/openjdk-${maven.compiler.release}:latest</jkube.generator.from>
      <jkube.namespace>${project.artifactId}</jkube.namespace>
      <jkube.recreate>true</jkube.recreate>
      <jkube.version>1.10.1</jkube.version>
    </properties>
    <build>
      <plugins>
        <plugin>
          <groupId>org.eclipse.jkube</groupId>
          <artifactId>kubernetes-maven-plugin</artifactId>
          <version>${jkube.version}</version>
          <executions>
            <execution>
              <id>jkube</id>
              <goals>
                <goal>resource</goal>
                <goal>build</goal>
              </goals>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

We then run:

./mvnw k8s:deploy -Pk8s

We can then see our service running:

tom@tom-ubuntu:~/Projects/spring-jkube-external-config$ minikube service list
|------------------------------|------------------------------|--------------|---------------------------|
|          NAMESPACE           |             NAME             | TARGET PORT  |            URL            |
|------------------------------|------------------------------|--------------|---------------------------|
| default                      | kubernetes                   | No node port |
| kube-system                  | kube-dns                     | No node port |
| kubernetes-dashboard         | dashboard-metrics-scraper    | No node port |
| kubernetes-dashboard         | kubernetes-dashboard         | No node port |
| spring-jkube-external-config | spring-jkube-external-config | http/8080    | http://192.168.49.2:30526 |
|------------------------------|------------------------------|--------------|---------------------------|

Externalize configuration to ConfigMap

We will use the Spring Cloud Kubernetes project’s PropertySource implementations to help read external configuration. We’ll need to add some dependencies to our project as well as some additional JKube resource fragments, but we won’t need to make any changes to the application’s source code.

Open the project’s pom.xml file again. We first need to add the Spring Cloud Bill of Materials to the project:

In the section, add <spring-cloud.version>2022.0.0</spring-cloud.version>

After the section, add a new section:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

In the , add the kubernetes-client-config starter:

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-kubernetes-client-config</artifactId>
</dependency>

We then run ./mvnw verify to make sure everything still works.

We then add rolebinding.yml:

roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
  - kind: ServiceAccount
    name: default

and configmap.yml:

data:
  hello.greeting: Hello (from Kubernetes ConfigMap)

We then run:

./mvnw k8s:deploy -Pk8s

to redeploy to minikube.

We can then see our service running:

tom@tom-ubuntu:~/Projects/spring-jkube-external-config$ minikube service list
|------------------------------|------------------------------|--------------|---------------------------|
|          NAMESPACE           |             NAME             | TARGET PORT  |            URL            |
|------------------------------|------------------------------|--------------|---------------------------|
| default                      | kubernetes                   | No node port |
| kube-system                  | kube-dns                     | No node port |
| kubernetes-dashboard         | dashboard-metrics-scraper    | No node port |
| kubernetes-dashboard         | kubernetes-dashboard         | No node port |
| spring-jkube-external-config | spring-jkube-external-config | http/8080    | http://192.168.49.2:30526 |
|------------------------------|------------------------------|--------------|---------------------------|

The hello.greeting property is now being read from the ConfigMap. image

We can delete our deployment with:

./mvnw k8s:undeploy -Pk8s

About

Practice with Kubernetes and Spring


Languages

Language:Java 100.0%