Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Eureka and Kubernetes

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

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

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 I setup something like eureka.client.serviceUri so my microservices can locate their peers without knowing fixed IP addresses within the K8 cluster?

like image 308
Andrew Rutter Avatar asked Nov 12 '16 20:11

Andrew Rutter


People also ask

Can we use Eureka with Kubernetes?

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".

Do we need Eureka server in Kubernetes?

The eureka server application must be deployed in a very stable network environment, and kubernetes statefulset helps us in ensuring stable network, in your kubernetes file, have a section for the service, and another for the statefulset.

Do I need service discovery in Kubernetes?

An abstract way to expose an application running on a set of Pods as a network service. With Kubernetes you don't need to modify your application to use an unfamiliar service discovery mechanism. Kubernetes gives Pods their own IP addresses and a single DNS name for a set of Pods, and can load-balance across them.

Can we use spring cloud with Kubernetes?

Spring Cloud Kubernetes is a Kubernetes API server integration that allows for service discovery, configuration, and load balancing used by Spring Cloud; it provides Spring Cloud implementations of common interfaces that consume Kubernetes.


2 Answers

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.

like image 81
so-random-dude Avatar answered Sep 29 '22 05:09

so-random-dude


Regarding HA configuration of Eureka in Kubernetes: You can (meanwhile) use a StatefulSet for this instead of creating a service for each instance. The StatefulSet guarantees stable network identity for each instance you create. For example, the deployment could look like the following yaml (StatefulSet + headless Service). There are two Eureka instances here, according to the DNS naming rules for StatefulSets (assuming namespace is "default"):

  • eureka-0.eureka.default.svc.cluster.local and

  • eureka-1.eureka.default.svc.cluster.local

As long as your pods are in the same namespace, they can reach Eureka also as:

  • eureka-0.eureka
  • eureka-1.eureka

Note: The docker image used in the example is from https://github.com/stefanocke/eureka. You might want to chose or build your own one.

--- apiVersion: v1 kind: Service metadata:   name: eureka   labels:     app: eureka spec:   ports:   - port: 8761     name: eureka   clusterIP: None   selector:     app: eureka ---     apiVersion: apps/v1beta2 kind: StatefulSet metadata:   name: eureka spec:   serviceName: "eureka"   replicas: 2    selector:     matchLabels:       app: eureka   template:     metadata:       labels:         app: eureka     spec:       containers:       - name: eureka         image: stoc/eureka         ports:         - containerPort: 8761         env:         - name: MY_POD_NAME           valueFrom:             fieldRef:               fieldPath: metadata.name           # Due to camelcase issues with "defaultZone" and "preferIpAddress", _JAVA_OPTIONS is used here         - name: _JAVA_OPTIONS           value: -Deureka.instance.preferIpAddress=false -Deureka.client.serviceUrl.defaultZone=http://eureka-0.eureka:8761/eureka/,http://eureka-1.eureka:8761/eureka/         - name: EUREKA_CLIENT_REGISTERWITHEUREKA           value: "true"         - name: EUREKA_CLIENT_FETCHREGISTRY           value: "true"         # The hostnames must match with the the eureka serviceUrls, otherwise the replicas are reported as unavailable in the eureka dashboard               - name: EUREKA_INSTANCE_HOSTNAME           value: ${MY_POD_NAME}.eureka   # No need to start the pods in order. We just need the stable network identity podManagementPolicy: "Parallel" 
like image 23
Stefan Ocke Avatar answered Sep 29 '22 05:09

Stefan Ocke