繁体   English   中英

尤里卡和 Kubernetes

[英]Eureka and Kubernetes

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

我有一个 Eureka 服务设置,它在我的 Kubernetes 集群中没有问题。 这被命名为发现,并在使用添加到 K8 时被命名为“discovery-1551420162-iyz2c”

对于我的配置服务器,我正在尝试基于逻辑 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。 然后我在配置服务器日志中看到异常,因为它试图找到 eureka 实例并且无法定位。

我在本地使用带有链接的 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 地址的情况下定位它们的对等点?

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

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

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

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

  • Eureka service 1 --> 单个 pod
  • Eureka Service 2 --> 另一个单一的 pod
  • ..
  • ..
  • Eureka Service n --> 另一个单个 pod

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

感觉是不是有点矫枉过正了? 如果您的所有服务都在同一个 kubernetes 命名空间中,您可以通过 k8s 服务 + KubeDNS 附加组件实现 eureka 提供的所有内容(嗯,几乎所有内容,客户端负载均衡除外)。 阅读克里斯蒂安·波斯塔的这篇文章

编辑

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

与 Deployment 类似,StatefulSet 管理基于相同容器规范的 Pod。 与 Deployment 不同,StatefulSet 为其每个 Pod 维护一个粘性标识。 这些 pod 是根据相同的规范创建的,但不可互换:每个 pod 都有一个持久标识符,它在任何重新调度时都会维护该标识符。

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

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

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

只要您的 pod 在同一个命名空间中,它们也可以通过以下方式访问 Eureka:

  • 尤里卡-0.尤里卡
  • 尤里卡-1.尤里卡

注意:示例中使用的 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"

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

状态集配置:

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

您必须安装一个 kubernetes kube-dns 服务器来使用其 IP 解析名称,然后将您的 eureka pod 作为服务公开。 (请参阅 kubernetes文档)以获取有关如何创建 dns 和服务的更多信息。 @random_dude,如果我曾经创建 2 或 3 个 eureka 副本会怎样? 事实证明,当我挂载一个微服务“X”时,我将在所有 eureka 副本中注册,但是当它关​​闭时,只有一个副本得到更新! 其他人仍然认为微服务实例正在运行

我确实遇到了这个问题,并通过为 pod 添加环境变量来解决它。 有答案。 我的 pod 的示例环境变量如下所示,

在此处输入图像描述

我想知道你把那个配置放在哪里,是在 eureka 上的 service-registry 上,还是在客户端(我们想要连接到 eureka 的地方)?

我目前的情况是,所有配置都放在一个 repo 上,eureka 配置也是如此。 这使得配置静态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM