In this article, you can read more about the Quarkus code guide I tried out, related to the following topic:
- The ability to automatically generate Kubernetes resources by Quarkus
The guide covers generating and deploying Kubernetes resources based on sane defaults and user supplied configuration. In this article, I will focus on the automatic deployment of the generated resources to a target platform, in my case K3s (lightweight certified Kubernetes distribution).
Quarkus guide “Quarkus – Kubernetes extension”
I continue where I left the previous time, with the steps from the Quarkus guide “Quarkus – Kubernetes extension”, still using the code in my existing “getting-started” project (as described in my previous article) . You may remember that amongst the other files, two files named kubernetes.json and kubernetes.yml were created in the target/kubernetes/ directory.
If you look at either file you will see that it contains a Kubernetes ServiceAccount, Service and a Deployment.
[https://technology.amis.nl/2020/10/03/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-part-2/]
By the way, Quarkus has the ability to push a created container image to a registry before deploying the application to the target platform. I skipped trying that out for now.
Deployment targets
By default, when no deployment-target is set, then only vanilla Kubernetes resources are generated and deployed to a cluster (if quarkus.kubernetes.deploy has been set to true). That was fine by me.
Please see the documentation, for generating resources and deploying to a Kubernetes cluster like:
[https://quarkus.io/guides/deploying-to-kubernetes]
- Minikube (via the quarkus-minikube extension that Quarkus provides)
[https://minikube.sigs.k8s.io/docs/]
- OpenShift (via the OpenShift extension that Quarkus provides)
[https://www.openshift.com/]
- Knative
[https://knative.dev/]
In my demo environment I had K3s (lightweight certified Kubernetes distribution) installed.
[https://k3s.io/]
Automatic deployment
To trigger building and deploying a container image you need to enable the quarkus.kubernetes.deploy flag (the flag is disabled by default – furthermore it has no effect during test runs or dev mode).
[https://quarkus.io/guides/deploying-to-kubernetes#deployment]
In order to build and deploy a container image, I used the following command on the Linux Command Prompt:
./mvnw clean package -Dquarkus.kubernetes.deploy=true
Unfortunately, I got the following build error, related to my demo environment:
[ERROR] Failed to execute goal io.quarkus:quarkus-maven-plugin:1.7.0.Final:build (default) on project getting-started: Failed to build quarkus application: io.quarkus.builder.BuildException: Build failure: Build failed due to errors [ERROR] [error]: Build step io.quarkus.kubernetes.deployment.KubernetesDeployer#deploy threw an exception: java.lang.RuntimeException: Although a Kubernetes deployment was requested, it however cannot take place because there was an error during communication with the API Server at 'https://kubernetes.default.svc/'
So, apparently the Kubernetes API Server could not be contacted.
The code guide (after reading a few lines further down) gave me an answer about what was wrong.
When deployment is enabled, the Kubernetes extension will select the resources specified by quarkus.kubernetes.deployment.target and deploy them. This assumes that a .kube/config is available in your user directory that points to the target Kubernetes cluster. In other words, the extension will use whatever cluster kubectl uses. The same applies to credentials.
[https://quarkus.io/guides/deploying-to-kubernetes#deploying]
In order to create the .kube/config file in my user (/home/vagrant) directory on my demo environment, I used the following command on the Linux Command Prompt:
With the following output:
total 20 drwxr-xr-x 7 vagrant vagrant 4096 Sep 13 15:18 .. drwxr-x--- 3 vagrant vagrant 4096 Sep 13 15:18 cache drwxr-x--- 3 vagrant vagrant 4096 Sep 13 15:40 http-cache drwxr-x--- 4 vagrant vagrant 4096 Sep 13 17:18 . -rw-rw-r-- 1 vagrant vagrant 1044 Sep 13 17:39 config
In order to build and deploy a container image, again I used the following command on the Linux Command Prompt:
cd /vagrant/applications/getting-started ./mvnw clean package -Dquarkus.kubernetes.deploy=true
With the following output:
[INFO] Scanning for projects... [INFO] [INFO] ----------------------< org.acme:getting-started >---------------------- [INFO] Building getting-started 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ getting-started --- [INFO] Deleting /vagrant/applications/getting-started/target [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 4 resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/classes [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare-tests (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /vagrant/applications/getting-started/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ getting-started --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running org.acme.getting.started.GreetingResourceTest 2020-09-21 13:51:09,412 WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.deploy" was provided; it will be ignored; verify that the dependency extension for this configuration is set or you did not make a typo 2020-09-21 13:51:10,202 INFO [io.quarkus] (main) Quarkus 1.7.0.Final on JVM started in 4.759s. Listening on: http://0.0.0.0:8081 2020-09-21 13:51:10,202 INFO [io.quarkus] (main) Profile test activated. 2020-09-21 13:51:10,203 INFO [io.quarkus] (main) Installed features: [cdi, kubernetes, resteasy] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 13.899 s - in org.acme.getting.started.GreetingResourceTest 2020-09-21 13:51:14,017 INFO [io.quarkus] (main) Quarkus stopped in 0.045s [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ getting-started --- [INFO] Building jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT.jar [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:build (default) @ getting-started --- [INFO] [org.jboss.threads] JBoss Threads version 3.1.1.Final [WARNING] [io.quarkus.kubernetes.deployment.KubernetesDeployer] A Kubernetes deployment was requested, but the container image to be built will not be pushed to any registry because "quarkus.container-image.registry" has not been set. The Kubernetes deployment will only work properly if the cluster is using the local Docker daemon. For that reason 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building thin jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT-runner.jar [WARNING] [io.quarkus.kubernetes.deployment.KubernetesProcessor] No registry was set for the container image, so 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] Checking for existing resources in: /vagrant/applications/getting-started/src/main/kubernetes. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeploy] Kubernetes API Server at 'https://127.0.0.1:6443/' successfully contacted. [INFO] [io.quarkus.container.image.docker.deployment.DockerWorking] Docker daemon found. Version:'19.03.12' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Building docker image for jar. [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Executing the following command to build docker image: 'docker build -f /vagrant/applications/getting-started/src/main/docker/Dockerfile.jvm -t vagrant/getting-started:1.0-SNAPSHOT /vagrant/applications/getting-started' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Sending build context to Docker daemon 11.09MB [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 1/11 : FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 91d23a64fdf2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 2/11 : ARG JAVA_PACKAGE=java-11-openjdk-headless [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 3818465cc8fa [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 3/11 : ARG RUN_JAVA_VERSION=1.3.8 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> c45c7ada9216 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 4/11 : ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eea2c4e04c6c [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 5/11 : RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} && microdnf update && microdnf clean all && mkdir /deployments && chown 1001 /deployments && chmod "g+rwX" /deployments && chown 1001:root /deployments && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh && chown 1001 /deployments/run-java.sh && chmod 540 /deployments/run-java.sh && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eedc98908837 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 6/11 : ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> ef0d7a761730 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 7/11 : COPY target/lib/* /deployments/lib/ [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> d8153bf53db2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 8/11 : COPY target/*-runner.jar /deployments/app.jar [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 29c8cb2728a9 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 9/11 : EXPOSE 8080 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in 357e10f70946 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container 357e10f70946 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 6c0c45ae950a [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 10/11 : USER 1001 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in cc1e69f157cd [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container cc1e69f157cd [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 4f1a7ea4cc5f [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 11/11 : ENTRYPOINT [ "/deployments/run-java.sh" ] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in 6b9c8969b315 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container 6b9c8969b315 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> a4f6437458b3 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully built a4f6437458b3 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully tagged vagrant/getting-started:1.0-SNAPSHOT [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Built container image vagrant/getting-started:1.0-SNAPSHOT (a4f6437458b3) [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Deploying to kubernetes server: https://127.0.0.1:6443/ in namespace: default. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: ServiceAccount my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Service my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Deployment my-quarkus-kubernetes-name. [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 15738ms [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 43.627 s [INFO] Finished at: 2020-09-21T13:51:30Z [INFO] ------------------------------------------------------------------------ vagrant@ubuntu-bionic:/vagrant/applications/getting-started$
Remark about the namespace:
As you can see in the output, namespace default is used, although in the Kubernetes manifests I used namespace nl-amis-development. This is to be expected because my custom namespace does not yet exist.
In order to check the resources that where created, I used the following command on the Linux Command Prompt:
kubectl get all --all-namespaces
With the following output:
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system pod/metrics-server-7566d596c8-gxrjt 1/1 Running 0 32d kube-system pod/helm-install-traefik-7mps6 0/1 Completed 0 32d kube-system pod/local-path-provisioner-6d59f47c7-vtb4t 1/1 Running 0 32d kube-system pod/coredns-8655855d6-qxqhf 1/1 Running 0 32d kube-system pod/svclb-traefik-hdxqf 2/2 Running 0 32d kube-system pod/traefik-758cd5fc85-m4cvj 1/1 Running 0 32d kubernetes-dashboard pod/kubernetes-dashboard-7b544877d5-l4qfb 1/1 Running 0 32d kubernetes-dashboard pod/dashboard-metrics-scraper-6b4884c9d5-hdxmn 1/1 Running 0 32d NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 32d kube-system service/kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 32d kube-system service/metrics-server ClusterIP 10.43.183.35 <none> 443/TCP 32d kube-system service/traefik-prometheus ClusterIP 10.43.50.120 <none> 9100/TCP 32d kube-system service/traefik LoadBalancer 10.43.116.205 10.0.2.15 80:30676/TCP,443:31713/TCP 32d kubernetes-dashboard service/kubernetes-dashboard ClusterIP 10.43.175.253 <none> 443/TCP 32d kubernetes-dashboard service/dashboard-metrics-scraper ClusterIP 10.43.5.8 <none> 8000/TCP 32d default service/my-quarkus-kubernetes-name NodePort 10.43.220.219 <none> 8090:31939/TCP 15m NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system daemonset.apps/svclb-traefik 1 1 1 1 1 <none> 32d NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE kube-system deployment.apps/metrics-server 1/1 1 1 32d kube-system deployment.apps/local-path-provisioner 1/1 1 1 32d kube-system deployment.apps/coredns 1/1 1 1 32d kube-system deployment.apps/traefik 1/1 1 1 32d kubernetes-dashboard deployment.apps/kubernetes-dashboard 1/1 1 1 32d kubernetes-dashboard deployment.apps/dashboard-metrics-scraper 1/1 1 1 32d default deployment.apps/my-quarkus-kubernetes-name 0/3 0 0 15m NAMESPACE NAME DESIRED CURRENT READY AGE kube-system replicaset.apps/metrics-server-7566d596c8 1 1 1 32d kube-system replicaset.apps/local-path-provisioner-6d59f47c7 1 1 1 32d kube-system replicaset.apps/coredns-8655855d6 1 1 1 32d kube-system replicaset.apps/traefik-758cd5fc85 1 1 1 32d kubernetes-dashboard replicaset.apps/kubernetes-dashboard-7b544877d5 1 1 1 32d kubernetes-dashboard replicaset.apps/dashboard-metrics-scraper-6b4884c9d5 1 1 1 32d default replicaset.apps/my-quarkus-kubernetes-name-7845545ff5 3 0 0 15m NAMESPACE NAME COMPLETIONS DURATION AGE kube-system job.batch/helm-install-traefik 1/1 41s 32d
In order to check the ServiceAccount that was created, I used the following command on the Linux Command Prompt:
kubectl get serviceAccounts
With the following output:
NAME SECRETS AGE
default 1 32d
my-quarkus-kubernetes-name 1 18m
Remark:
Several resources are created, but no Pods!
When I checked the resources via the Kubernetes Dashboard, I saw the following error message:
So, as expected, an error occurred because the ServiceAccount with name my-quarkus-kubernetes-service-account does not exist. As I remarked earlier in my previous article, the service account that is used to run the pod, refers to a non-existing service account.
[https://technology.amis.nl/2020/10/03/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-part-2/]
To work around this problem. I opted to remark the configuration I set earlier in src/main/resources/application.properties.
# Kubernetes manifest service-account #quarkus.kubernetes.service-account=my-quarkus-kubernetes-service-account
Creating the namespace
For creating the namespace, I used an existing yaml file, with the following content:
apiVersion: v1 kind: Namespace metadata: name: "nl-amis-development" labels: name: "nl-amis-development"
In order to create the namespace, I used the following command on the Linux Command Prompt:
kubectl apply -f /vagrant/yaml/namespace-development.yaml
With the following output:
namespace/nl-amis-development created
Deleting the created resources
In order to delete the created Service, I used the following command on the Linux Command Prompt:
kubectl delete -n default service my-quarkus-kubernetes-name
With the following output:
service “my-quarkus-kubernetes-name” deleted
In order to delete the created ReplicaSet, I used the following command on the Linux Command Prompt:
kubectl delete -n default replicaset my-quarkus-kubernetes-name-7845545ff5
With the following output:
replicaset.apps “my-quarkus-kubernetes-name-7845545ff5” deleted
In order to delete the created Deployment, I used the following command on the Linux Command Prompt:
kubectl delete -n default deployment my-quarkus-kubernetes-name
With the following output:
deployment.apps “my-quarkus-kubernetes-name” deleted
In order to delete the created ServiceAccount, I used the following command on the Linux Command Prompt:
kubectl delete -n default serviceAccounts my-quarkus-kubernetes-name
With the following output:
serviceaccount “my-quarkus-kubernetes-name” deleted
Automatic deployment with a namespace created beforehand
In order to build and deploy a container image, again I used the following command on the Linux Command Prompt:
./mvnw clean package -Dquarkus.kubernetes.deploy=true
With the following output:
[INFO] Scanning for projects... [INFO] [INFO] ----------------------< org.acme:getting-started >---------------------- [INFO] Building getting-started 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ getting-started --- [INFO] Deleting /vagrant/applications/getting-started/target [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 4 resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/classes [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare-tests (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /vagrant/applications/getting-started/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ getting-started --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running org.acme.getting.started.GreetingResourceTest 2020-09-21 14:46:03,627 WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.deploy" was provided; it will be ignored; verify that the dependency extension for this configuration is set or you did not make a typo 2020-09-21 14:46:04,421 INFO [io.quarkus] (main) Quarkus 1.7.0.Final on JVM started in 4.530s. Listening on: http://0.0.0.0:8081 2020-09-21 14:46:04,422 INFO [io.quarkus] (main) Profile test activated. 2020-09-21 14:46:04,422 INFO [io.quarkus] (main) Installed features: [cdi, kubernetes, resteasy] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 13.133 s - in org.acme.getting.started.GreetingResourceTest 2020-09-21 14:46:08,139 INFO [io.quarkus] (main) Quarkus stopped in 0.032s [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ getting-started --- [INFO] Building jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT.jar [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:build (default) @ getting-started --- [INFO] [org.jboss.threads] JBoss Threads version 3.1.1.Final [WARNING] [io.quarkus.kubernetes.deployment.KubernetesDeployer] A Kubernetes deployment was requested, but the container image to be built will not be pushed to any registry because "quarkus.container-image.registry" has not been set. The Kubernetes deployment will only work properly if the cluster is using the local Docker daemon. For that reason 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building thin jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT-runner.jar [WARNING] [io.quarkus.kubernetes.deployment.KubernetesProcessor] No registry was set for the container image, so 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] Checking for existing resources in: /vagrant/applications/getting-started/src/main/kubernetes. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeploy] Kubernetes API Server at 'https://127.0.0.1:6443/' successfully contacted. [INFO] [io.quarkus.container.image.docker.deployment.DockerWorking] Docker daemon found. Version:'19.03.12' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Building docker image for jar. [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Executing the following command to build docker image: 'docker build -f /vagrant/applications/getting-started/src/main/docker/Dockerfile.jvm -t vagrant/getting-started:1.0-SNAPSHOT /vagrant/applications/getting-started' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Sending build context to Docker daemon 11.09MB [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 1/11 : FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 91d23a64fdf2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 2/11 : ARG JAVA_PACKAGE=java-11-openjdk-headless [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 3818465cc8fa [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 3/11 : ARG RUN_JAVA_VERSION=1.3.8 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> c45c7ada9216 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 4/11 : ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eea2c4e04c6c [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 5/11 : RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} && microdnf update && microdnf clean all && mkdir /deployments && chown 1001 /deployments && chmod "g+rwX" /deployments && chown 1001:root /deployments && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh && chown 1001 /deployments/run-java.sh && chmod 540 /deployments/run-java.sh && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eedc98908837 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 6/11 : ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> ef0d7a761730 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 7/11 : COPY target/lib/* /deployments/lib/ [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> d8153bf53db2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 8/11 : COPY target/*-runner.jar /deployments/app.jar [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 3df12d03be99 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 9/11 : EXPOSE 8080 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in bb78b4896889 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container bb78b4896889 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> e16d4e1becbb [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 10/11 : USER 1001 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in b451ee1e0bfa [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container b451ee1e0bfa [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 753eaa08a26d [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 11/11 : ENTRYPOINT [ "/deployments/run-java.sh" ] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in 505c90dddf04 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container 505c90dddf04 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> d2af95734312 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully built d2af95734312 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully tagged vagrant/getting-started:1.0-SNAPSHOT [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Built container image vagrant/getting-started:1.0-SNAPSHOT (d2af95734312) [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Deploying to kubernetes server: https://127.0.0.1:6443/ in namespace: default. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: ServiceAccount my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Service my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Deployment my-quarkus-kubernetes-name. [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 12056ms [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 38.809 s [INFO] Finished at: 2020-09-21T14:46:21Z [INFO] ------------------------------------------------------------------------ vagrant@ubuntu-bionic:/vagrant/applications/getting-started$
So, the output is similar as the one from before, when the namespace didn’t already exist!
Remark about the namespace:
As you can see in the output, namespace default is used, although in the Kubernetes manifest I used namespace nl-amis-development. This is not what I expected because, this time, my custom namespace did already exist.
So, why didn’t this namespace thing work?
In order to check the resources that where created, again I used the following command on the Linux Command Prompt:
kubectl get all --all-namespaces
With the following output:
NAMESPACE NAME READY STATUS RESTARTS AGE kube-system pod/metrics-server-7566d596c8-gxrjt 1/1 Running 0 32d kube-system pod/helm-install-traefik-7mps6 0/1 Completed 0 32d kube-system pod/local-path-provisioner-6d59f47c7-vtb4t 1/1 Running 0 32d kube-system pod/coredns-8655855d6-qxqhf 1/1 Running 0 32d kube-system pod/svclb-traefik-hdxqf 2/2 Running 0 32d kube-system pod/traefik-758cd5fc85-m4cvj 1/1 Running 0 32d kubernetes-dashboard pod/kubernetes-dashboard-7b544877d5-l4qfb 1/1 Running 0 32d kubernetes-dashboard pod/dashboard-metrics-scraper-6b4884c9d5-hdxmn 1/1 Running 0 32d default pod/my-quarkus-kubernetes-name-84995c96b7-jvzvt 1/1 Running 0 151m default pod/my-quarkus-kubernetes-name-84995c96b7-sqcfr 1/1 Running 0 151m default pod/my-quarkus-kubernetes-name-84995c96b7-2fjlp 1/1 Running 0 151m NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 32d kube-system service/kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 32d kube-system service/metrics-server ClusterIP 10.43.183.35 <none> 443/TCP 32d kube-system service/traefik-prometheus ClusterIP 10.43.50.120 <none> 9100/TCP 32d kube-system service/traefik LoadBalancer 10.43.116.205 10.0.2.15 80:30676/TCP,443:31713/TCP 32d kubernetes-dashboard service/kubernetes-dashboard ClusterIP 10.43.175.253 <none> 443/TCP 32d kubernetes-dashboard service/dashboard-metrics-scraper ClusterIP 10.43.5.8 <none> 8000/TCP 32d default service/my-quarkus-kubernetes-name NodePort 10.43.242.139 <none> 8090:30526/TCP 151m NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE kube-system daemonset.apps/svclb-traefik 1 1 1 1 1 <none> 32d NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE kube-system deployment.apps/metrics-server 1/1 1 1 32d kube-system deployment.apps/local-path-provisioner 1/1 1 1 32d kube-system deployment.apps/coredns 1/1 1 1 32d kube-system deployment.apps/traefik 1/1 1 1 32d kubernetes-dashboard deployment.apps/kubernetes-dashboard 1/1 1 1 32d kubernetes-dashboard deployment.apps/dashboard-metrics-scraper 1/1 1 1 32d default deployment.apps/my-quarkus-kubernetes-name 3/3 3 3 151m NAMESPACE NAME DESIRED CURRENT READY AGE kube-system replicaset.apps/metrics-server-7566d596c8 1 1 1 32d kube-system replicaset.apps/local-path-provisioner-6d59f47c7 1 1 1 32d kube-system replicaset.apps/coredns-8655855d6 1 1 1 32d kube-system replicaset.apps/traefik-758cd5fc85 1 1 1 32d kubernetes-dashboard replicaset.apps/kubernetes-dashboard-7b544877d5 1 1 1 32d kubernetes-dashboard replicaset.apps/dashboard-metrics-scraper-6b4884c9d5 1 1 1 32d default replicaset.apps/my-quarkus-kubernetes-name-84995c96b7 3 3 3 151m NAMESPACE NAME COMPLETIONS DURATION AGE kube-system job.batch/helm-install-traefik 1/1 41s 32d
The good news, however, is that the ReplicaSet was able to create the 3 Pods, because this time the correct service account name was used.
Manual deployment using the generated kubernetes.yml file
First, I wanted to check if there was a problem with the content of the generated kubernetes.yml file.
In order to manually deploy the resources, I used the following command on the Linux Command Prompt:
kubectl apply -f /vagrant/applications/getting-started/target/kubernetes/kubernetes.yml
With the following output:
unable to decode "/vagrant/applications/getting-started/target/kubernetes/kubernetes.yml": resource.metadataOnlyObject.ObjectMeta: v1.ObjectMeta.Namespace: Name: Labels: ReadString: expects " or n, but found 1, error found in #10 byte of ...|version":1},"name":"|..., bigger context ...|s_version","environment":"development","version":1},"name":"my-quarkus-kubernetes-name","namespace":|... unable to decode "/vagrant/applications/getting-started/target/kubernetes/kubernetes.yml": resource.metadataOnlyObject.ObjectMeta: v1.ObjectMeta.Namespace: Name: Labels: ReadString: expects " or n, but found 1, error found in #10 byte of ...|version":1},"name":"|..., bigger context ...|s_version","environment":"development","version":1},"name":"my-quarkus-kubernetes-name","namespace":|... unable to decode "/vagrant/applications/getting-started/target/kubernetes/kubernetes.yml": resource.metadataOnlyObject.ObjectMeta: v1.ObjectMeta.Namespace: Name: Labels: ReadString: expects " or n, but found 1, error found in #10 byte of ...|version":1},"name":"|..., bigger context ...|s_version","environment":"development","version":1},"name":"my-quarkus-kubernetes-name","namespace":|... vagrant@ubuntu-bionic:/vagrant/applications/getting-started$
So, using the generated yaml file in this way, didn’t work. Apparently, there was something wrong with the label version and its value 1.0. There was an error for every resource that was going to be created.
For just the ServiceAccount part I created a new yaml file, with the following content:
[in bold, I highlighted the changes (except app.quarkus.io/build-timestamp)]
apiVersion: v1 kind: ServiceAccount metadata: annotations: my_key1: key1_value my_key2: key2_value app.quarkus.io/build-timestamp: 2020-09-21 - 14:46:14 +0000 labels: app.kubernetes.io/name: my-quarkus-kubernetes-name app.kubernetes.io/part-of: my_quarkus_kubernetes_part-of app.kubernetes.io/version: my_quarkus_kubernetes_version app: getting-started environment: development version: "1.0" name: my-quarkus-kubernetes-name namespace: nl-amis-development
Remark about a label value:
The label values must be strings. In yaml, that means all numeric values must be quoted.
[https://github.com/kubernetes/kubernetes/issues/57509]
As I also mentioned in my previous article, I tried to get the quotes around the label value by changing the configuration (using quarkus.kubernetes.labels.version) I set earlier in src/main/resources/application.properties, but I didn’t succeed. So, I changed it manually.
[https://technology.amis.nl/2020/10/03/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-part-2/]
Then, I used the following command on the Linux Command Prompt:
kubectl apply -f /vagrant/yaml/serviceaccount-getting-started.yaml
With the following output:
serviceaccount/my-quarkus-kubernetes-name created
In order to check the ServiceAccount that was created, I used the following command on the Linux Command Prompt:
kubectl get serviceAccounts --all-namespaces
With the following output:
NAMESPACE NAME SECRETS AGE kube-system pv-protection-controller 1 32d kube-system certificate-controller 1 32d kube-system generic-garbage-collector 1 32d kube-system cronjob-controller 1 32d kube-system node-controller 1 32d kube-system service-controller 1 32d kube-system coredns 1 32d kube-system clusterrole-aggregation-controller 1 32d kube-system endpoint-controller 1 32d kube-system replication-controller 1 32d kube-system daemon-set-controller 1 32d kube-system job-controller 1 32d kube-system local-path-provisioner-service-account 1 32d kube-system horizontal-pod-autoscaler 1 32d kube-system pvc-protection-controller 1 32d kube-system endpointslice-controller 1 32d kube-system service-account-controller 1 32d kube-system replicaset-controller 1 32d kube-system expand-controller 1 32d kube-system metrics-server 1 32d kube-system pod-garbage-collector 1 32d kube-system namespace-controller 1 32d kube-system disruption-controller 1 32d kube-system statefulset-controller 1 32d kube-system ttl-controller 1 32d kube-system resourcequota-controller 1 32d kube-system helm-traefik 1 32d kube-system deployment-controller 1 32d kube-system persistent-volume-binder 1 32d kube-system attachdetach-controller 1 32d kube-system default 1 32d kube-public default 1 32d kube-node-lease default 1 32d default default 1 32d kube-system traefik 1 32d kubernetes-dashboard kubernetes-dashboard 1 32d kubernetes-dashboard default 1 32d kubernetes-dashboard admin-user 1 32d nl-amis-development default 1 3h13m nl-amis-development my-quarkus-kubernetes-name 1 4m47s
So, doing it this way, a service account is created in my custom namespace.
By the way:
Service Account Controller manages ServiceAccount inside namespaces, and ensures a ServiceAccount named “default” exists in every active namespace.
[https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/#service-account-controller]
Next, in a similar way like I did before, I removed all the created resources.
Deployment with namespace set in current Kubernetes context
Remember, in the Deployment, the environment variable KUBERNETES_NAMESPACE is used. Its value is derived from the Pod’s metadata.namespace field.
When the ‘namespace’ field is not added to the ‘metadata’ section of the generated manifest, this means that when the manifests are applied to a cluster, the namespace will be resolved from the current Kubernetes context (see https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#context for more details).
[https://quarkus.io/guides/all-config]
In order to permanently save the namespace for all subsequent kubectl commands in that context, I used the following command on the Linux Command Prompt:
[https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-context-and-configuration]
sudo kubectl config set-context --current --namespace=nl-amis-development
With the following output:
In order to validate the current Kubernetes context, I used the following command on the Linux Command Prompt:
[https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#setting-the-namespace-preference]
kubectl config view --minify | grep namespace:
With the following output:
namespace: nl-amis-development
So now the kubeconfig settings are changed, on my demo environment, I had to recreate the .kube/config file in my user (/home/vagrant) directory. So, again I used the following command on the Linux Command Prompt:
With the following output:
total 20 drwxr-xr-x 7 vagrant vagrant 4096 Sep 13 15:18 .. drwxr-x--- 3 vagrant vagrant 4096 Sep 13 15:18 cache drwxr-x--- 4 vagrant vagrant 4096 Sep 21 13:49 . -rw-rw-r-- 1 vagrant vagrant 1044 Sep 21 13:49 config drwxr-x--- 3 vagrant vagrant 4096 Sep 22 14:42 http-cache
In order to build and deploy a container image, again I used the following command on the Linux Command Prompt:
cd /vagrant/applications/getting-started ./mvnw clean package -Dquarkus.kubernetes.deploy=true
With the following output:
[INFO] Scanning for projects... [INFO] [INFO] ----------------------< org.acme:getting-started >---------------------- [INFO] Building getting-started 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- maven-clean-plugin:2.5:clean (default-clean) @ getting-started --- [INFO] Deleting /vagrant/applications/getting-started/target [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 4 resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:compile (default-compile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/classes [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:prepare-tests (default) @ getting-started --- [INFO] [INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ getting-started --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] skip non existing resourceDirectory /vagrant/applications/getting-started/src/test/resources [INFO] [INFO] --- maven-compiler-plugin:3.8.1:testCompile (default-testCompile) @ getting-started --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 2 source files to /vagrant/applications/getting-started/target/test-classes [INFO] [INFO] --- maven-surefire-plugin:3.0.0-M5:test (default-test) @ getting-started --- [INFO] [INFO] ------------------------------------------------------- [INFO] T E S T S [INFO] ------------------------------------------------------- [INFO] Running org.acme.getting.started.GreetingResourceTest 2020-09-22 14:50:35,938 WARN [io.qua.config] (main) Unrecognized configuration key "quarkus.kubernetes.deploy" was provided; it will be ignored; verify that the dependency extension for this configuration is set or you did not make a typo 2020-09-22 14:50:36,914 INFO [io.quarkus] (main) Quarkus 1.7.0.Final on JVM started in 5.126s. Listening on: http://0.0.0.0:8081 2020-09-22 14:50:36,917 INFO [io.quarkus] (main) Profile test activated. 2020-09-22 14:50:36,917 INFO [io.quarkus] (main) Installed features: [cdi, kubernetes, resteasy] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 14.502 s - in org.acme.getting.started.GreetingResourceTest 2020-09-22 14:50:41,102 INFO [io.quarkus] (main) Quarkus stopped in 0.055s [INFO] [INFO] Results: [INFO] [INFO] Tests run: 2, Failures: 0, Errors: 0, Skipped: 0 [INFO] [INFO] [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ getting-started --- [INFO] Building jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT.jar [INFO] [INFO] --- quarkus-maven-plugin:1.7.0.Final:build (default) @ getting-started --- [INFO] [org.jboss.threads] JBoss Threads version 3.1.1.Final [WARNING] [io.quarkus.kubernetes.deployment.KubernetesDeployer] A Kubernetes deployment was requested, but the container image to be built will not be pushed to any registry because "quarkus.container-image.registry" has not been set. The Kubernetes deployment will only work properly if the cluster is using the local Docker daemon. For that reason 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] [io.quarkus.deployment.pkg.steps.JarResultBuildStep] Building thin jar: /vagrant/applications/getting-started/target/getting-started-1.0-SNAPSHOT-runner.jar [WARNING] [io.quarkus.kubernetes.deployment.KubernetesProcessor] No registry was set for the container image, so 'ImagePullPolicy' is being force-set to 'IfNotPresent'. [INFO] Checking for existing resources in: /vagrant/applications/getting-started/src/main/kubernetes. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeploy] Kubernetes API Server at 'https://127.0.0.1:6443/' successfully contacted. [INFO] [io.quarkus.container.image.docker.deployment.DockerWorking] Docker daemon found. Version:'19.03.12' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Building docker image for jar. [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Executing the following command to build docker image: 'docker build -f /vagrant/applications/getting-started/src/main/docker/Dockerfile.jvm -t vagrant/getting-started:1.0-SNAPSHOT /vagrant/applications/getting-started' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Sending build context to Docker daemon 11.09MB [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 1/11 : FROM registry.access.redhat.com/ubi8/ubi-minimal:8.1 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 91d23a64fdf2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 2/11 : ARG JAVA_PACKAGE=java-11-openjdk-headless [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 3818465cc8fa [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 3/11 : ARG RUN_JAVA_VERSION=1.3.8 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> c45c7ada9216 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 4/11 : ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eea2c4e04c6c [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 5/11 : RUN microdnf install curl ca-certificates ${JAVA_PACKAGE} && microdnf update && microdnf clean all && mkdir /deployments && chown 1001 /deployments && chmod "g+rwX" /deployments && chown 1001:root /deployments && curl https://repo1.maven.org/maven2/io/fabric8/run-java-sh/${RUN_JAVA_VERSION}/run-java-sh-${RUN_JAVA_VERSION}-sh.sh -o /deployments/run-java.sh && chown 1001 /deployments/run-java.sh && chmod 540 /deployments/run-java.sh && echo "securerandom.source=file:/dev/urandom" >> /etc/alternatives/jre/lib/security/java.security [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> eedc98908837 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 6/11 : ENV JAVA_OPTIONS="-Dquarkus.http.host=0.0.0.0 -Djava.util.logging.manager=org.jboss.logmanager.LogManager" [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> ef0d7a761730 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 7/11 : COPY target/lib/* /deployments/lib/ [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Using cache [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> d8153bf53db2 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 8/11 : COPY target/*-runner.jar /deployments/app.jar [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 59b825cb8990 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 9/11 : EXPOSE 8080 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in bde06af91dbf [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container bde06af91dbf [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 6b375d273b9d [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 10/11 : USER 1001 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in 4558ef2af8fb [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container 4558ef2af8fb [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> 8cf926c7f9f0 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Step 11/11 : ENTRYPOINT [ "/deployments/run-java.sh" ] [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> Running in cd400ddd9c11 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Removing intermediate container cd400ddd9c11 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] ---> afb3bc1d2ea1 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully built afb3bc1d2ea1 [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Successfully tagged vagrant/getting-started:1.0-SNAPSHOT [INFO] [io.quarkus.container.image.docker.deployment.DockerProcessor] Built container image vagrant/getting-started:1.0-SNAPSHOT (afb3bc1d2ea1) [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Deploying to kubernetes server: https://127.0.0.1:6443/ in namespace: nl-amis-development. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: ServiceAccount my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Service my-quarkus-kubernetes-name. [INFO] [io.quarkus.kubernetes.deployment.KubernetesDeployer] Applied: Deployment my-quarkus-kubernetes-name. [INFO] [io.quarkus.deployment.QuarkusAugmentor] Quarkus augmentation completed in 12151ms [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 40.553 s [INFO] Finished at: 2020-09-22T14:50:54Z [INFO] ------------------------------------------------------------------------ vagrant@ubuntu-bionic:/vagrant/applications/getting-started$
So, this time, as you can see in the output, the correct nl-amis-development namespace is used. I am not sure however why the construction with the environment variable KUBERNETES_NAMESPACE in the generated Kubernetes manifest for Deployment didn’t work in my case. At least my work around for this problem did work.
Kubernetes Dashboard
Next, in the Web Browser on my Windows laptop, I started the Kubernetes Dashboard in my demo environment, in order to check the generated resources.
Below, you can see an overview of the Namespaces:
I changed the namespace to nl-amis-development. Below, you can see an overview of the Deployments:
Below, you can see an overview of the Replica Sets:
Below, you can see an overview of the Pods:
Here, again we can see that the ReplicaSet was able to create the 3 Pods.
Below, you can see some more details (including all the labels) of the first Pod:
I opened the log from the first Pod:
Below, you can see an overview of the Services:
I noticed something about the ports, so I clicked on Edit:
As you may remember, in my previous article I described how I changed the service type to NodePort and tried, but did not succeed, to set the values for nodePort, port and targetPort to respectively: 30010, 8190 and 8090. So, in the end, these settings were also not used in the deployed Service!
Then I closed the “Edit a resource” window.
Below, you can see some more details of the Service:
Here you can see the endpoints of the 3 Pods, I will be using later on.
So, this confirmed to me that everything was up and running.
For every one of the 3 Pods I quickly checked if they worked. Below you see the check I did for the first Pod (with the endpoint we saw earlier).
I used the following command on the Linux Command Prompt:
curl http://10.42.0.25:8090/hello
With the following output:
I used the following command on the Linux Command Prompt:
curl http://10.42.0.25:8090/hello/greeting/readers
With the following output:
For the other two Pods, I did the same, using the host 10.42.0.26 and 10.42.0.27.
Besides already being able to use the Kubernetes Dashboard (in a Web Browser) on my Windows laptop (via port forwarding), I also wanted to be able to use a Web Browser on my Windows laptop, for sending requests to the Kubernetes my-quarkus-kubernetes-name Service on my guest (Ubuntu).
In order to determine the IP of the K3s node, I used the following command on the Linux Command Prompt, as I described in a previous article:
[https://technology.amis.nl/2020/04/30/creating-a-re-usable-vagrant-box-from-an-existing-vm-with-ubuntu-and-k3s-with-the-kubernetes-dashboard-and-adding-mysql-using-vagrant-and-oracle-virtualbox/]
nodeIP=$(kubectl get node ubuntu-bionic -o yaml | grep address: | grep -E -o "([0-9]{1,3}[\.]){3}[0-9]{1,3}") echo "---$nodeIP---"
With the following output:
In order to forward local port 8090 to port 32171 on the K3s node ($nodeIP), I used the following command on the Linux Command Prompt, as I described in a previous article:
[https://technology.amis.nl/2020/04/30/creating-a-re-usable-vagrant-box-from-an-existing-vm-with-ubuntu-and-k3s-with-the-kubernetes-dashboard-and-adding-mysql-using-vagrant-and-oracle-virtualbox/]
socat tcp-listen:8090,fork tcp:$nodeIP:32171 &
With the following output:
[1] 19990
vagrant@ubuntu-bionic:~$
Then, in the Web Browser on my Windows laptop, I entered the URL: http://localhost:8090/hello
And I got the following result:
Then, in the Web Browser on my Windows laptop, I entered the URL: http://localhost:8090/hello/greeting/readers
And I got the following result:
So, running the application in a container using the produced executable worked.
Below, is a schematic overview of my demo environment with K3s (with the Kubernetes Dashboard) on top of an Ubuntu guest Operating System within an VirtualBox appliance, created using Vagrant:
So, I conclude this article. I shared with you the steps I took trying out the Quarkus code guide “Quarkus – Kubernetes extension”, and more specific the steps related the automatic deployment of the generated resources to a target platform, in my case K3s (lightweight certified Kubernetes distribution).
If you have read my last articles about this code quide, you know I had quite some problems trying to get the customizations I wanted into the generated Kubernetes manifests. Be aware that for a production environment you probably want to do things a bit different any way and have more control of what is going to be deployed. For a development situation it’s probably all right. At least the generated resources can provide a good base, for example for manually creating the final version of a particular resource and putting it in a version control system (like git).
I want to point out some remarks that are also made in the code guide itself, with regard to deploying to Minikube.
[https://quarkus.io/guides/deploying-to-kubernetes#deploying-to-minikube]
I also want to point out the part in the code guide about using existing resources.
Sometimes it’s desirable to either provide additional resources (e.g. a ConfigMap, a Secret, a Deployment for a database etc) or provide custom ones that will be used as a base for the generation process. Those resources can be added under src/main/kubernetes directory and can be named after the target environment (e.g. kubernetes.json, openshift.json, knative.json, or the yml equivalents). Each of these files may contain one or more Kubernetes resources.
Any resource found will be added in the generated manifests. Global modifications (e.g. labels, annotations etc) will also be applied to those resources. If one of the provided resources has the same name as one of the generated ones, then the generated resource will be created on top of the provided resource, respecting existing content when possible (e.g. existing labels, annotations, environment variables, mounts, replicas etc).
The name of the resource is determined by the application name and may be overridden by quarkus.kubernetes.name, quarkus.openshift.name and quarkus.knative.name.
[https://quarkus.io/guides/deploying-to-kubernetes#using-existing-resources]