Quarkus - Supersonic Subatomic Java, trying out Quarkus guide “Quarkus - Kubernetes extension” (part 2) lameriks 2020 10 1f

Quarkus – Supersonic Subatomic Java, trying out Quarkus guide “Quarkus – Kubernetes extension” (part 2)

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 steps I took related to customizing the namespace, the service account name, the number of replicas and the type of service.
[https://quarkus.io/guides/deploying-to-kubernetes]

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/09/27/quarkus-supersonic-subatomic-java-trying-out-quarkus-guide-quarkus-kubernetes-extension-part-1/]

Kubernetes Namespaces

Namespaces are intended for use in environments with many users spread across multiple teams, or projects. For clusters with a few to tens of users, you should not need to create or think about namespaces at all. Start using namespaces when you need the features they provide.

Namespaces provide a scope for names. Names of resources need to be unique within a namespace, but not across namespaces. Namespaces cannot be nested inside one another and each Kubernetes resource can only be in one namespace.

Namespaces are a way to divide cluster resources between multiple users (via resource quota).
[https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/#when-to-use-multiple-namespaces]

Kubernetes Resource Quotas

When several users or teams share a cluster with a fixed number of nodes, there is a concern that one team could use more than its fair share of resources.

Resource quotas are a tool for administrators to address this concern.

A resource quota, defined by a ResourceQuota object, provides constraints that limit aggregate resource consumption per namespace. It can limit the quantity of objects that can be created in a namespace by type, as well as the total amount of compute resources that may be consumed by resources in that project.
[https://kubernetes.io/docs/concepts/policy/resource-quotas/]

Customizing the namespaces

In a previous article I describe how I deployed applications (based on the booksservice) to Minikube.
I described how, in the Kubernetes manifest files, I used namespaces. In my case these namespaces were for example:

  • nl-amis-development
  • nl-amis-testing

[https://technology.amis.nl/2019/03/05/using-a-restful-web-service-spring-boot-application-in-minikube-together-with-an-external-dockerized-mysql-database/]

A namespace can be added by applying the following configuration:

quarkus.kubernetes.namespace

I changed the code of src/main/resources/application.properties by adding the following:

# Kubernetes manifest namespaces
quarkus.kubernetes.namespace=nl-amis-development

In order to recreate the Kubernetes manifests, I used the following command on the Linux Command Prompt:

./mvnw package

Below, you can see the content of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[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-12 - 10:02:17 +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
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-12 - 10:02:17 +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
spec:
  ports:
  - name: http
    port: 8090
    targetPort: 8090
  selector:
    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
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-12 - 10:02:17 +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
spec:
  replicas: 1
  selector:
    matchLabels:
      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
  template:
    metadata:
      annotations:
        my_key1: key1_value
        my_key2: key2_value
        app.quarkus.io/build-timestamp: 2020-09-12 - 10:02:17 +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
      namespace: nl-amis-development
    spec:
      containers:
      - env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: vagrant/getting-started:1.0-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: my-quarkus-kubernetes-name
        ports:
        - containerPort: 8090
          name: http
          protocol: TCP
      serviceAccount: my-quarkus-kubernetes-name

Remark:
The Kubernetes manifest for the Namespace itself isn’t generated. Which is to be expected because a namespace can be used by several Kubernetes manifests generated from several Quarkus applications.

In the Deployment, the environment variable KUBERNETES_NAMESPACE is used. Its value is derived from the Pod’s metadata.namespace field, which in my case results to nl-amis-development.

The field in this example is a Pod field. It is not a field of the Container in the Pod.

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 display a list of Kubernetes contexts, I used the following command on the Linux Command Prompt:
[https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-context-and-configuration]

kubectl config get-contexts

With the following output:


CURRENT   NAME      CLUSTER   AUTHINFO   NAMESPACE
*         default   default   default

In order to display the current Kubernetes context, I used the following command on the Linux Command Prompt:
[https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-context-and-configuration]

kubectl config current-context

With the following output:


default

In order to view the config, I used the following command on the Linux Command Prompt:
[https://kubernetes.io/docs/reference/kubectl/cheatsheet/#kubectl-context-and-configuration]

kubectl config view

With the following output:


apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUJWVENCL3FBREFnRUNBZ0VBTUFvR0NDcUdTTTQ5QkFNQ01DTXhJVEFmQmdOVkJBTU1HR3N6Y3kxelpYSjIKWlhJdFkyRkFNVFU1TnpnMk1ERTFNVEFlRncweU1EQTRNVGt4T0RBeU16RmFGdzB6TURBNE1UY3hPREF5TXpGYQpNQ014SVRBZkJnTlZCQU1NR0dzemN5MXpaWEoyWlhJdFkyRkFNVFU1TnpnMk1ERTFNVEJaTUJNR0J5cUdTTTQ5CkFnRUdDQ3FHU000OUF3RUhBMElBQkxVOGFhUWhKdE5URG5ORkhDUlBrUEhnL2FHTUxldDhSbnNkektLSXdySmgKZzFmeTFNR283dXp3NThXYXhtMlkwNGtaYXlSZXRoVlRSNGpWUnRoK0J5eWpJekFoTUE0R0ExVWREd0VCL3dRRQpBd0lDcERBUEJnTlZIUk1CQWY4RUJUQURBUUgvTUFvR0NDcUdTTTQ5QkFNQ0EwWUFNRU1DSHdnN1J6c2trb2grClVrUldsVXNwK1ZRMjVkNjRxVHFwK1huTzVmTjVYdWdDSUdhWm8zbDVZVCtuSW1HQjZad1QwanM5STY4dTY4b0oKblRpeHZGTndrWWxyCi0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
    server: https://127.0.0.1:6443
  name: default
contexts:
- context:
    cluster: default
                                  
    user: default
  name: default
current-context: default
kind: Config
preferences: {}
users:
- name: default
  user:
    password: cfb31936a4fc771b81540abfef608679
    username: admin

So, the default context is used, implying, the namespace default is used when the metadata.namespace field is not set.

Namespace default is the default namespace for objects with no other namespace
[https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/]

Customizing the service account

The service account name can be set by applying the following configuration:

quarkus.kubernetes.service-account

I changed the code of src/main/resources/application.properties by adding the following:

# Kubernetes manifest service-account
quarkus.kubernetes.service-account=my-quarkus-kubernetes-service-account

In order to recreate the Kubernetes manifests, I used the following command on the Linux Command Prompt:

./mvnw package

Below, you can see the content of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[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-12 - 11:06:21 +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
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-12 - 11:06:21 +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
spec:
  ports:
  - name: http
    port: 8090
    targetPort: 8090
  selector:
    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
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-12 - 11:06:21 +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
spec:
  replicas: 1
  selector:
    matchLabels:
      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
  template:
    metadata:
      annotations:
        my_key1: key1_value
        my_key2: key2_value
        app.quarkus.io/build-timestamp: 2020-09-12 - 11:06:21 +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
      namespace: nl-amis-development
    spec:
      containers:
      - env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: vagrant/getting-started:1.0-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: my-quarkus-kubernetes-name
        ports:
        - containerPort: 8090
          name: http
          protocol: TCP
      serviceAccount: my-quarkus-kubernetes-service-account

Remark about the Deloyment, serviceAccount part:
You can see that serviceAccount is used. However, serviceAccount is a depreciated alias for serviceAccountName. Deprecated: Use serviceAccountName instead. ServiceAccountName is the name of the ServiceAccount to use to run this pod. More info: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
[https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#podspec-v1-core]

To use a non-default service account, simply set the spec.serviceAccountName field of a pod to the name of the service account you wish to use.

The service account has to exist at the time the pod is created, or it will be rejected.
[https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/]

Remark about the ServiceAccount metadata.name:
As you can see, the metadata.name of the ServiceAccount isn’t changed! So, the service account that is used to run the pod, refers to a non-existing service account!

Customizing the number of replicas

The number of desired pods can be set by applying the following configuration:

quarkus.kubernetes.replicas

Then, following the guide, I changed the code of src/main/resources/application.properties by adding the following:

# Kubernetes manifest service-account
quarkus.kubernetes.replicas=3

In order to recreate the Kubernetes manifests, I used the following command on the Linux Command Prompt:

./mvnw package

Below, you can see the content of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[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-13 - 08:22:47 +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
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-13 - 08:22:47 +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
spec:
  ports:
  - name: http
    port: 8090
    targetPort: 8090
  selector:
    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
  type: ClusterIP
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-13 - 08:22:47 +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
spec:
  replicas: 3
  selector:
    matchLabels:
      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
  template:
    metadata:
      annotations:
        my_key1: key1_value
        my_key2: key2_value
        app.quarkus.io/build-timestamp: 2020-09-13 - 08:22:47 +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
      namespace: nl-amis-development
    spec:
      containers:
      - env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: vagrant/getting-started:1.0-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: my-quarkus-kubernetes-name
        ports:
        - containerPort: 8090
          name: http
          protocol: TCP
      serviceAccount: my-quarkus-kubernetes-service-account

Customizing the service type

The type of service that will be generated for the application can be set by applying the following configuration:
[https://quarkus.io/guides/all-config]

quarkus.kubernetes.service-type

For some parts of your application (for example, frontends) you may want to expose a Service onto an external IP address, that’s outside of your cluster.
Kubernetes ServiceTypes allow you to specify what kind of Service you want. The default is ClusterIP.
[https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types]

The service type values and their behaviors are:

Type Behavior
ClusterIP Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
NodePort Exposes the Service on each Node's IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You'll be able to contact the NodePort Service, from outside the cluster, by requesting <NodeIP>:<NodePort>.
LoadBalancer Exposes the Service externally using a cloud provider's load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
ExternalName Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record with its value. No proxying of any kind is set up.

You can also use Ingress to expose your Service. Ingress is not a Service type, but it acts as the entry point for your cluster. It lets you consolidate your routing rules into a single resource as it can expose multiple services under the same IP address.
[https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types]

In a previous article I describe how I deployed applications (based on the booksservice) to Minikube.
I described how, in the Kubernetes manifest files, I used nodePort as the type of service, because, on my Windows laptop, I also wanted to be able to use Postman (for sending requests). Via port forwarding this was made possible.
[https://technology.amis.nl/2019/04/23/using-vagrant-and-shell-scripts-to-further-automate-setting-up-my-demo-environment-from-scratch-including-elasticsearch-fluentd-and-kibana-efk-within-minikube/]

When the serviceType is set to node-port, you have to set the nodePort, via:
[https://quarkus.io/guides/all-config]

quarkus.kubernetes.node-port

I changed the code of src/main/resources/application.properties by adding the following:

# Kubernetes manifest service-type
quarkus.kubernetes.service-type=node-port
quarkus.kubernetes.node-port=30010

In order to recreate the Kubernetes manifests, I used the following command on the Linux Command Prompt:

./mvnw package

Below, you can see the content (only the Service part) of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[in bold, I highlighted the changes (except app.quarkus.io/build-timestamp)]


apiVersion: v1
kind: Service
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-13 - 08:58:44 +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
spec:
  ports:
  - name: http
    port: 8090
    targetPort: 8090
  selector:
    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
  type: NodePort

Remark:
The node-port (nodePort: 30010) wasn’t set as expected!

In the previous article, I mentioned earlier, I used the following Kubernetes manifest file for a Service:
[https://technology.amis.nl/2019/03/05/using-a-restful-web-service-spring-boot-application-in-minikube-together-with-an-external-dockerized-mysql-database/]

kind: Service
apiVersion: v1
metadata:
  name: booksservice-v1-0-service
  namespace: nl-amis-development
  labels:
    app: booksservice
    version: "1.0"
    environment: development
spec:
  selector:
    app: booksservice
    version: "1.0"
    environment: development
  type: NodePort
  ports:
  - protocol: TCP
    nodePort: 30010
    port: 9190
    targetPort: 9090

Just a reminder about ports:

Field Description
nodePort The port on each node on which this service is exposed when type=NodePort or LoadBalancer. Usually assigned by the system. If specified, it will be allocated to the service if unused or else creation of the service will fail. Default is to auto-allocate a port if the ServiceType of this Service requires one. More info: https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport
port The port that will be exposed by this service.
targetPort Number or name of the port to access on the pods targeted by the service. Number must be in the range 1 to 65535. Name must be an IANA_SVC_NAME. If this is a string, it will be looked up as a named port in the target Pod's container ports. If this is not specified, the value of the 'port' field is used (an identity map). This field is ignored for services with clusterIP=None, and should be omitted or set equal to the 'port' field. More info: https://kubernetes.io/docs/concepts/services-networking/service/#defining-a-service

[https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#serviceport-v1-core]

In line with the example above I wanted to set the port and targetPort.

The host port can be set by applying the following configuration:
[https://quarkus.io/guides/all-config]

quarkus.kubernetes.ports.”ports”.host-port

The port number which refers to the container port can be set by applying the following configuration:
[https://quarkus.io/guides/all-config]

quarkus.kubernetes.ports.”ports”.container-port

I changed the code of src/main/resources/application.properties by adding the following:

quarkus.kubernetes.ports."ports".host-port=8190
quarkus.kubernetes.ports."ports".container-port=8090

In order to recreate the Kubernetes manifests, I used the following command on the Linux Command Prompt:

./mvnw package

Below, you can see the content of the target/kubernetes/kubernetes.yml Kubernetes manifests, provided by the Quarkus project packaging:
[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-13 - 15:02:01 +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
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-13 - 15:02:01 +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
spec:
  ports:
  - name: ports
    port: 8090
    targetPort: 8190
  selector:
    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
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    my_key1: key1_value
    my_key2: key2_value
    app.quarkus.io/build-timestamp: 2020-09-13 - 15:02:01 +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
spec:
  replicas: 3
  selector:
    matchLabels:
      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
  template:
    metadata:
      annotations:
        my_key1: key1_value
        my_key2: key2_value
        app.quarkus.io/build-timestamp: 2020-09-13 - 15:02:01 +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
      namespace: nl-amis-development
    spec:
      containers:
      - env:
        - name: KUBERNETES_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: vagrant/getting-started:1.0-SNAPSHOT
        imagePullPolicy: IfNotPresent
        name: my-quarkus-kubernetes-name
        ports:
        - containerPort: 8090
          hostPort: 8190
          name: ports
          protocol: TCP
      serviceAccount: my-quarkus-kubernetes-service-account

Although the nodePort wasn’t set, I proceeded with the next steps of the code guide. But more about that, you can read in a next article.

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 to customizing the namespace, the service account name, the number of replicas and the type of service.

By the way, the code guide also covers topics like environment variables, and adding readiness and liveness probes. I skipped those for now.

In a next article, you can read more about the steps I took (continuing with the code guide) with regard to the automatic deployment of the generated resources to a target platform, in my case K3s (lightweight certified Kubernetes distribution).