Kubernetes 部署 SpringBoot Admin + Eureka 监控微服务

Kubernetes 部署 SpringBoot Admin + Eureka 监控微服务

文章目录

  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。


系统环境

  • Kubernetes 版本:1.5.3
  • SpringBoot Admin 版本:2.1.6
  • SpringCloud 版本:Greenwich.SR2
  • SpringCloud Kubernetes 版本:1.0.2.RELEASE

参考地址

  • 示例 Github 地址:https://github.com/my-dlq/blog-example/tree/master/springcloud/springboot-admin-demo

一、概念简介

1、背景

现在很多 SpringCloud 组件都在往 Kubernetes 中迁移,SpringBoot Admin 作为我们微服务监控经常使用的组件,也要将它迁移到 Kubernetes 环境下。

在之前写过 SpringBoot Admin 与 SpringCloud Kubernetes 组件结合,通过 API 方式发现服务列表,让 Admin 服务能服务发现。但是现在还是很多实际生产环境中,还是将 Eureka 注册中心部署到 Kubernetes 环境下作为注册中心,然后将全部服务注册到 Eureka,通过注册中心将服务间关系进行关联,所以考虑到这种情况,所以这里将使用 Admin + Eureka 方式来部署。

2、SpringBoot Admin 简介

SpringBoot Admin 是一个管理和监控 SpringBoot 应用程序的开源软件,每个应用都认为是一个客户端,它可用通过 HTTP 或者使用 Eureka 注册到 admin server 中,能收集这些客户端的监控指标信息,展示在页面上,并且还能动态更改日志级别。

3、SpringBoot Admin 功能

常见的功能如下:

  • 显示健康状况
  • 显示详细信息,例如
    • JVM和内存指标
    • micrometer.io指标
    • 数据源指标
    • 缓存指标
  • 显示构建信息编号
  • 关注并下载日志文件
  • 查看jvm系统和环境属性
  • 查看Spring Boot配置属性
  • 支持Spring Cloud的postable / env-和/ refresh-endpoint
  • 轻松的日志级管理
  • 与JMX-beans交互
  • 查看线程转储
  • 查看http跟踪
  • 查看auditevents
  • 查看http-endpoints
  • 查看计划任务
  • 查看和删除活动会话(使用spring-session)
  • 查看Flyway / Liquibase数据库迁移
  • 下载heapdump
  • 状态变更通知(通过电子邮件,Slack,Hipchat,......)
  • 状态更改的事件日志(非持久性)

二、Kubernetes 部署 SpringBoot Admin 需要的环境

1、注册中心

由于这里使用 SpringBoot Admin 用于监控 SpringCloud 下的微服务,故而需要一个注册中心。现在生产环境下使用最多的还是 Eureka,所以我们需要提前部署 Eureka 注册中心,并且现在是 Kubernets 环境,如何在 Kubernetes 部署 Eureka 注册中心,在之前博博客中已经写过,这里不过多描述,本人这里已经存在的环境如下:

2、配置中心

在 SpringCloud 微服务框架中,我们需要一个配置中心来管理整个微服务的配置,并且实现动态刷新配置。

我们常用的做法是部署 SpringCloud Config 组件,但是由于 SpringCloud Config 需要将配置存放于 Git 或者 SVN 中,这两种存储仓库都会有不可读取或者读取超时问题,动态通知可能还需要部署一个消息队列动来充当消息总线,还要保证队列的稳定性从而不影响全部服务的可用性,故而比较麻烦和需要保证可用性,这里不太推荐。

由于 SpringCloud 各个组件和服务都是部署在 Kubernetes 环境下,而 Kubernetes 自己也有个配置管理的 ConfigMap。考虑到这点 SpringCloud 也有 SpringCloud Kubernetes Config项目,可以从 ConfigMap 动态读取配置信息,只要 Kubernetes 整个集群不宕机,那么配置就可以得到保障,这是目前比较推荐的组件。

关于如何使用 SpringCloud Kubernetes Config 完成动态配置,之前文章中也有写,需要了解的可以查看下。当然,如果你使用不是该组件,而是另一款比较流行的配置中心 Apollo 也是可以的。

使用 SpringCloud Kubernetes Config 配置中心非常简单,只需要:

  • (1)、SpringBoot 项目 Maven 引入 spring-cloud-starter-kubernetes-config 组件。
  • (2)、SpringBoot 项目 Maven 引入 spring-boot-starter-actuator 组件,并开启 management.endpoint.restart.enabled 选项。
  • (3)、将 SpringBoot 项目中的 Application.yml 配置内容存入 ConfigMap。
  • (4)、SpringBoot 项目中的 Bootstrap.yml 配置 spring-cloud-starter-kubernetes-config 的配置项,配置从 Kubernetes 的哪个 Namespace 下读取 ConfigMap 对象信息。

