> 欢迎关注我的个人博客,关注最新动态: http://www.mydlq.club
系统环境:
演示示例:
Eureka 是 Netflix 开发的服务发现框架,本身是一个基于 REST 的服务。Eureka包含 Eureka Server
和 Eureka Client
两个组件,Eureka Server 提供服务注册服务,Eureka Client 会将信息注册到 Eureka Server,然后各个 Eureka Client 间就能通过 Eureka Server 获取已经注册服务实例的节点位置信息和状态等信息。
SpringCloud 是一套非常火爆的微服务架构,它很多组件都需要 Eureka Server
充作注册中心来完成服务间负载均衡和维护服务列表信息等功能。Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化。现在我们很多服务都是以 Docker
镜像方式运行在各个服务器上,并且依赖 Kubernetes
来对服务镜像进行编排,接下来要部署的 Eureka Server 也是要用 StaetfulSet
方式部署到 Kubernetes
中运行。
现阶段实际往 Kubernetes
中迁移的项目大多数都是之前未使用 Kubernetes 的项目,由于 Kubernetes
自己有一套服务发现、负载均衡机制(ETCD、CoreDNS、Service),所以觉得用 Eureka
来当注册中心就不能和 Kubernetes
的 Service
配合起来,也就不能使用过 Kubernetes
提供的负载能力,使之带来了开发的不便。当然,之前的老项目很多是基于 SpringCloud + 物理机部署方式部署的,迁移的原则就是减少重构开发量,故而对于一些老项目迁移到 Kubernetes
中的话,还是需要部署 Eureka
来避免大规模改动代码。
话不多说,这里就将记录下 Kubernetes 中部署 Eureka 的过程。
引入 SpringBoot 做基础框架,引入 SprigCloud Eureka 依赖来实现 Eureka Server 功能。
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
club.mydlq
springcloud-kubernetes-eureka
0.0.1
springcloud-kubernetes-eureka
1.8
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-actuator
org.springframework.cloud
spring-cloud-starter-netflix-eureka-server
org.springframework.cloud
spring-cloud-dependencies
Greenwich.SR2
pom
import
org.springframework.boot
spring-boot-maven-plugin
需要在配置文件中设置两个参数:
application.yaml
server:
port: 8080
management:
server:
port: 8081
启动类加上 @EnableEurekaServer
注解来开启 Eureka Server 功能。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
执行 Maven 命令将项目编译成一个可执行 JAR。
$ mvn clean install
创建构建 Docker 镜像需要的 Dockerfile 文件,将 Maven 编译的 JAR 复制到镜像内部,然后设置两个变量,分别是:
Dockerfile
FROM openjdk:8u222-jre-slim
VOLUME /tmp
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai"
ENV APP_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]
执行 Docker Build 命令构建 Docker 镜像。
$ docker build -t mydlqclub/eureka-server:2.1.2 .
创建 Eureka 部署文件,用于在 Kubernetes
中部署 Eureka
,这里选择用 StatefulSet
(有状态集)方式来部署,这样能保证它 Eureka Pod
名是有序的,如果部署为 Deployment
,那么得部署三个 Deployment
对象,比较繁琐。并且 StatefulSet
支持 Service Headless
方式创建 Service
来对内部服务访问,如果是 CluserIP
方式创建 Service
会分一个虚拟 IP 给该 Service
,那么服务通过 Service
访问 Pod
每次都需要经过 Kube-proxy
代理流量,这样会增加与注册中心的通信造成一定性能损耗。Headless
方式部署的 Service
不会分配虚拟 IP,而是用轮询的访问,每次都直接与 Pod
的 IP 进行通信。
eureka.yaml
apiVersion: v1
kind: Service
metadata:
name: eureka
labels:
app: eureka
spec:
clusterIP: None
ports:
- name: server
port: 8080
targetPort: 8080
- name: management
port: 8081
selector:
app: eureka
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: eureka
labels:
app: eureka
spec:
serviceName: eureka
replicas: 3
podManagementPolicy: Parallel #Pod启停顺序管理
selector:
matchLabels:
app: eureka
template:
metadata:
labels:
app: eureka
spec:
terminationGracePeriodSeconds: 10 #当删除Pod时,等待时间
containers:
- name: eureka
image: mydlqclub/eureka-server:2.1.2
ports:
- name: server
containerPort: 8080
- name: management
containerPort: 8081
env:
- name: APP_NAME
value: "eureka"
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: APP_OPTS
value: "
--eureka.instance.hostname=${POD_NAME}.${APP_NAME}
--registerWithEureka=true
--fetchRegistry=true
--eureka.instance.preferIpAddress=false
--eureka.client.serviceUrl.defaultZone=http://eureka-0.${APP_NAME}:8080/eureka/,http://eureka-1.${APP_NAME}:8080/eureka/,http://eureka-2.${APP_NAME}:8080/eureka/
"
resources:
limits:
cpu: 2000m
memory: 1024Mi
requests:
cpu: 2000m
memory: 1024Mi
readinessProbe: #就绪探针
initialDelaySeconds: 20 #延迟加载时间
periodSeconds: 5 #重试时间间隔
timeoutSeconds: 10 #超时时间设置
failureThreshold: 5 #探测失败的重试次数
httpGet:
path: /actuator/health
port: 8081
livenessProbe: #存活探针
initialDelaySeconds: 60 #延迟加载时间
periodSeconds: 5 #重试时间间隔
timeoutSeconds: 5 #超时时间设置
failureThreshold: 3 #探测失败的重试次数
httpGet:
path: /actuator/health
port: 8081
env 参数说明:
APP_NAME
和 POD_NAME
两值配合使用。其它参数说明:
-n:创建应用到指定的 Namespace 中。
$ kubectl apply -f eureka.yaml -n mydlqcloud
创建一个类型为 NodePort 类型的 Service,供 Kubernetes 集群外部访问 Eureka UI 界面,方便观察服务注册情况。
apiVersion: v1
kind: Service
metadata:
name: eureka-nodeport
labels:
app: eureka-nodeport
spec:
type: NodePort
ports:
- name: server
port: 8080
targetPort: 8080
nodePort: 31011
selector:
app: eureka
-n:创建应用到指定的 Namespace 中。
$ kubectl apply -f eureka.yaml -n mydlqcloud
本人的 Kubernetes 集群 IP 地址为 192.168.2.11,且上面设置 NodePort 端口为 31001,所以这里访问 http://192.168.2.11:31001 地址,查看 Eureka UI 界面。
—END—