Kubernetes 部署 Spring Cloud 注册中心 Eureka Server

Kubernetes 部署 Spring Cloud 注册中心 Eureka Server

系统环境

Java JDK 版本:openjdk:8-jdk
Docker 版本: version 19.03.8
kubernetes 版本:1.14.0
SpringBoot 版本:2.0.3.RELEASE
SpringCloud 版本:Finchley.RELEASE

一. 简介

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 + docker 部署方式部署的,迁移的原则就是减少重构开发量,故而对于一些老项目迁移到 Kubernetes 中的话,还是需要部署 Eureka 来避免大规模改动代码。

二. 创建 Eureka Server 项目

a、Maven 引入相应 Jar



	4.0.0 
	eureka-server
	 1.0.0
	jar
	
		org.springframework.boot
		spring-boot-starter-parent
		2.0.3.RELEASE
		 
	
	
		UTF-8
        UTF-8
        1.8
        Finchley.RELEASE
	
	
		 
            org.springframework.cloud
            spring-cloud-starter-netflix-eureka-server
         
 		
 			io.micrometer
 			micrometer-core 
 		
 		    	
 		 
            net.logstash.logback
            logstash-logback-encoder
            4.10
        
	 
	
		
			
				org.springframework.boot
				spring-boot-maven-plugin
			
			  
		
	 
	 

		
			
				org.springframework.cloud
				spring-cloud-dependencies
				${spring-cloud.version}
				pom
				import
			
		
	
	
	


b、配置文件

需要在配置文件中设置两个参数:

server.port: 程序的 server 端口,用于外部访问 Eureka UI 与服务注册。
management.server.port: 程序的监控数据端口,这里主要用其中的 /actuator/health 端口进行健康检查。
bootstrap.yml

server:
  port: 8761 #启动端口
management:
  server:
    port: 8762
  endpoints:
    web:
      exposure:
        include: '*'

application.yml

eureka:
  environment: dev
  instance:
    hostname: localhost
  client:
    registerWithEureka: false  #false:不作为一个客户端注册到注册中心
    fetchRegistry: false      #为true时,可以启动,但报异常:Cannot execute request on any known server
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

c、启动类

启动类加上 @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 EurekaServiceApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(EurekaServiceApplication.class, args);
    }
}

三、构建 Eureka Docker 镜像

1、执行 Maven 编译

执行 Maven 命令将项目编译成一个可执行 JAR。

$ mvn clean install

2、准备 Dockerfile

创建构建 Docker 镜像需要的 Dockerfile 文件,将 Maven 编译的 JAR 复制到镜像内部,然后设置三个变量,分别是:
JVM_OPTS 设置一些必要的 JVM 启动参数。
JAVA_OPTS:Java JVM 启动参数变量,这里需要在这里加一个时区参数。
APP_OPTS:Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数。
Dockerfile

FROM openjdk:8-jdk
VOLUME /tmp
ADD eureka-server-1.0.0.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JVM_OPTS=" -Xms2048m -Xmx2048m -Xss256k -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom"
ENV JAVA_OPTS=""
ENV APP_OPTS=" -spring.profiles.active=local "
ENTRYPOINT [ "sh", "-c", "java $JVM_OPTS $JAVA_OPTS -jar /app.jar $APP_OPTS" ]

3、构建 Docker 镜像

执行 Docker Build 命令构建 Docker 镜像

docker build -t sscloud/eureka-server:1 .

坑点:注意版本号 后面的 . 否则会提示语法错误

4.给镜像打标签

docker tag aaf5e5e08b37 192.168.0.21:5000/eureka-server:1

aaf5e5e08b37 是构建后镜像的ID , 通过 docker images 查看
192.168.0.21:5000 是docker 私有仓库的地址和端口

5. 推送镜像到docker 私有仓库中

 docker push 192.168.0.21:5000/eureka-server:1

四、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

apiVersion: v1
kind: Service
metadata:
  name: eureka-server
  namespace: sscloud
  labels:
    app: eureka-server
spec:
  clusterIP: None
  ports:
    - name: server
      port: 8761
      targetPort: 8761
    - name: management
      port: 8762
  selector:
    app: eureka-server
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: eureka-server
  namespace: sscloud
  labels:
    app: eureka-server
spec:
  serviceName: eureka-server
  replicas: 3
  podManagementPolicy: Parallel     #Pod启停顺序管理
  selector:
    matchLabels:
      app: eureka-server
  template:
    metadata:
      labels:
        app: eureka-server
    spec:
      terminationGracePeriodSeconds: 10    #当删除Pod时,等待时间
      containers:
        - name: eureka
          image: 192.168.0.21:5000/eureka-server:1
          ports:
            - name: server
              containerPort: 8761
            - name: management
              containerPort: 8762
          env:
            - name: APP_NAME
              value: "eureka-server"
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: APP_OPTS
              value: "
                     --spring.application.name=${APP_NAME}
                     --eureka.instance.hostname=${POD_NAME}.${APP_NAME}
                     --registerWithEureka=true
                     --fetchRegistry=true
                     --eureka.instance.preferIpAddress=false
                     --eureka.client.serviceUrl.defaultZone=http://eureka-0.${APP_NAME}:8761/eureka/,http://eureka-1.${APP_NAME}:8761/eureka/,http://eureka-2.${APP_NAME}:8761/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: 8762
          livenessProbe:               #存活探针
            initialDelaySeconds: 60    #延迟加载时间
            periodSeconds: 5           #重试时间间隔
            timeoutSeconds: 5          #超时时间设置
            failureThreshold: 3        #探测失败的重试次数
            httpGet:
              path: /actuator/health
              port: 8762

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 中。
查看命名空间

kubectl get namespaces

创建命名空间
namespace.yml

apiVersion: v1
kind: Namespace
metadata:
  name: sscloud

在 k8s 主机上执行命令

 kubectl create -f namespace.yaml

服务部署

 kubectl apply -f eureka.yaml -n sscloud

五、创建 Kubernetes 集群外部访问的 NodePort Service

创建一个类型为 NodePort 类型的 Service,供 Kubernetes 集群外部访问 Eureka UI 界面,方便观察服务注册情况。

1、创建 Service 部署文件

eureka-node.yaml

apiVersion: v1
kind: Service
metadata:
  name: eureka-nodeport
  namespace: sscloud
  labels:
    app: eureka-nodeport
spec:
  type: NodePort
  ports:
    - name: eureka-server
      port: 8761
      targetPort: 8761
      nodePort: 31000
  selector:
    app: eureka-server

2、创建 Service

 kubectl apply -f eureka-node.yaml -n sscloud

3、访问 Eureka UI

本人的 Kubernetes 集群 IP 地址为 192.168.0.249,且上面设置 NodePort 端口为 31000,所以这里访问 http://192.168.0.249:31000 地址,查看 Eureka UI 界面。
Kubernetes 部署 Spring Cloud 注册中心 Eureka Server_第1张图片

你可能感兴趣的:(SpringCloud)