Not able to deploy a Spring Boot Helloworld application on MicroK8s cluster using jkube plugin

12/24/2020

I have a very simple Spring Boot Helloworld application that displays Hello World! message using a REST API.

I would like to deploy that application on my Ubuntu node which has MicroK8s installed.

Steps Followed:

  1. git clone project_repo_url_here
  2. Build image using ./mvnw k8s:build
  3. Apply resources using ./mvnw k8s:resource
  4. Deploy application using ./mvnw k8s:deploy

I am able to build that image using ./mvnw k8s:build command and can also see the image using docker images command but not able to deploy it on MicroK8s cluster using ./mvnw k8s:resource and ./mvnw k8s:deploy commands

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.3.3.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>helloworld</artifactId>
	<version>0.0.2-SNAPSHOT</version>
	<name>helloworld</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>11</java.version>
		<spring-boot.build-image.imageName>chandeln/${project.artifactId}:${project.version}</spring-boot.build-image.imageName>
		<jkube.generator.name>${spring-boot.build-image.imageName}</jkube.generator.name>
		<docker.skip.tag>true</docker.skip.tag>
		<jkube.enricher.jkube-service.type>NodePort</jkube.enricher.jkube-service.type>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-actuator</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
			<plugin>
				<groupId>org.eclipse.jkube</groupId>
				<artifactId>kubernetes-maven-plugin</artifactId>
				<version>1.0.2</version>
			</plugin>
		</plugins>
	</build>

</project>

HelloworldController.java

@RestController
public class HelloworldController {

    @GetMapping("/")
    public String hello() {
        return "Hello World!";
    }

}

On my Ubuntu machine I have MicroK8s installed.

microk8s status --wait-ready

microk8s is running
high-availability: no
  datastore master nodes: <my-ubuntu-machine-public-ip>:19001
  datastore standby nodes: none
addons:
  enabled:
    dashboard            # The Kubernetes dashboard
    dns                  # CoreDNS
    ha-cluster           # Configure high availability on the current node
    ingress              # Ingress controller for external access
    metrics-server       # K8s Metrics Server for API access to service metrics
  disabled:
    ambassador           # Ambassador API Gateway and Ingress
    cilium               # SDN, fast with full network policy
    fluentd              # Elasticsearch-Fluentd-Kibana logging and monitoring
    gpu                  # Automatic enablement of Nvidia CUDA
    helm                 # Helm 2 - the package manager for Kubernetes
    helm3                # Helm 3 - Kubernetes package manager
    host-access          # Allow Pods connecting to Host services smoothly
    istio                # Core Istio service mesh services
    jaeger               # Kubernetes Jaeger operator with its simple config
    knative              # The Knative framework on Kubernetes.
    kubeflow             # Kubeflow for easy ML deployments
    linkerd              # Linkerd is a service mesh for Kubernetes and other frameworks
    metallb              # Loadbalancer for your Kubernetes cluster
    multus               # Multus CNI enables attaching multiple network interfaces to pods
    prometheus           # Prometheus operator for monitoring and logging
    rbac                 # Role-Based Access Control for authorisation
    registry             # Private image registry exposed on localhost:32000
    storage              # Storage class; allocates storage from host directory

kubectl cluster-info

Kubernetes master is running at https://127.0.0.1:16443
Metrics-server is running at https://127.0.0.1:16443/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
CoreDNS is running at https://127.0.0.1:16443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

kubectl get all

NAME                            READY   STATUS    RESTARTS   AGE
pod/microbot-5f5499d479-t2cdz   1/1     Running   1          31d
pod/microbot-5f5499d479-r6d57   1/1     Running   3          31d
pod/microbot-5f5499d479-7zztm   1/1     Running   3          31d
pod/nginx-6799fc88d8-9sf5j      1/1     Running   5          31d

NAME                       TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/kubernetes         ClusterIP   10.152.183.1     <none>        443/TCP        31d
service/microbot-service   NodePort    10.152.183.184   <none>        81:31587/TCP   31d

NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/microbot   3/3     3            3           31d
deployment.apps/nginx      1/1     1            1           31d

NAME                                  DESIRED   CURRENT   READY   AGE
replicaset.apps/microbot-5f5499d479   3         3         3       31d
replicaset.apps/nginx-6799fc88d8      1         1         1       31d

./mvnw k8s:build

Docker image built successfully. See below.

docker images

REPOSITORY                            TAG                     IMAGE ID            CREATED             SIZE
chandeln/helloworld                   0.0.2-SNAPSHOT          dc061ea2b469        17 minutes ago      509MB
chandeln/helloworld                   latest                  dc061ea2b469        17 minutes ago      509MB

./mvnw k8s:resource

