Skip to content

jeroenr/k8s-svc-discovery

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

K8s service discovery hook Build Status Maven Central

Simple library which implements an agent that listens for Kubernetes svc events and provides a callback to receive service metadata. It's polling the Kubernetes API endpoint /api/v1/services endpoint for services

Contributions

This is a young but very active project and absolutely needs your help. Good ways to contribute include:

  • Raising bugs and feature requests
  • Fixing bugs
  • Improving the performance
  • Adding to the documentation

Quick start

Setup

Latest stable release is 0.6 and is available on Maven Central. Just add the following dependency:

libraryDependencies ++= Seq(
  "com.github.jeroenr" %% "k8s-svc-discovery" % "0.6"
)

Or if you want to be on the bleeding edge using snapshots, latest snapshot release is 0.7-SNAPSHOT. Add the following repository and dependency:

resolvers += "Sonatype Snapshots" at "https://oss.sonatype.org/content/repositories/snapshots/"

libraryDependencies ++= Seq(
  "com.github.jeroenr" %% "k8s-svc-discovery" % "0.7-SNAPSHOT"
)

Usage

You can simply initiate the ServiceDiscoveryAgent actor and pass an instance of KubernetesServiceDiscoveryClient along with your callback function of signature (List[T <: ServiceUpdate]) => Any

import com.github.jeroenr.service.discovery._
import com.github.jeroenr.service.discovery.health._

implicit val system = ActorSystem()

// some callback function to do something useful with the list of service updates
def handleServiceUpdates[T <: ServiceUpdate](allServiceUpdates: List[T]) = {
  println(s"Service updates: $allServiceUpdates")
}

val serviceDiscoveryAgent =
    system.actorOf(Props(new ServiceDiscoveryAgent[KubernetesServiceUpdate](new KubernetesServiceDiscoveryClient, handleServiceUpdates)))

  // start watching services
  serviceDiscoveryAgent ! ServiceDiscoveryAgent.WatchServices

Example usage in a real project: https://github.com/jeroenr/api-gateway#automatic-service-discovery

Configuration

When using this library you need to configure the Kubernetes API endpoint.

service-discovery {
  kubernetes {
    host = "localhost"
    host = ${?K8S_API_HOST}
    port = 8001 // default kube-proxy port
    port = ${?K8S_API_PORT}
    token = ""
    token = ${?K8S_API_TOKEN}  // you need a valid API token to access the Kubernetes API 
    # namespaces that are filtered down to in the client
    namespaces = ["default"] // list of namespaces to monitor
  }

  polling.interval = 2 seconds
}

Most important is to set the Kubernetes API token. Conveniently you can easily do all this through environment variables in your Kubernetes deployment descriptor.

Authenticating K8s API calls

You need a valid API token to access the Kubernetes API. There's many different options for this. My favourite is through service accounts. The steps below will create a service account and associated secret

$ kubectl create serviceaccount my-service-account
serviceaccount "my-service-account" created

Great, now a new service account has been created and under the hood also an associated secret which we can retrieve by:

$ kubectl get serviceaccounts my-service-account -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  # ...
secrets:
- name: my-service-account-token-1yvwg

As you can see in our example the generated secret is called "my-service-account-token-1yvwg". You can use this secret to set the value of the K8S_API_TOKEN environment variable. Example K8s deployment descriptor:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: my-deployment
spec:
  template:
    spec:
      containers:
      - name: my-container
        image: my-container-image
        env:
        - name: K8S_API_TOKEN
          valueFrom:
            secretKeyRef:
              name: my-serviceaccount-token-secret
              key: token
        - name: K8S_API_HOST
          value: "kubernetes.default.svc.cluster.local"
        - name: K8S_API_PORT
          value: "443"
        args: [
          "-Djava.security.egd=file:/dev/./urandom",
          "-Dintegration.kubernetes.namespaces.0=my-env",
        ]