Эврика и Кубернетес

Я собираю доказательство концепции, чтобы помочь выявить ошибки с использованием Spring Boot / Netflix OSS и Kubernetes вместе. Это также доказывает наличие связанных технологий, таких как Prometheus и Graphana.

У меня есть настройка службы Eureka, которая без проблем запускается в моем кластере Kubernetes. Это называется обнаружением и при добавлении в K8 с использованием

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

и я начинаю это использовать

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

Эта служба завершает работу с именем configserver-3481062421-tmv4d. Затем я вижу исключения в журналах сервера конфигурации, поскольку он пытается найти экземпляр eureka и не может.

У меня такая же настройка для этого, используя docker-compose локально со ссылками, и он без проблем запускает различные контейнеры.

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

Как я могу настроить что-то вроде eureka.client.serviceUri, чтобы мои микросервисы могли определять местонахождение своих сверстников, не зная фиксированных IP-адресов в кластере K8?


person Andrew Rutter    schedule 12.11.2016    source источник
comment
Eureka использует имя службы, чтобы найти экземпляр. Если вы проверите сервер eureka, вы увидите список служб, зарегистрированных на сервере eureka. Когда служба A пытается связаться со службой B, служба A извлекает всю информацию, относящуюся к службе B, с сервера eureka, используя имя службы B. Таким образом, в настройке eureka не будет фиксированного IP-адреса.   -  person Keaz    schedule 10.08.2018
comment
Я не совсем понял, что вы пытаетесь сделать, но зачем вам eurika, когда вы развертываете на кубернатах, разве кубернаты не выполняют работу eurika?   -  person Adelin    schedule 23.07.2019
comment
@ Аделин, да, именно так. В Kubernetes уже есть сервисы, указывающие на поды. Я не смог найти никаких ресурсов, объясняющих обнаружение сервисов и Kubernetes вместе.   -  person reoxey    schedule 17.01.2021


Ответы (5)


Как я могу настроить что-то вроде eureka.client.serviceUri?

У вас должен быть сервис Kubernetes поверх модулей / развертываний eureka, который затем будет предоставить вам рекомендуемый IP-адрес и номер порта. А затем используйте этот референтный адрес для поиска службы Eureka вместо «8761».

Чтобы ответить на дальнейший вопрос о конфигурации высокой доступности Eureka

У вас не должно быть более одного модуля / реплики Eureka для каждой службы k8s (помните, что модули недолговечны, вам нужен референтный IP-адрес / доменное имя для реестра службы Eureka). Чтобы достичь высокой доступности (HA), разверните больше сервисов k8s с одним модулем в каждом.

  • Eureka Service 1 -> одиночный контейнер
  • Eureka Service 2 -> еще один одиночный контейнер
  • ..
  • ..
  • Eureka Service n -> еще одна капсула

Итак, теперь у вас есть референтный IP-адрес / доменное имя (IP-адрес службы k8s) для каждого из ваших Eureka .. теперь они могут регистрировать друг друга.

Чувствуете, что это перебор? Если все ваши службы находятся в одном пространстве имен kubernetes, вы можете достичь всего (ну, почти всего, кроме балансировки нагрузки на стороне клиента), что предлагает eureka, используя службу k8s + надстройку KubeDNS. Прочтите эту статью Кристиана Поста

Редактировать

Вместо служб с одним модулем для каждой вы можете использовать StatefulSets как указал Стефан Оке.

Как и развертывание, StatefulSet управляет модулями, основанными на идентичной спецификации контейнера. В отличие от развертывания, StatefulSet поддерживает постоянную идентификацию для каждого из своих модулей. Эти модули созданы на основе одной и той же спецификации, но не являются взаимозаменяемыми: у каждого есть постоянный идентификатор, который он поддерживает при любом изменении расписания.

person so-random-dude    schedule 12.11.2016

Что касается конфигурации высокой доступности Eureka в Kubernetes: вы можете (пока) использовать StatefulSet вместо создания службы для каждого экземпляра. StatefulSet гарантирует стабильную сетевую идентификацию для каждого создаваемого вами экземпляра. Например, развертывание может выглядеть следующим образом yaml (StatefulSet + headless Service). В соответствии с правилами именования DNS для StatefulSets (при условии, что пространство имен "по умолчанию"):

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

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

Пока ваши поды находятся в одном пространстве имен, они могут достигать Eureka также как:

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

Примечание. Образ докера, используемый в примере, взят из https://github.com/stefanocke/eureka. Вы можете выбрать или построить свой собственный.