[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< com.example:helloworld >-----------------------
[INFO] Building helloworld 0.0.2-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- kubernetes-maven-plugin:1.0.2:resource (default-cli) @ helloworld ---
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[WARNING] k8s: Cannot access cluster for detecting mode: Unknown host kubernetes.default.svc: Name or service not known
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[INFO] k8s: Running generator spring-boot
[INFO] k8s: spring-boot: Using Docker image quay.io/jkube/jkube-java-binary-s2i:0.0.8 as base / builder
[INFO] k8s: Using resource templates from /home/admin/apps/helloworld/src/main/jkube
[INFO] k8s: jkube-controller: Adding a default Deployment
[INFO] k8s: jkube-service: Adding a default service 'helloworld' with ports [8080]
[INFO] k8s: jkube-healthcheck-spring-boot: Adding readiness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 10 seconds
[INFO] k8s: jkube-healthcheck-spring-boot: Adding liveness probe on port 8080, path='/actuator/health', scheme='HTTP', with initial delay 180 seconds
[INFO] k8s: jkube-revision-history: Adding revision history limit to 2
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  10.701 s
[INFO] Finished at: 2020-12-24T03:01:08Z
[INFO] ------------------------------------------------------------------------

./mvnw k8s:deploy

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

2020-12-24 03:18:13.492  INFO 1828768 --- [           main] c.e.h.HelloworldApplicationTests         : Starting HelloworldApplicationTests on tools-server.kanaaritech.com with PID 1828768 (started by admin in /home/admin/apps/helloworld)
2020-12-24 03:18:13.494  INFO 1828768 --- [           main] c.e.h.HelloworldApplicationTests         : The following profiles are active: tools
2020-12-24 03:18:24.499  INFO 1828768 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-24 03:18:27.959  INFO 1828768 --- [           main] o.s.b.a.e.web.EndpointLinksResolver      : Exposing 2 endpoint(s) beneath base path '/actuator'
2020-12-24 03:18:28.684  INFO 1828768 --- [           main] c.e.h.HelloworldApplicationTests         : Started HelloworldApplicationTests in 15.912 seconds (JVM running for 18.923)
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 20.012 s - in com.example.helloworld.HelloworldApplicationTests
2020-12-24 03:18:31.927  INFO 1828768 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
[INFO]
[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ helloworld ---
[INFO] Building jar: /home/admin/apps/helloworld/target/helloworld-0.0.2-SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.3.3.RELEASE:repackage (repackage) @ helloworld ---
[INFO] Replacing main artifact with repackaged archive
[INFO]
[INFO] --- maven-install-plugin:2.5.2:install (default-install) @ helloworld ---
[INFO] Installing /home/admin/apps/helloworld/target/helloworld-0.0.2-SNAPSHOT.jar to /home/admin/.m2/repository/com/example/helloworld/0.0.2-SNAPSHOT/helloworld-0.0.2-SNAPSHOT.jar
[INFO] Installing /home/admin/apps/helloworld/pom.xml to /home/admin/.m2/repository/com/example/helloworld/0.0.2-SNAPSHOT/helloworld-0.0.2-SNAPSHOT.pom
[INFO]
[INFO] <<< kubernetes-maven-plugin:1.0.2:deploy (default-cli) < install @ helloworld <<<
[INFO]
[INFO]
[INFO] --- kubernetes-maven-plugin:1.0.2:deploy (default-cli) @ helloworld ---
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[WARNING] k8s: Cannot access cluster for detecting mode: Unknown host kubernetes.default.svc: Name or service not known
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[WARNING] k8s: Cannot access cluster for detecting mode: Unknown host kubernetes.default.svc
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[WARNING] Error reading service account token from: [/var/run/secrets/kubernetes.io/serviceaccount/token]. Ignoring.
[ERROR] k8s: Could not connect to kubernetes cluster!
[ERROR] k8s: Connection error: %s: java.net.UnknownHostException: kubernetes.default.svc
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:  38.670 s
[INFO] Finished at: 2020-12-24T03:18:42Z
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.eclipse.jkube:kubernetes-maven-plugin:1.0.2:deploy (default-cli) on project helloworld: Execution default-cli of goal org.eclipse.jkube:kubernetes-maven-plugin:1.0.2:deploy failed: Could not connect to kubernetes cluster. Have you started a cluster via `mvn jkube:cluster-start` or connected to a remote cluster via `kubectl`? Error: java.net.UnknownHostException: kubernetes.default.svc: An error has occurred. Unknown host kubernetes.default.svc -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/PluginExecutionException

Information about Eclipse JKube (successor of Jib plugin) plugin can be found here.

https://www.eclipse.org/jkube/docs/kubernetes-maven-plugin

-- Nital
docker
jkube
kubernetes
microk8s
spring-boot

1 Answer

2/12/2021

MicroK8s has his own packaged version of kubectl that by default it's accessed through MicroK8s including its configuration.

microk8s kubectl

In order that JKube knows about your MicroK8s cluster you will need to export the configuration microk8s config and put it on your kubeconfig file ~/.kube/config

cd $HOME
mkdir .kube
cd .kube
microk8s config > config

Reference: https://microk8s.io/docs/working-with-kubectl

-- Alejandro Mart&#237;nez
Source: StackOverflow