(1)、Maven 引入对应依赖

 1<!--Actuator-->
 2<dependency>
 3  	<groupId>org.springframework.boot</groupId>
 4  	<artifactId>spring-boot-starter-actuator</artifactId>
 5</dependency>
 6<!--springcloud kubernetes config-->
 7<dependency>
 8    <groupId>org.springframework.cloud</groupId>
 9    <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
10</dependency>

(2)、将 application.yml 内容写入 Kubernetes 的 ConfigMap 中,然后部署到 Kubernetes

 1kind: ConfigMap
 2apiVersion: v1
 3metadata:
 4  name: springcloud-zuul-config
 5data:
 6  application.yaml: |-
 7    eureka:
 8      client:
 9        service-url:
10          defaultZone: http://127.0.0.1:30002/eureka/    

(3)、Bootstrap 中配置 spring-cloud-starter-kubernetes-config 和 Actuator 的配置项,用于加载 ConfigMap 中的配置和开启 Actuator 的 Restart 功能

 1#Actuator Config
 2management:
 3  server:
 4    port: 8081
 5  endpoint:
 6    restart:
 7      enabled: true
 8#Read ConfigMap Config
 9server:
10  port: 8080
11spring:
12  application:
13    name: springcloud-zuul-demo
14  cloud:
15    kubernetes:
16      reload:
17        enabled: true
18        mode: polling
19        period: 5000
20        strategy: refresh
21        monitoring-secrets: true
22      config:
23        enabled: true
24        enableApi: true
25        sources:
26          - namespace: mydlqcloud
27            name: springcloud-zuul-config

三、SpringBoot Admin Server 示例项目

1、Maven 引入相关依赖

 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
 6    <parent>
 7        <groupId>org.springframework.boot</groupId>
 8        <artifactId>spring-boot-starter-parent</artifactId>
 9        <version>2.1.8.RELEASE</version>
10    </parent>
11
12    <groupId>club.mydlq</groupId>
13    <artifactId>springboot-admin-demo</artifactId>
14    <version>0.0.1</version>
15    <name>springboot-admin-demo</name>
16    <description>springboot admin demo project</description>
17
18    <properties>
19        <java.version>1.8</java.version>
20    </properties>
21
22    <dependencies>
23    	<!--Web-->
24        <dependency>
25            <groupId>org.springframework.boot</groupId>
26            <artifactId>spring-boot-starter-web</artifactId>
27        </dependency>
28        <!--Actuator-->
29        <dependency>
30		  	<groupId>org.springframework.boot</groupId>
31		  	<artifactId>spring-boot-starter-actuator</artifactId>
32		</dependency>
33		<!--Eureka-->
34		<dependency>
35            <groupId>org.springframework.cloud</groupId>
36            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
37        </dependency>
38        <!--SpringBoot Admin Server-->
39        <dependency>
40            <groupId>de.codecentric</groupId>
41            <artifactId>spring-boot-admin-starter-server</artifactId>
42            <version>2.1.6</version>
43        </dependency>
44        <!-- 在管理界面中与 JMX-beans 进行交互所需要被依赖的 JAR -->
45		<dependency>
46		  	<groupId>org.jolokia</groupId>
47		  	<artifactId>jolokia-core</artifactId>
48		</dependency>
49		<!--SpringCloud Kubernetes Config-->
50        <dependency>
51            <groupId>org.springframework.cloud</groupId>
52            <artifactId>spring-cloud-starter-kubernetes-config</artifactId>
53        </dependency>
54    </dependencies>
55
56    <dependencyManagement>
57        <!--SpringCloud 版本管理-->
58        <dependencies>
59            <dependency>
60                <groupId>org.springframework.cloud</groupId>
61                <artifactId>spring-cloud-dependencies</artifactId>
62                <version>Greenwich.SR2</version>
63                <type>pom</type>
64                <scope>import</scope>
65            </dependency>
66        </dependencies>
67    </dependencyManagement>
68
69    <build>
70        <plugins>
71            <plugin>
72                <groupId>org.springframework.boot</groupId>
73                <artifactId>spring-boot-maven-plugin</artifactId>
74            </plugin>
75        </plugins>
76    </build>
77
78</project>

2、配置文件

