簡體   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