Micronaut Kubernetes

Integration between Micronaut and Kubernetes

Version: 1.0.0.BUILD-SNAPSHOT

1 Introduction

This project eases Kubernetes integration with Micronaut.

To use the BUILD-SNAPSHOT version of this library, check the documentation to use snapshots.

It adds support for the following features:

  • Service Discovery.

  • Configuration client.

To get started, you need to declare the following dependency:

compile 'io.micronaut.kubernetes:micronaut-kubernetes-discovery-client:1.0.0.BUILD-SNAPSHOT'
<dependency>
    <groupId>io.micronaut.kubernetes</groupId>
    <artifactId>micronaut-kubernetes-discovery-client</artifactId>
    <version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>

The core library for all features can be configured using the following configuration properties:

🔗
Table 1. Configuration Properties for KubernetesConfiguration
Property Type Description

kubernetes.namespace

java.lang.String

Sets the namespace. Default value: {@value #DEFAULT_NAMESPACE}.

kubernetes.ssl-configuration

SslConfiguration

kubernetes.logger-name

java.lang.String

kubernetes.follow-redirects

boolean

kubernetes.default-charset

java.nio.charset.Charset

kubernetes.channel-options

java.util.Map

kubernetes.shutdown-timeout

java.time.Duration

kubernetes.read-timeout

java.time.Duration

kubernetes.read-idle-timeout

java.time.Duration

kubernetes.connect-timeout

java.time.Duration

kubernetes.num-of-threads

java.lang.Integer

kubernetes.thread-factory

java.lang.Class

kubernetes.max-content-length

int

kubernetes.proxy-type

java.net.Proxy$Type

kubernetes.proxy-address

java.net.SocketAddress

kubernetes.proxy-username

java.lang.String

kubernetes.proxy-password

java.lang.String

2 Service Discovery

The Service Discovery module allows Micronaut HTTP clients to discover Kubernetes services.

In any client you can use as Service ID the Kubernetes Endpoints name generated by a Kubernetes Service.

Consider the following Kubernetes service definition:

my-service.yml
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  selector:
    app: MyApp
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376

This specification will create a new Service object named my-service, as well as an Endpoints object also named my-service.

In your HTTP client, you can use my-service as Service ID: @Client("my-service").

Kubernetes API authentication

Micronaut connects to the Kubernetes API using the default service account, which by default only has permissions over the kube-system namespace. This service account needs read permission over the services and endpoints namespace. Refer to the Kubernetes documentation for more information about Role-based access control (RBAC).

One of the options is to create the following Role and RoleBinding:

auth.yml
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: service-discoverer
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["services", "endpoints", "configmaps"]
    verbs: ["get", "watch", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: default-service-discoverer
  namespace: default
subjects:
  - kind: ServiceAccount
    name: default
    namespace: default
roleRef:
  kind: Role
  name: service-discoverer
  apiGroup: rbac.authorization.k8s.io
In Google Cloud’s Kubernetes Engine, in order to create the above, you must grant your user the ability to create roles in Kubernetes by running the following command:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole cluster-admin --user yourGoogleAccount@gmail.com

Connecting to services using HTTPS

There are three ways for this library to determine whether a service should be connected to using SSL (the following examples assume there is a Deployment named secure-deployment).

Using https as port name

my-service.yml
apiVersion: v1
kind: Service
metadata:
  name: secure-service-port-name
spec:
  selector:
    app: secure-deployment
  type: NodePort
  ports:
    - port: 1234
      protocol: TCP
      name: https

Using a port ending in 443

Port numbers like 443, 8443, etc. will match.

my-service.yml
apiVersion: v1
kind: Service
metadata:
  name: secure-service-port-number
spec:
  selector:
    app: secure-deployment
  type: NodePort
  ports:
    - port: 443
      protocol: TCP

Using labels

Set a label named secure with value true to have the client use HTTPS.

my-service.yml
apiVersion: v1
kind: Service
metadata:
  name: secure-service-labels
  labels:
    secure: "true"
spec:
  selector:
    app: secure-deployment
  type: NodePort
  ports:
    - port: 1234
      protocol: TCP

3 Configuration Client

The Configuration client will read Kubernetes' `ConfigMap`s and make them available as `PropertySource`s in your application.

Then, in any bean you can read the configuration values from the ConfigMap using @Value or any other way to read configuration values.

Supported formats are:

  • Java .properties.

  • YAML.

Example

You can create a Kubernetes ConfigMap off an existing file with the following command:

kubectl create configmap my-config --from-file=my-config.properties

Or:

kubectl create configmap my-config --from-file=my-config.yml