SpringBoot 中有 application.yml 和 bootstrap.yml 两个配置文件,SpirngBoot 在加载时候会先加载 bootstrap.yml 配置,然后再加载 application.yml 中的配置。在这里 application.yml 和 bootstrap.yml 两个文件分别有不同的作用:

  • application: 这里一般用于配置应用程序中的参数,将 Eureka、Log、Server、Spring 等配置存入该配置文件中,在将 SpringBoot Admin 部署到 Kubernetes 前,会将 application.yml 的配置内容存于 Kubernetes 的 ConfigMap 中,方便 SpringBoot Admin Server 动态读取配置。
  • bootstrap: 设置 SpringCloud Kubernetes Config 配置参数,动态读取上面配置的 Kubernetes 下的 ConfigMap 的参数值。

(1)、配置文件 application.yml

 1#log config
 2logging:
 3  path: /opt/logs/
 4#eureka config
 5eureka:
 6  instance:
 7    prefer-ip-address: true
 8    instance-id: ${spring.cloud.client.ip-address}:${server.port}
 9  client:
10    service-url:
11      #defaultZone: http://192.168.2.11:31011/eureka/
12      defaultZone: http://eureka-0.eureka.mydlqcloud:8080/eureka/,http://eureka-1.eureka.mydlqcloud:8080/eureka/,http://eureka-2.eureka.mydlqcloud:8080/eureka/

参数简介:

  • eureka: Eureka 注册中心相关配置。
  • log: 日志配置信息,如果不设置 loggging.path 参数,那么 SpringBoot Admin UI 中不能查看到应用的日志信息。

(2)、配置文件 bootstrap.yml

这里主要是设置 SpringCloud Kubernetes Config 的配置,用于读取 Kubernetes 中的 ConfigMap 中的配置项。

  • 注意:请修改下面的 spring.cloud.kubernetes.config.sources 选项中的 namespace 和对应 ConfigMapname 参数。
 1#Actuator Config
 2management:
 3  server:
 4    port: 8081
 5  endpoint:
 6    restart:
 7      enabled: true
 8    health:
 9      show-details: always
10  endpoints:
11    web:
12      exposure:
13        include: "*"
14#Base Config
15server:
16  port: 8080
17spring:
18  application:
19    name: springboot-admin-demo
20  cloud:
21    kubernetes:
22      reload:
23        enabled: true
24        mode: polling
25        period: 5000
26        strategy: refresh
27        monitoring-secrets: true
28      config:
29        enabled: true
30        enableApi: true
31        sources:
32          - namespace: mydlqcloud		#Namespace
33            name: springboot-admin		#ConfigMap Name

参数简介:

  • application: SpringBoot 基础配置。
  • actuator: SpringBoot 的 Actuator 端口,可以暴露监控指标信息,这里一定要设置 management.endpoint.restart.enabled=true 这个配置项,否则启动时候 SpringCloud Kubernetes 组件会报错。

3、项目启动类

启动类上需要额外加上俩个注解:

  • @EnableAdminServer: 启用 SpringBoot Amdin Server。
  • @EnableDiscoveryClient: 启用 SpringCloud 服务发现,这里会开启 Eureka。
 1import de.codecentric.boot.admin.server.config.EnableAdminServer;
 2import org.springframework.boot.SpringApplication;
 3import org.springframework.boot.autoconfigure.SpringBootApplication;
 4import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
 5
 6@SpringBootApplication
 7@EnableDiscoveryClient
 8@EnableAdminServer
 9public class Application {
10
11    public static void main(String[] args) {
12        SpringApplication.run(Application.class, args);
13    }
14
15}

四、构建 Docker 镜像

由于我们是将 SpringBoot Admin Server 部署到 Kubernetes 环境下,所以我们这里将上面的示例项目构建成 Docker 镜像,然后推送到镜像仓库,方便后续部署到 Kubernetes 环境下。

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 镜像,等待镜像构建完成后,执行 Docker push 命令,将镜像推送到镜像仓库。

1# 构建镜像
2$ docker build -t mydlqclub/springboot-admin-server:0.0.1 .
3
4# 推送镜像
5$ docker push mydlqclub/springboot-admin-server:0.0.1

五、Kubernetes 部署 SpringBoot Admin

1、创建应用权限 RBAC

(1)、创建 RBAC 部署文件

由于程序需要读取 ConfigMap 中的配置,需要一定的权限,这里提前创建一个 RBAC 对象来供程序绑定以获取读取的权限,下面是 RBAC 对象的部署文件。

  • 注意:需要修改下面的全部 Namespace 参数为你自己 Kubernetes 集群的 Namespace 名称。