---
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"
person Stefan Ocke    schedule 25.11.2017
comment
Это сработает? -Deureka.client.serviceUrl.defaultZone=http://eureka-0.eureka.${CURRENT_NAME_SPACE}.svc.cluster.local:8761/eureka/,http://eureka-1.eureka.${CURRENT_NAME_SPACE}.svc.cluster.local:8761/eureka/ Доступны ли какие-либо переменные по умолчанию для получения текущего пространства имен? - person Govind Kailas; 08.08.2018
comment
Хороший вопрос. Я думаю, что лучше всего было бы опустить пространство имен: -Deureka.client.serviceUrl.defaultZone=http://eureka-0.eureka:8761/eureka/,http://eureka-1.eureka:8761/eureka/. Однако я помню, что у меня это не сработало. Но причину я особо не искал. Может, ты попробуешь. - person Stefan Ocke; 09.08.2018
comment
@GovindKailas, обновил и протестировал пример. Теперь я использую короткие версии имен хостов. Уловка состоит не только в том, чтобы изменить defaultZone, но и изменить EUREKA_INSTANCE_HOSTNAME соответственно, чтобы они соответствовали значениям в зоне по умолчанию. В противном случае Eureka сообщит о недоступных репликах. Обратите внимание, что я также изменил образ докера, так как тот, который я использовал раньше, больше не существует и тоже сильно устарел. - person Stefan Ocke; 10.08.2018
comment
Это очень хорошее улучшение и тоже изящно. Я просто попробовал это, и единственная проблема, о которой я мог подумать, - это то, что люди могут запутаться в URL-адресе службы Eureka. Спасибо за помощь. - person Govind Kailas; 11.08.2018
comment
Спасибо за это решение. У меня вопрос: как я могу открыть этот набор состояний, чтобы проверить, правильно ли зарегистрированы эти модули? - person inix; 10.01.2019
comment
Вы можете создать второй сервис с clusterIp, который также указывает на ваши модули eureka. Затем эта служба может быть предоставлена ​​с помощью балансировщика нагрузки, входящего трафика или других средств. - person Stefan Ocke; 11.01.2019
comment
@StefanOcke, не могли бы вы помочь мне с моей текущей настройкой, упомянутой ниже? - person rajesh023; 27.09.2019
comment
Как добавить запись в JAVA_OPTIONS и -Deureka.client.serviceUrl.defaultZone выше, когда HPA добавляет еще один экземпляр эврики? Всегда ли это должно быть вручную? Возможно ли автоматическое добавление записи в список зон по умолчанию с помощью HPA - person SRK; 24.11.2020
comment
@SRK, я не знаю, как это сделать. Но если вам даже нужно автоматически масштабировать обнаружение служб, вы, вероятно, достигли точки, чтобы наконец избавиться от Eureka и вместо этого использовать службы Kubernetes и DNS. Я всегда рассматривал Eureka в Kubernetes как приемлемый подход при миграции приложений Spring Cloud, но не как постоянное решение. - person Stefan Ocke; 13.12.2020

@Stefan Ocke, я пытаюсь настроить то же самое, но с моим собственным изображением сервера eureka. но я продолжаю получать эту ошибку

Request execution failed with message: java.net.ConnectException: Connection refused (Connection refused)
2019-09-27 06:27:03.363 ERROR 1 --- [           main] c.n.d.s.t.d.RedirectingEurekaHttpClient  : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://eureka-1.eureka:8761/eureka/}

Вот конфигурации:

Свойства Eureka Spring:

server.port=${EUREKA_PORT}
spring.security.user.name=${EUREKA_USERNAME}
spring.security.user.password=${EUREKA_PASSWORD}
eureka.client.register-with-eureka=true
eureka.client.fetch-registry=true
eureka.instance.prefer-ip-address=false
eureka.server.wait-time-in-ms-when-sync-empty=0
eureka.server.eviction-interval-timer-in-ms=15000
eureka.instance.leaseRenewalIntervalInSeconds=30
eureka.instance.leaseExpirationDurationInSeconds=30
eureka.instance.hostname=${EUREKA_INSTANCE_HOSTNAME}
eureka.client.serviceUrl.defaultZone=http://eureka-0.eureka:8761/eureka/,http://eureka-1.eureka:8761/eureka/

Конфигурация StatefulSet:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka
spec:
  serviceName: "eureka"
  podManagementPolicy: "Parallel" 
  replicas: 2
  selector:
    matchLabels:
      app: eureka
  template:
    metadata:
      labels:
        app: eureka    
    spec:
      containers:
      - name: eureka
        image: "my-image"
        command: ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar","/app/eureka-service.jar"]
        ports:
        - containerPort: 8761
        env: 
        - name: EUREKA_PORT
          value: "8761"
        - name: EUREKA_USERNAME
          value: "theusername"
        - name: EUREKA_PASSWORD
          value: "thepassword"
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: EUREKA_INSTANCE_HOSTNAME
          value: ${MY_POD_NAME}.eureka   

Конфигурация службы:

apiVersion: v1
kind: Service
metadata:
  name: eureka
  labels:
    app: eureka
spec:
  clusterIP: None
  selector:
    app: eureka
  ports:
  - port: 8761
    targetPort: 8761

Контроллер входящего трафика:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-service
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /
            backend:
              serviceName: eureka
              servicePort: 8761
person rajesh023    schedule 27.09.2019
comment
сам разобрался, я использовал аутентификацию на сервере eureka и забыл передать учетные данные при регистрации на нем. - person rajesh023; 27.09.2019

Вы должны установить сервер kubernetes kube-dns, чтобы разрешать имена с их IP-адресами, а затем предоставлять свои модули eureka как услугу. (см. документы kubernetes) для получения дополнительной информации о том, как создавать DNS и службы. @random_dude, что будет, если я использовал для создания 2 или 3 реплик эврики? Оказалось, что когда я монтирую микросервис 'X', я буду зарегистрирован во всех репликах eureka, но когда он выйдет из строя, только одна реплика получит обновление! другие по-прежнему считают экземпляр микросервиса работающим

person mootez    schedule 01.12.2016
comment
Я знаю, что немного опоздал, чтобы ответить на этот вопрос, я пропустил уведомление. У вас не должно быть более одного модуля / реплики Eureka на одну службу k8s (помните, что модули эфемерны, вам нужен референтный IP-адрес / доменное имя для службы Eureka. Registry) .. Для достижения высокой доступности (HA) разверните больше сервисов k8s с одним модулем в каждом. - person so-random-dude; 22.02.2017

У меня возникла именно эта проблема, и она была решена путем добавления переменной среды для pod. Здесь есть ответ. Пример переменной env для моего модуля показан ниже.

введите описание изображения здесь

person Kiran Joshi    schedule 08.03.2021
comment
Спасибо, в следующий раз добавьте env как код (чтобы его можно было скопировать / вставить) - person akub; 01.07.2021