Asteris

Service Discovery Outside Kubernetes

// Brian Hicks // Kubernetes

You’ve started your Kubernetes cluster, and you’re all ready to move apps inside. Only one question remains: what happens when services are not hosted in Kubernetes? How can you reference these services?

Kubernetes lets us solve this with Service objects. We’ll just need to create one with no selector. When set under normal conditions, the selector is continuously evaluated to create an Endpoints object. That object is then used by the service to route traffic. But with no selector, Kubernetes won’t ever create that object. This leaves us an opening: we can create our own Endpoints object, give it the same name, and the service will be happy to use that instead.

Let’s create the service first. For our purposes, we’ll register a PostgreSQL server running at 10.0.0.100:5432. Our service definition will look like this:

---
apiVersion: v1
kind: Service
metadata:
  name: postgres
  namespace: default
spec:
  ports:
    - port: 5432

Save that as svc.yaml and submit it to your cluster with kubectl create -f svc.yaml. Now if you look in kubectl describe service postgres, you can see that the service exists but doesn’t have any endpoints:

$ kubectl describe service postgres
Name:                   postgres
Namespace:              default
Labels:                 <none>
Selector:               <none>
Type:                   ClusterIP
IP:                     10.19.244.244
Port:                   <unnamed>       5432/TCP
Endpoints:              <none>
Session Affinity:       None

This is just what we want at this point, so let’s go ahead and create our endpoint:

---
apiVersion: v1
kind: Endpoints
metadata:
  name: postgres # Note that this *must* be the same as the service name, or this won't work!
  namespace: default
subsets:
  - addresses:
      - ip: 10.0.0.100
    ports:
      - port: 5432

After creating that with kubectl create -f ep.yml we can see the endpoint in the service description:

$ kubectl describe service postgres
Name:                   postgres
Namespace:              default
Labels:                 <none>
Selector:               <none>
Type:                   ClusterIP
IP:                     10.19.244.244
Port:                   <unnamed>       5432/TCP
Endpoints:              10.0.0.100:5432
Session Affinity:       None
No events.

To use this service, connect to 10.19.244.244 (the virtual IP Kubernetes assigned us.) That will proxy traffic to 10.0.0.100:5432. If you have cluster DNS set up you can resolve using the name of the service.

Service Discovered!

So to recap: we’ve created a Kubernetes service along with the associated Endpoints object that will enable service discovery for services hosted outside your cluster. The next time you need to discover something outside of what Kubernetes’ usually provides you’ll know where to go.

Want More Sleep?

Is your deployment keeping you up a night? Is it secure? Reliable? We'll help you keep the lights on with timely tutorials and tips to give you peace of mind that your cluster is running how it's supposed to.