简体   繁体   English

尤里卡和 Kubernetes

[英]Eureka and Kubernetes

I am putting together a proof of concept to help identify gotchas using Spring Boot/Netflix OSS and Kubernetes together.我正在整理一个概念证明,以帮助识别同时使用 Spring Boot/Netflix OSS 和 Kubernetes 的问题。 This is also to prove out related technologies such as Prometheus and Graphana.这也是为了证明 Prometheus 和 Graphana 等相关技术。

I have a Eureka service setup which is starting with no trouble within my Kubernetes cluster.我有一个 Eureka 服务设置,它在我的 Kubernetes 集群中没有问题。 This is named discovery and has been given the name "discovery-1551420162-iyz2c" when added to K8 using这被命名为发现,并在使用添加到 K8 时被命名为“discovery-1551420162-iyz2c”

For my config server, I am trying to use Eureka based on a logical URL so in my bootstrap.yml I have对于我的配置服务器,我正在尝试基于逻辑 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

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.该服务最终运行命名为 configserver-3481062421-tmv4d。 I then see exceptions in the config server logs as it tries to locate the eureka instance and cannot.然后我在配置服务器日志中看到异常,因为它试图找到 eureka 实例并且无法定位。

I have the same setup for this using docker-compose locally with links and it starts the various containers with no trouble.我在本地使用带有链接的 docker-compose 对此进行了相同的设置,它可以毫无问题地启动各种容器。

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?我如何设置像 eureka.client.serviceUri 这样的东西,这样我的微服务就可以在不知道 K8 集群中的固定 IP 地址的情况下定位它们的对等点?

How can I setup something like eureka.client.serviceUri?如何设置 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.你必须在 eureka pods/deployments 之上有一个 Kubernetes服务,然后它会为你提供一个可参考的 IP 地址和端口号。 And then use that referable address to look up the Eureka service, instead of "8761".然后使用该可引用地址来查找 Eureka 服务,而不是“8761”。

To address further question about HA configuration of Eureka解决有关 Eureka 的 HA 配置的进一步问题

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).每个 k8s 服务不应该有超过一个 Eureka 的 Pod/副本(请记住,Pod 是短暂的,你需要一个可引用的 IP 地址/域名用于 eureka 服务注册表)。 To achieve high availability (HA), spin up more k8s services with one pod in each.要实现高可用性 (HA),请启动更多 k8s 服务,每个服务都有一个 pod。

  • Eureka service 1 --> a single pod Eureka service 1 --> 单个 pod
  • Eureka Service 2 --> another single pod Eureka Service 2 --> 另一个单一的 pod
  • .. ..
  • .. ..
  • Eureka Service n --> another single pod Eureka Service n --> 另一个单个 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.所以,现在你的每个 Eureka 都有可参考的 IP/域名(k8s 服务的 IP)。现在它可以相互注册了。

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.如果您的所有服务都在同一个 kubernetes 命名空间中,您可以通过 k8s 服务 + KubeDNS 附加组件实现 eureka 提供的所有内容(嗯,几乎所有内容,客户端负载均衡除外)。 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.正如Stefan Ocke指出的那样,您可以使用StatefulSet ,而不是每个服务都有一个 pod。

Like a Deployment, a StatefulSet manages Pods that are based on an identical container spec.与 Deployment 类似,StatefulSet 管理基于相同容器规范的 Pod。 Unlike a Deployment, a StatefulSet maintains a sticky identity for each of their Pods.与 Deployment 不同,StatefulSet 为其每个 Pod 维护一个粘性标识。 These pods are created from the same spec, but are not interchangeable: each has a persistent identifier that it maintains across any rescheduling.这些 pod 是根据相同的规范创建的,但不可互换:每个 pod 都有一个持久标识符,它在任何重新调度时都会维护该标识符。

Regarding HA configuration of Eureka in Kubernetes: You can (meanwhile) use a StatefulSet for this instead of creating a service for each instance.关于 Kubernetes中 Eureka 的 HA 配置:您可以(同时)为此使用StatefulSet ,而不是为每个实例创建服务。 The StatefulSet guarantees stable network identity for each instance you create. StatefulSet 为您创建的每个实例保证稳定的网络身份。 For example, the deployment could look like the following yaml (StatefulSet + headless Service).例如,部署可能类似于以下 yaml(StatefulSet + headless Service)。 There are two Eureka instances here, according to the DNS naming rules for StatefulSets (assuming namespace is "default"):这里有两个 Eureka 实例,根据 StatefulSets 的DNS 命名规则(假设命名空间是“默认”):

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

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

As long as your pods are in the same namespace, they can reach Eureka also as:只要您的 pod 在同一个命名空间中,它们也可以通过以下方式访问 Eureka:

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

Note: The docker image used in the example is from https://github.com/stefanocke/eureka .注意:示例中使用的 docker 镜像来自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"

@Stefan Ocke i'm trying to the same setup the same, but with my own image of eureka server. @Stefan Ocke 我正在尝试相同的设置,但使用我自己的尤里卡服务器图像。 but i keep getting this error但我不断收到此错误

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

Here are configurations:以下是配置:

Eureka Spring Properties:尤里卡弹簧属性:

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 Config:状态集配置:

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   

Service Config:服务配置:

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

Ingress Controller:入口控制器:

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

You have to install a kubernetes kube-dns server to resolve names with their IPs, and then expose your eureka pods as a service.您必须安装一个 kubernetes kube-dns 服务器来使用其 IP 解析名称,然后将您的 eureka pod 作为服务公开。 (see kubernetes docs ) for more infos to how to create dns and services. (请参阅 kubernetes文档)以获取有关如何创建 dns 和服务的更多信息。 @random_dude, what will be the case if i used to create 2 or 3 replicas of eureka? @random_dude,如果我曾经创建 2 或 3 个 eureka 副本会怎样? it turned out that when i mount a micro-service 'X' i will be registred in all eureka replicas, but when it becomes down, only one replicas gets the update !事实证明,当我挂载一个微服务“X”时,我将在所有 eureka 副本中注册,但是当它关​​闭时,只有一个副本得到更新! the others still consider the micro-service instance as running其他人仍然认为微服务实例正在运行

I got exactly this problem and it got resoled by adding an environment variable for pod.我确实遇到了这个问题,并通过为 pod 添加环境变量来解决它。 This has the answer.有答案。 Sample env variable for my pod is shown below,我的 pod 的示例环境变量如下所示,

在此处输入图像描述

I'm wondering where you put that config, is that on service-registry which is on the eureka, or in the client-side (where we want to connect to eureka)?我想知道你把那个配置放在哪里,是在 eureka 上的 service-registry 上,还是在客户端(我们想要连接到 eureka 的地方)?

my current case is, that all configuration is placed on a repo, the eureka config as well.我目前的情况是,所有配置都放在一个 repo 上,eureka 配置也是如此。 which makes the config static.这使得配置静态。

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

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