[英]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”。
每個 k8s 服務不應該有超過一個 Eureka 的 Pod/副本(請記住,Pod 是短暫的,你需要一個可引用的 IP 地址/域名用於 eureka 服務注冊表)。 要實現高可用性 (HA),請啟動更多 k8s 服務,每個服務都有一個 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:
注意:示例中使用的 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.