前言
服務發現原則:
- 各個微服務在啟動時,會將自己的網絡地址等信息注冊到服務發現組件中,服務發現組件會存儲這些信息
- 服務消費者可以從服務發現組件中查詢到服務提供者的網絡地址,並使用該地址來遠程調用服務提供者的接口
- 各個微服務與服務發現組件使用一定的機制(如:心跳)通信。服務發現組件長時間無法與某微服務實例通信,就會注銷該實例
- 當某個微服務網絡地址發生變更(例如實例增減或IP端口發生變化等)時,會重新注冊到服務發現組件
所以,使用服務發現的好處是非常多的,那么Spring Cloud提供了多種服務發現組件的支持,例如:Eureka、Consul和Zookeeper等。本文章以Eureka為例
Eureka簡介
Eureka是Netflix
開開源的,一個基於REST
服務的服務注冊
與發現
的組件,它包含Server
和Client
兩部分,
Eureka兩組件:
- Eureka Client:一個Java客戶端,用於簡化與 Eureka Server 的交互(通常就是微服務中的客戶端和服務端)
- Eureka Server:提供服務注冊和發現的能力(通常就是微服務中的注冊中心)
默認情況下,Eureka Server同時也是Eureka Client,多個Eureka Server實例,互相之間通過復制的方式,來實現服務注冊表中數據的同步
Eureka至構建鏡像
1、Eureka的dockerfile
FROM java:8-jdk-alpine
LABEL maintainer
ENV JAVA_OPTS="$JAVA_OPTS -Dfile.encoding=UTF8 -Duser.timezone=GMT+08"
RUN apk add -U tzdata && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
COPY ./target/eureka-service.jar ./
EXPOSE 8888
CMD java -jar -Dpinpoint.agentId=${HOSTNAME} -Dpinpoint.applicationName=ms-eureka $JAVA_OPTS -Deureka.instance.hostname=${MY_POD_NAME}.eureka.test /eureka-service.jar
Eureka暴露端口:8888
Eureka以容器方式啟動后的主機名:${MY_POD_NAME}.eureka.test,test為namespace環境名
Eureka啟動參數:${JAVA_OPTS}
構建鏡像並上傳至harbor倉庫
$ docker build ./ -t harbor.od.com/infra/eureka
$ docker push harbor.od.com/infra/eureka:v1.0.0
Eureka交付至k8s
思考
在本文中Eureka是以三節點
高可用的方式交付進k8s,這里選擇用 StatefulSet
(有狀態集)方式來部署,這樣能保證它 Eureka Pod
名是有序的,並且這里選擇用 StatefulSet (有狀態集)方式來部署,這樣能保證它的 Eureka Pod 名是有序的,並且 StatefulSet
支持 Service Headless
方式創建 Service
來對內部服務訪問,如果選擇使用ClusterIP方式創建Service
會自動分配一個虛擬IP給予Service
,那服務通過Service
訪問Pod每次都需要經過Kube-proxy
代理流量,這樣就會增加與注冊中心通信造成一定的消耗,Headless
方式部署的 Service
不會分配虛擬 IP,而是用輪詢的訪問,每次都直接與 Pod
的 IP 進行通信。
1、准備yaml文件
- StatefulSet
$ vim /data/k8s-yaml/spring-cloud/eureka/st.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka
namespace: test
spec:
replicas: 3
selector:
matchLabels:
app: eureka
serviceName: "eureka"
template:
metadata:
labels:
app: eureka
spec:
imagePullSecrets:
- name: harbor
containers:
- name: eureka
image: harbor.od.com/infra/eureka:v1.0.0
ports:
- protocol: TCP
containerPort: 8888
env:
- name: JAVA_OPTS
value: "-Xmx1g"
- name: MY_POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
resources:
requests:
cpu: 0.5
memory: 256Mi
limits:
cpu: 1
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8888
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8888
initialDelaySeconds: 60
periodSeconds: 10
- Service
$ vim /data/k8s-yaml/spring-cloud/eureka/svc.yaml
apiVersion: v1
kind: Service
metadata:
name: eureka
namespace: test
spec:
clusterIP: None
ports:
- port: 8888
targetPort: 8888
name: eureka
selector:
app: eureka
- Ingress
$ vim /data/k8s-yaml/spring-cloud/eureka/ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: eureka
namespace: test
spec:
rules:
- host: eureka.od.com
http:
paths:
- path: /
backend:
serviceName: eureka
servicePort: 8888
2、應用yaml文件
$ cd /data/k8s-yaml/spring-cloud/eureka/
$ kubectl create -f ./
3、檢查eureka狀態
$ kubectl get statefulset -n test
NAME READY AGE
eureka 3/3 99s
4、spring cloud服務注冊進eureka
$ cat application.yaml
eureka:
instance:
prefer-ip-address: true # 以IP方式注冊進eureka,不以ID注冊
client:
register-with-eureka: true # 注冊到eureka選true
fetch-registry: true
service-url:
defaultZone: http://eureka-0.eureka.test:8888/eureka,http://eureka-1.eureka.test:8888/eureka,http://eureka-2.eureka.test:8888/eureka
Pod的dns記錄組成:
. . .svc.cluster.local
Pod的Name組成:statefulSet控制器的Name + 序號
5、瀏覽器訪問Eureka管理頁面