Eureka 和 Kubernetes

问题描述 投票:0回答:6

我正在整理一个概念证明,以帮助识别同时使用 Spring Boot/Netflix OSS 和 Kubernetes 的问题。这也是为了证明Prometheus、Grafana等相关技术。

我有一个 Eureka 服务设置,在我的 Kubernetes 集群中启动时没有任何问题。这被命名为 discovery,并在使用

添加到 K8 时被命名为“discovery-1551420162-iyz2c”
kubectl run discovery --image=xyz/discovery-microservice --replicas=1 --port=8761

对于我的配置服务器,我尝试基于逻辑 URL 使用 Eureka,因此在我的 bootstrap.yml 中我有

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 的名称运行。然后,我在配置服务器日志中看到异常,因为它尝试找到尤里卡实例但无法找到。

我在本地使用 docker-compose 和链接进行了相同的设置,它可以毫无问题地启动各种容器。

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

如何设置像 eureka.client.serviceUri 这样的东西,以便我的微服务可以在不知道 K8 集群内固定 IP 地址的情况下找到其对等点?

spring-boot kubernetes microservices netflix-eureka spring-cloud-netflix
6个回答
29
投票

我如何设置类似 eureka.client.serviceUri 的东西?

您必须在 eureka pod/部署之上有一个 Kubernetes 服务,然后它将为您提供可参考的 IP 地址和端口号。然后使用该可引用地址来查找 Eureka 服务,而不是“8761”。

解决有关 Eureka HA 配置的进一步问题

每个 k8s 服务不应该有超过一个 Eureka 的 pod/副本(记住,pod 是短暂的,您需要一个用于 eureka 服务注册表的可引用 IP 地址/域名)。为了实现高可用性 (HA),请启动更多 k8s 服务,每个服务包含一个 pod。

  • Eureka 服务 1 --> 单个 pod
  • Eureka Service 2 --> 另一个 pod
  • ..
  • ..
  • Eureka 服务 n --> 另一个 pod

所以,现在你的每个 Eureka 都有了可引用的 IP/域名(k8s 服务的 IP)..现在它可以互相注册了。

感觉这太过分了? 如果您的所有服务都在同一个 kubernetes 命名空间中,您可以通过 k8s 服务 + KubeDNS 附加组件实现 eureka 提供的所有功能(嗯,几乎所有功能,除了客户端负载平衡)。阅读 Christian Posta 的这篇文章

编辑

您可以使用 StatefulSets,而不是每个服务都有一个 pod,正如 Stefan Ocke 指出的那样。

与 Deployment 类似,StatefulSet 管理基于 相同的集装箱规格与 Deployment 不同,StatefulSet 维护 每个 Pod 都有一个固定的身份。这些 Pod 是从创建的 相同的规格,但不可互换:每个都有一个持久的 它在任何重新安排中维护的标识符。


19
投票

关于Kubernetes中Eureka的HA配置: 您可以(同时)使用 StatefulSet 来实现此目的,而不是为每个实例创建一个服务。 StatefulSet 保证您创建的每个实例的稳定网络身份。 例如,部署可能类似于以下 yaml(StatefulSet + headless Service)。 根据 DNS,这里有两个 Eureka 实例 StatefulSet 的命名规则(假设命名空间为“默认”):

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

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

只要您的 Pod 位于同一命名空间中,它们也可以通过以下方式到达 Eureka:

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

注意:示例中使用的 docker 镜像来自 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"

3
投票

@Stefan Ocke 我正在尝试相同的设置,但使用我自己的尤里卡服务器图像。但我不断收到此错误

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/}

以下是配置:

尤里卡弹簧属性:

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

2
投票

您必须安装 kubernetes kube-dns 服务器来解析名称及其 IP,然后将您的 eureka pod 作为服务公开。 (请参阅 kubernetes docs)了解有关如何创建 dns 和服务的更多信息。 @random_dude,如果我曾经创建 2 个或 3 个尤里卡副本,会出现什么情况?事实证明,当我安装微服务“X”时,我将在所有尤里卡副本中注册,但是当它关闭时,只有一个副本获得更新!其他人仍然认为微服务实例正在运行


1
投票

我正是遇到了这个问题,通过为 pod 添加环境变量解决了这个问题。 有答案。我的 Pod 的示例环境变量如下所示,


0
投票

我想知道你将该配置放在哪里,是在尤里卡上的服务注册表上,还是在客户端(我们要连接到尤里卡的地方)?

我当前的情况是,所有配置都放在存储库上,尤里卡配置也是如此。这使得配置静态。

© www.soinside.com 2019 - 2024. All rights reserved.