Kubernetes 部署 SrpingCloud 注册中心 Eureka Server
文章目录
!版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。
系统环境:
- Java JDK 版本:8
- Docker 版本:18.09.3
- kubernetes 版本:1.14.0
- SpringBoot 版本:2.1.7.RELEASE
- SpringCloud 版本:Greenwich.SR2
演示示例:
- 项目示例 Github:https://github.com/my-dlq/blog-example/tree/master/springcloud/springcloud-kubernetes-eureka
一、简介
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 的过程。
二、创建 Eureka Server 项目
1、Maven 引入相应 Jar
引入 SpringBoot 做基础框架,引入 SprigCloud Eureka 依赖来实现 Eureka Server 功能。
1<?xml version="1.0" encoding="UTF-8"?>
2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <parent>
6 <groupId>org.springframework.boot</groupId>
7 <artifactId>spring-boot-starter-parent</artifactId>
8 <version>2.1.7.RELEASE</version>
9 </parent>
10
11 <groupId>club.mydlq</groupId>
12 <artifactId>springcloud-kubernetes-eureka</artifactId>
13 <version>0.0.1</version>
14 <name>springcloud-kubernetes-eureka</name>
15
16 <properties>
17 <java.version>1.8</java.version>
18 </properties>
19
20 <dependencies>
21 <!--web-->
22 <dependency>
23 <groupId>org.springframework.boot</groupId>
24 <artifactId>spring-boot-starter-web</artifactId>
25 </dependency>
26 <!--actuator-->
27 <dependency>
28 <groupId>org.springframework.boot</groupId>
29 <artifactId>spring-boot-starter-actuator</artifactId>
30 </dependency>
31 <!--eureka server-->
32 <dependency>
33 <groupId>org.springframework.cloud</groupId>
34 <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
35 </dependency>
36 </dependencies>
37
38 <!--管理 SpringCloud 组件依赖间的版本-->
39 <dependencyManagement>
40 <dependencies>
41 <dependency>
42 <groupId>org.springframework.cloud</groupId>
43 <artifactId>spring-cloud-dependencies</artifactId>
44 <version>Greenwich.SR2</version>
45 <type>pom</type>
46 <scope>import</scope>
47 </dependency>
48 </dependencies>
49 </dependencyManagement>
50
51 <build>
52 <plugins>
53 <plugin>
54 <groupId>org.springframework.boot</groupId>
55 <artifactId>spring-boot-maven-plugin</artifactId>
56 </plugin>
57 </plugins>
58 </build>
59
60</project>
2、配置文件
需要在配置文件中设置两个参数:
- server.port: 程序的 server 端口,用于外部访问 Eureka UI 与服务注册。
- management.server.port: 程序的监控数据端口,这里主要用其中的 /actuator/health 端口进行健康检查。
application.yaml
1server:
2 port: 8080
3
4management:
5 server:
6 port: 8081
7 endpoints:
8 web:
9 exposure:
10 include: "*"
3、启动类
启动类加上 @EnableEurekaServer
注解来开启 Eureka Server 功能。
1import org.springframework.boot.SpringApplication;
2import org.springframework.boot.autoconfigure.SpringBootApplication;
3import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
4
5@EnableEurekaServer
6@SpringBootApplication
7public class Application {
8
9 public static void main(String[] args) {
10 SpringApplication.run(Application.class, args);
11 }
12
13}
三、构建 Eureka Docker 镜像
1、执行 Maven 编译
执行 Maven 命令将项目编译成一个可执行 JAR。
1$ mvn clean install
2、准备 Dockerfile
创建构建 Docker 镜像需要的 Dockerfile 文件,将 Maven 编译的 JAR 复制到镜像内部,然后设置三个变量,分别是:
- JVM_OPTS 设置一些必要的 JVM 启动参数。
- JAVA_OPTS:Java JVM 启动参数变量,这里需要在这里加一个时区参数。
- APP_OPTS:Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数。
Dockerfile
1FROM openjdk:8u222-jre-slim
2VOLUME /tmp
3ADD target/*.jar app.jar
4RUN sh -c 'touch /app.jar'
5ENV JVM_OPTS="-Xss256k -XX:MaxRAMPercentage=80.0 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom"
6ENV JAVA_OPTS=""
7ENV APP_OPTS=""
8ENTRYPOINT [ "sh", "-c", "java $JVM_OPTS $JAVA_OPTS -jar /app.jar $APP_OPTS" ]
3、构建 Docker 镜像
执行 Docker Build 命令构建 Docker 镜像。
1$ docker build -t mydlqclub/eureka-server:2.1.2 .
四、Kubernetes 部署 Eureka Server
1、创建 Eureka 的 Kubernetes 部署文件
创建 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
1apiVersion: v1
2kind: Service
3metadata:
4 name: eureka
5 labels:
6 app: eureka
7spec:
8 clusterIP: None
9 ports:
10 - name: server
11 port: 8080
12 targetPort: 8080
13 - name: management
14 port: 8081
15 selector:
16 app: eureka
17---
18apiVersion: apps/v1
19kind: StatefulSet
20metadata:
21 name: eureka
22 labels:
23 app: eureka
24spec:
25 serviceName: eureka
26 replicas: 3
27 podManagementPolicy: Parallel #Pod启停顺序管理
28 selector:
29 matchLabels:
30 app: eureka
31 template:
32 metadata:
33 labels:
34 app: eureka
35 spec:
36 terminationGracePeriodSeconds: 10 #当删除Pod时,等待时间
37 containers:
38 - name: eureka
39 image: mydlqclub/eureka-server:2.1.2
40 ports:
41 - name: server
42 containerPort: 8080
43 - name: management
44 containerPort: 8081
45 env:
46 - name: APP_NAME
47 value: "eureka"
48 - name: POD_NAME
49 valueFrom:
50 fieldRef:
51 fieldPath: metadata.name
52 - name: APP_OPTS
53 value: "
54 --spring.application.name=${APP_NAME}
55 --eureka.instance.hostname=${POD_NAME}.${APP_NAME}
56 --eureka.client.registerWithEureka=true
57 --eureka.client.fetchRegistry=true
58 --eureka.instance.preferIpAddress=false
59 --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/
60 "
61 resources:
62 limits:
63 cpu: 2000m
64 memory: 1024Mi
65 requests:
66 cpu: 2000m
67 memory: 1024Mi
68 readinessProbe: #就绪探针
69 initialDelaySeconds: 20 #延迟加载时间
70 periodSeconds: 5 #重试时间间隔
71 timeoutSeconds: 10 #超时时间设置
72 failureThreshold: 5 #探测失败的重试次数
73 httpGet:
74 path: /actuator/health
75 port: 8081
76 livenessProbe: #存活探针
77 initialDelaySeconds: 60 #延迟加载时间
78 periodSeconds: 5 #重试时间间隔
79 timeoutSeconds: 5 #超时时间设置
80 failureThreshold: 3 #探测失败的重试次数
81 httpGet:
82 path: /actuator/health
83 port: 8081
env 参数说明:
- APP_NAME: 和服务名称一致,将服务名称传入容器环境中。
- POD_NAME: Pod名称,将 Pod 名称传入容器环境中。
- APP_OPTS: Dockerfile 中定义的变量,用于设置 Spring 启动参数,这里主要设置此值与
APP_NAME
和POD_NAME
两值配合使用。
其它参数说明:
- resources: 对 Pod 使用计算资源的限制,最好两个值设置成一致,Kubernetes 中会对 Pod 设置 QoS 等级,跟这两个值的设置挂钩,limits 与 request 值一致时 Qos 等级最高,当资源不足时候 QoS 等级低的最先被杀死,等级高的一般不会受太大影响。
- readinessProbe: 就绪探针,Pod 启动时只有就绪探针探测成功后才对外提供访问,用它可用避免 Pod 启动而内部程序没有启动的情况下就允许外部流量流入这种情况。
- livenessProbe: 存活探针,定期检测 Docker 内部程序是否存活。
- spec.podManagementPolicy: pod的启动顺序策略
- OrderedReady: 顺序启停 Pod,默认设置。
- Parallel: 并行启停 Pod,而不遵循一个 Pod 启动后再启动另一个这种规则。
2、部署 Eureka 到 Kubernetes
-n:创建应用到指定的 Namespace 中。
1$ kubectl apply -f eureka.yaml -n mydlqcloud
五、创建 Kubernetes 集群外部访问的 NodePort Service
创建一个类型为 NodePort 类型的 Service,供 Kubernetes 集群外部访问 Eureka UI 界面,方便观察服务注册情况。
1、创建 Service 部署文件
1apiVersion: v1
2kind: Service
3metadata:
4 name: eureka-nodeport
5 labels:
6 app: eureka-nodeport
7spec:
8 type: NodePort
9 ports:
10 - name: server
11 port: 8080
12 targetPort: 8080
13 nodePort: 31011
14 selector:
15 app: eureka
2、创建 Service
-n:创建应用到指定的 Namespace 中。
1$ kubectl apply -f eureka.yaml -n mydlqcloud
3、访问 Eureka UI
本人的 Kubernetes 集群 IP 地址为 192.168.2.11,且上面设置 NodePort 端口为 31001,所以这里访问 http://192.168.2.11:31001 地址,查看 Eureka UI 界面。
---END---
!版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。