前言
服务发现原则:
- 各个微服务在启动时,会将自己的网络地址等信息注册到服务发现组件中,服务发现组件会存储这些信息
- 服务消费者可以从服务发现组件中查询到服务提供者的网络地址,并使用该地址来远程调用服务提供者的接口
- 各个微服务与服务发现组件使用一定的机制(如:心跳)通信。服务发现组件长时间无法与某微服务实例通信,就会注销该实例
- 当某个微服务网络地址发生变更(例如实例增减或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 + 序号