Eureka and Kubernetes

Andrew Rutter picture Andrew Rutter · Nov 12, 2016 · Viewed 29k times · Source

I am putting together a proof of concept to help identify gotchas using Spring Boot/Netflix OSS and Kubernetes together. This is also to proove out related technologies such as Prometheus and Graphana.

I have a Eureka service setup which is starting with no trouble within my Kubernetes clouster. This is named discovery and has been given the name "discovery-1551420162-iyz2c" when added to K8 using

kubectl run discovery --image=xyz/discovery-microservice --replicas=1 --port=8761

For my config server, I am trying to use Eureka based on a logical URL so in my bootstrap.yml I have

server:
  port: 8889

eureka:
  instance:
    hostname: configserver
  client:
    registerWithEureka: true
    fetchRegistry: true
    serviceUrl:
      defaultZone: http://discovery:8761/eureka/

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/xyz/microservice-config

and I am starting this using

kubectl run configserver --image=xyz/config-microservice --replicas=1 --port=8889

This service ends up running named as configserver-3481062421-tmv4d. I then see exceptions in the config server logs as it tries to locate the eureka instance and cannot.

I have the same setup for this using docker-compose locally with links and it starts the various containers with no trouble.

discovery:
  image: xyz/discovery-microservice
  ports:
   - "8761:8761"
configserver:
  image: xyz/config-microservice
  ports:
   - "8888:8888"
  links:
   - discovery

How can should I setup something like eureka.client.serviceUri so my microserices can locate their peers without knowing fixed IP addresses within the K8 cluster?

Answer

so-random-dude picture so-random-dude · Nov 12, 2016

How can I setup something like eureka.client.serviceUri?

You have to have a Kubernetes service on top of the eureka pods/deployments which then will provide you a referable IP address and port number. And then use that referable address to look up the Eureka service, instead of "8761".

To address further question about HA configuration of Eureka

You shouldn't have more than one pod/replica of Eureka per k8s service (remember, pods are ephemeral, you need a referable IP address/domain name for eureka service registry). To achieve high availability (HA), spin up more k8s services with one pod in each.

  • Eureka service 1 --> a single pod
  • Eureka Service 2 --> another single pod
  • ..
  • ..
  • Eureka Service n --> another single pod

So, now you have referable IP/Domain name (IP of the k8s service) for each of your Eureka.. now it can register each other.

Feeling like it's an overkill? If all your services are in same kubernetes namespace you can achieve everything (well, almost everything, except client side load balancing) that eureka offers though k8s service + KubeDNS add-On. Read this article by Christian Posta

Edit

Instead of Services with one pod each, you can make use of StatefulSets as Stefan Ocke pointed out.

Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec. Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods. These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.