Kubernetes API

The typical way to consume a service in Kubernetes is to discover it through DNS: this will take into account liveness/readiness checks, and depending on the configuration take care of load balancing (removing the need for client-side load balancing). For this reason, for general usage the akka-dns implementation is usually a better fit for discovering services in Kubernetes. However, in some cases, such as for Cluster Bootstrap, it is desirable to connect to the pods directly, bypassing any liveness/readiness checks or load balancing. For such situations we provide a discovery implementation that uses the Kubernetes API.

Project Info

Project Info: Akka Discovery Kubernetes
JDK versions
Adopt OpenJDK 8 with Hotspot
Adopt OpenJDK 11 with Hotspot
Scala versions2.11.12, 2.12.8, 2.13.0-M5
Readiness level
Since 1.0.0, 2019-03-15
Home pagehttps://akka.io/
API documentation
Release notesGitHub releases
IssuesGitHub issues

Dependencies and usage

First, add the dependency on the component:

libraryDependencies += "com.lightbend.akka.discovery" %% "akka-discovery-kubernetes-api" % "1.0.1"
dependencies {
  compile group: 'com.lightbend.akka.discovery', name: 'akka-discovery-kubernetes-api_2.12', version: '1.0.1'

As described above, it is uncommon to use the Kubernetes API discovery mechanism as your default discovery mechanism. When using it with Akka Cluster Bootstrap, it is sufficient to configure it as described here. Otherwise, to load it manually, use loadServiceDiscovery on the Discovery extension:

val discovery = Discovery(system).loadServiceDiscovery("kubernetes-api")
ServiceDiscovery discovery = Discovery.get(system).loadServiceDiscovery("kubernetes-api");

To find other pods, this method needs to know how they are labeled, what the name of the target port is, and what namespace they reside in. Below, you’ll find the default configuration. It can be customized by changing these values in your application.conf.

akka.discovery {
  kubernetes-api {
    # Namespace discovery path
    # If this path doesn't exist, the namespace will default to "default".
    pod-namespace-path = "/var/run/secrets/kubernetes.io/serviceaccount/namespace"
    # Namespace to query for pods.
    # Set this value to a specific string to override discovering the namespace using pod-namespace-path.
    pod-namespace = "<pod-namespace>"

    # Selector value to query pod API with.
    # `%s` will be replaced with the configured effective name, which defaults to the actor system name
    pod-label-selector = "app=%s"

This configuration complements the following Deployment specification:

apiVersion: extensions/v1beta1
kind: Deployment
    app: example
  name: example
  replicas: 4
      app: example
        app: example
      - name: example
        image: example/image:1.0.0
        imagePullPolicy: IfNotPresent
        # akka remoting
        - name: remoting
          containerPort: 2552
          protocol: TCP
        # When
        # akka.management.cluster.bootstrap.contact-point-discovery.port-name
        # is defined, it must correspond to this name:
        - name: management
          containerPort: 8558
          protocol: TCP

Role-Based Access Control

If your Kubernetes cluster has Role-Based Access Control (RBAC) enabled, you’ll also have to grant the Service Account that your pods run under access to list pods. The following configuration can be used as a starting point. It creates a Role, pod-reader, which grants access to query pod information. It then binds the default Service Account to the Role by creating a RoleBinding. Adjust as necessary.

Using Google Kubernetes Engine? Your user will need permission to grant roles. See Google’s Documentation for more information.

# Create a role, `pod-reader`, that can list pods and
# bind the default service account in the `default` namespace
# to that role.

kind: Role
apiVersion: rbac.authorization.k8s.io/v1
  name: pod-reader
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
  name: read-pods
# Note the `name` line below. The first default refers to the namespace. The second refers to the service account name.
# For instance, `name: system:serviceaccount:myns:default` would refer to the default service account in namespace `myns`
- kind: User
  name: system:serviceaccount:default:default
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.