admin-rbac.yaml

 1apiVersion: v1
 2kind: ServiceAccount
 3metadata:
 4  name: springboot-admin
 5  namespace: mydlqcloud
 6---
 7kind: ClusterRoleBinding
 8apiVersion: rbac.authorization.k8s.io/v1
 9metadata:
10  name: springboot-admin
11subjects:
12  - kind: ServiceAccount
13    name: springboot-admin
14    namespace: mydlqcloud
15roleRef:
16  kind: ClusterRole
17  name: cluster-admin
18  apiGroup: rbac.authorization.k8s.io

(2)、在 Kubernetes 中部署应用配置 RBAC

-n:创建应用到指定的 Namespace 中。

1$ kubectl apply -f admin-rbac.yaml -n mydlqcloud

2、创建应用配置 ConfigMap

(1)、创建 ConfigMap 部署文件

创建 application-configmap.yaml 配置文件,将示例项目中 application.yml 配置文件中的配置项复制到 ConfigMap 中。

admin-configmap.yaml

 1kind: ConfigMap
 2apiVersion: v1
 3metadata:
 4  name: springboot-admin
 5data:
 6  application.yaml: |-
 7    #log config
 8    logging:
 9      path: /opt/logs/
10    #eureka config
11    eureka:
12      instance:
13        prefer-ip-address: true
14        instance-id: ${spring.cloud.client.ip-address}:${server.port}
15      client:
16        service-url:
17          #defaultZone: http://192.168.2.11:31011/eureka/
18          defaultZone: http://eureka-0.eureka.mydlqcloud:8080/eureka/,http://eureka-1.eureka.mydlqcloud:8080/eureka/,http://eureka-2.eureka.mydlqcloud:8080/eureka/      

(2)、在 Kubernetes 中部署应用配置 ConfigMap

-n:创建应用到指定的 Namespace 中。

1$ kubectl apply -f admin-configmap.yaml -n mydlqcloud

3、创建 SpringBoot Admin 的 Kubernetes 部署文件

(1)、创建 SpringBoot Admin 部署文件

admin-server.yaml

 1apiVersion: v1
 2kind: Service
 3metadata:
 4  name: springboot-admin-server
 5spec:
 6  type: NodePort
 7  ports:
 8    - name: server
 9      nodePort: 31083
10      port: 8080
11      targetPort: 8080
12    - name: management
13      nodePort: 31084
14      port: 8081
15      targetPort: 8081
16  selector:
17    app: springboot-admin-server
18---
19apiVersion: apps/v1
20kind: Deployment
21metadata:
22  name: springboot-admin-server
23  labels:
24    app: springboot-admin-server
25spec:
26  replicas: 1
27  selector:
28    matchLabels:
29      app: springboot-admin-server
30  template:
31    metadata:
32      name: springboot-admin-server
33      labels:
34        app: springboot-admin-server
35    spec:
36      serviceAccountName: springboot-admin
37      containers:
38        - name: springboot-admin-server
39          image: mydlqclub/springboot-admin-server:0.0.1
40          #imagePullPolicy: Always
41          ports:
42            - name: server
43              containerPort: 8080
44            - name: management
45              containerPort: 8081           
46          resources:
47            limits:
48              memory: 1024Mi
49              cpu: 1000m
50            requests:
51              memory: 1024Mi
52              cpu: 1000m
53          readinessProbe:            
54            initialDelaySeconds: 20    
55            periodSeconds: 5         
56            timeoutSeconds: 10         
57            failureThreshold: 5       
58            httpGet:
59              path: /actuator/health
60              port: 8081
61          livenessProbe:             
62            initialDelaySeconds: 60    
63            periodSeconds: 5           
64            timeoutSeconds: 5       
65            failureThreshold: 3      
66            httpGet:
67              path: /actuator/health
68              port: 8081
69          volumeMounts:
70            - name: log
71              mountPath: /opt/logs
72      volumes:
73        - name: log
74          hostPath:
75            type: DirectoryOrCreate
76            path: /data/apps/logs

(2)、在Kubernetes 中部署应用

-n:创建应用到指定的 Namespace 中。

1$ kubectl apply -f admin-server.yaml -n mydlqcloud

六、测试部署的应用接口

将 SpringBoot Admin 部署到 Kubernetes 后,我们可以通过访问在部署文件中配置的 Service 的 NodePort 端口 31083 ,且 Kubernetes 集群地址为 192.168.2.11。所以输入地址:http://192.168.2.11:31083 访问 Admin UI 界面。

---END---


  !版权声明:本博客内容均为原创,每篇博文作为知识积累,写博不易,转载请注明出处。