Spring Cloud Kubernetes Discovery Server

The Spring Cloud Kubernetes Discovery Server provides HTTP endpoints apps can use to gather information about services available within a Kubernetes cluster. The Spring Cloud Kubernetes Discovery Server can be used by apps using the spring-cloud-starter-kubernetes-discoveryclient to provide data to the DiscoveryClient implementation provided by that starter.

Permissions

The Spring Cloud Discovery server uses the Kubernetes API server to get data about Pod, Service and Endpoint resources, so it needs list, watch, and get permissions to use those endpoints. See the below sample Kubernetes deployment YAML for an example of how to configure the Service Account on Kubernetes.

Endpoints

There are three endpoints exposed by the server.

/apps

A GET request sent to /apps will return a JSON array of available services. Each item contains the name of the Kubernetes service and service instance information. Below is a sample response.

[
   {
      "name":"spring-cloud-kubernetes-discoveryserver",
      "serviceInstances":[
         {
            "instanceId":"836a2f25-daee-4af2-a1be-aab9ce2b938f",
            "serviceId":"spring-cloud-kubernetes-discoveryserver",
            "host":"10.244.1.6",
            "port":8761,
            "uri":"http://10.244.1.6:8761",
            "secure":false,
            "metadata":{
               "app":"spring-cloud-kubernetes-discoveryserver",
               "kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"annotations\":{},\"labels\":{\"app\":\"spring-cloud-kubernetes-discoveryserver\"},\"name\":\"spring-cloud-kubernetes-discoveryserver\",\"namespace\":\"default\"},\"spec\":{\"ports\":[{\"name\":\"http\",\"port\":80,\"targetPort\":8761}],\"selector\":{\"app\":\"spring-cloud-kubernetes-discoveryserver\"},\"type\":\"ClusterIP\"}}\n",
               "http":"8761"
            },
            "namespace":"default",
            "scheme":"http"
         }
      ]
   },
   {
      "name":"kubernetes",
      "serviceInstances":[
         {
            "instanceId":"1234",
            "serviceId":"kubernetes",
            "host":"172.18.0.3",
            "port":6443,
            "uri":"http://172.18.0.3:6443",
            "secure":false,
            "metadata":{
               "provider":"kubernetes",
               "component":"apiserver",
               "https":"6443"
            },
            "namespace":"default",
            "scheme":"http"
         }
      ]
   }
]

/apps/{name}

A GET request to /apps/{name} can be used to get instance data for all instances of a given service. Below is a sample response when a GET request is made to /apps/kubernetes.

[
     {
        "instanceId":"1234",
        "serviceId":"kubernetes",
        "host":"172.18.0.3",
        "port":6443,
        "uri":"http://172.18.0.3:6443",
        "secure":false,
        "metadata":{
           "provider":"kubernetes",
           "component":"apiserver",
           "https":"6443"
        },
        "namespace":"default",
        "scheme":"http"
     }
]

/app/{name}/{instanceid}

A GET request made to /app/{name}/{instanceid} will return the instance data for a specific instance of a given service. Below is a sample response when a GET request is made to /app/kubernetes/1234.

 {
    "instanceId":"1234",
    "serviceId":"kubernetes",
    "host":"172.18.0.3",
    "port":6443,
    "uri":"http://172.18.0.3:6443",
    "secure":false,
    "metadata":{
       "provider":"kubernetes",
       "component":"apiserver",
       "https":"6443"
    },
    "namespace":"default",
    "scheme":"http"
 }

Deployment YAML

An image of the Spring Cloud Discovery Server is hosted on Docker Hub. However, if you need to customize the discovery server behavior or prefer to build the image yourself you can easily build your own image from the source code on GitHub and use that.

Below is a sample deployment YAML you can use to deploy the Kubernetes Discovery Server to Kubernetes.

---
apiVersion: v1
kind: List
items:
  - apiVersion: v1
    kind: Service
    metadata:
      labels:
        app: spring-cloud-kubernetes-discoveryserver
      name: spring-cloud-kubernetes-discoveryserver
    spec:
      ports:
        - name: http
          port: 80
          targetPort: 8761
      selector:
        app: spring-cloud-kubernetes-discoveryserver
      type: ClusterIP
  - apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app: spring-cloud-kubernetes-discoveryserver
      name: spring-cloud-kubernetes-discoveryserver
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      labels:
        app: spring-cloud-kubernetes-discoveryserver
      name: spring-cloud-kubernetes-discoveryserver:view
    roleRef:
      kind: Role
      apiGroup: rbac.authorization.k8s.io
      name: namespace-reader
    subjects:
      - kind: ServiceAccount
        name: spring-cloud-kubernetes-discoveryserver
  - apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      namespace: default
      name: namespace-reader
    rules:
      - apiGroups: ["", "extensions", "apps"]
        resources: ["pods", "services", "endpoints"]
        verbs: ["get", "list", "watch"]
  - apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: spring-cloud-kubernetes-discoveryserver-deployment
    spec:
      selector:
        matchLabels:
          app: spring-cloud-kubernetes-discoveryserver
      template:
        metadata:
          labels:
            app: spring-cloud-kubernetes-discoveryserver
        spec:
          serviceAccountName: spring-cloud-kubernetes-discoveryserver
          containers:
          - name: spring-cloud-kubernetes-discoveryserver
            image: springcloud/spring-cloud-kubernetes-discoveryserver:3.1.0
            imagePullPolicy: IfNotPresent
            readinessProbe:
              httpGet:
                port: 8761
                path: /actuator/health/readiness
            livenessProbe:
              httpGet:
                port: 8761
                path: /actuator/health/liveness
            ports:
            - containerPort: 8761