Kubernetes 部署 SpringBoot Admin + Eureka 监控微服务
系统环境
- Kubernetes 版本:1.5.3
- SpringBoot Admin 版本:2.1.6
- SpringCloud 版本:Greenwich.SR2
- SpringCloud Kubernetes 版本:1.0.2.RELEASE
参考地址
一、概念简介
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 注册中心,在之前博博客中已经写过,这里不过多描述,本人这里已经存在的环境如下:
- Kuberenetes 中 Eureka 地址: http://eureka-0.eureka.mydlqcloud:8080/eureka/,http://eureka-1.eureka.mydlqcloud:8080/eureka/,http://eureka-2.eureka.mydlqcloud:8080/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 引入对应依赖
<!--Actuator--><dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId></dependency><!--springcloud kubernetes config--><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId></dependency>(2)、将 application.yml 内容写入 Kubernetes 的 ConfigMap 中,然后部署到 Kubernetes
kind: ConfigMapapiVersion: v1metadata: name: springcloud-zuul-configdata: application.yaml: |- eureka: client: service-url: defaultZone: http://127.0.0.1:30002/eureka/(3)、Bootstrap 中配置 spring-cloud-starter-kubernetes-config 和 Actuator 的配置项,用于加载 ConfigMap 中的配置和开启 Actuator 的 Restart 功能
#Actuator Configmanagement: server: port: 8081 endpoint: restart: enabled: true#Read ConfigMap Configserver: port: 8080spring: application: name: springcloud-zuul-demo cloud: kubernetes: reload: enabled: true mode: polling period: 5000 strategy: refresh monitoring-secrets: true config: enabled: true enableApi: true sources: - namespace: mydlqcloud name: springcloud-zuul-config三、SpringBoot Admin Server 示例项目
1、Maven 引入相关依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.8.RELEASE</version> </parent>
<groupId>club.mydlq</groupId> <artifactId>springboot-admin-demo</artifactId> <version>0.0.1</version> <name>springboot-admin-demo</name> <description>springboot admin demo project</description>
<properties> <java.version>1.8</java.version> </properties>
<dependencies> <!--Web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--Actuator--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <!--Eureka--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <!--SpringBoot Admin Server--> <dependency> <groupId>de.codecentric</groupId> <artifactId>spring-boot-admin-starter-server</artifactId> <version>2.1.6</version> </dependency> <!-- 在管理界面中与 JMX-beans 进行交互所需要被依赖的 JAR --> <dependency> <groupId>org.jolokia</groupId> <artifactId>jolokia-core</artifactId> </dependency> <!--SpringCloud Kubernetes Config--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-kubernetes-config</artifactId> </dependency> </dependencies>
<dependencyManagement> <!--SpringCloud 版本管理--> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Greenwich.SR2</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
</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
#log configlogging: path: /opt/logs/#eureka configeureka: instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${server.port} client: service-url: #defaultZone: http://192.168.2.11:31011/eureka/ 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和对应ConfigMap的name参数。
#Actuator Configmanagement: server: port: 8081 endpoint: restart: enabled: true health: show-details: always endpoints: web: exposure: include: "*"#Base Configserver: port: 8080spring: application: name: springboot-admin-demo cloud: kubernetes: reload: enabled: true mode: polling period: 5000 strategy: refresh monitoring-secrets: true config: enabled: true enableApi: true sources: - namespace: mydlqcloud #Namespace 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。
import de.codecentric.boot.admin.server.config.EnableAdminServer;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication@EnableDiscoveryClient@EnableAdminServerpublic class Application {
public static void main(String[] args) { SpringApplication.run(Application.class, args); }
}四、构建 Docker 镜像
由于我们是将 SpringBoot Admin Server 部署到 Kubernetes 环境下,所以我们这里将上面的示例项目构建成 Docker 镜像,然后推送到镜像仓库,方便后续部署到 Kubernetes 环境下。
1、执行 Maven 编译
首先执行 Maven 命令,将项目编译成一个可执行 JAR。
$ mvn clean install2、准备 Dockerfile
创建构建 Docker 镜像需要的 Dockerfile 文件,放置到项目根目录中,将 Maven 编译的 JAR 复制到镜像内部,然后设置三个变量,分别是:
- JVM_OPTS 设置一些必要的 JVM 启动参数。
- JAVA_OPTS: Java JVM 启动参数变量,这里需要在这里加一个时区参数。
- APP_OPTS: Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数。
Dockerfile:
FROM openjdk:8u222-jre-slimVOLUME /tmpADD target/*.jar app.jarRUN sh -c 'touch /app.jar'ENV JVM_OPTS="-Xss256k -XX:MaxRAMPercentage=80.0 -Duser.timezone=Asia/Shanghai -Djava.security.egd=file:/dev/./urandom"ENV JAVA_OPTS=""ENV APP_OPTS=""ENTRYPOINT [ "sh", "-c", "java $JVM_OPTS $JAVA_OPTS -jar /app.jar $APP_OPTS" ]3、构建与推送 Docker 镜像
执行 Docker Build 命令构建 Docker 镜像,等待镜像构建完成后,执行 Docker push 命令,将镜像推送到镜像仓库。
# 构建镜像$ docker build -t mydlqclub/springboot-admin-server:0.0.1 .
# 推送镜像$ 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
apiVersion: v1kind: ServiceAccountmetadata: name: springboot-admin namespace: mydlqcloud---kind: ClusterRoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata: name: springboot-adminsubjects: - kind: ServiceAccount name: springboot-admin namespace: mydlqcloudroleRef: kind: ClusterRole name: cluster-admin apiGroup: rbac.authorization.k8s.io(2)、在 Kubernetes 中部署应用配置 RBAC
-n:创建应用到指定的 Namespace 中。
$ kubectl apply -f admin-rbac.yaml -n mydlqcloud2、创建应用配置 ConfigMap
(1)、创建 ConfigMap 部署文件
创建 application-configmap.yaml 配置文件,将示例项目中 application.yml 配置文件中的配置项复制到 ConfigMap 中。
admin-configmap.yaml
kind: ConfigMapapiVersion: v1metadata: name: springboot-admindata: application.yaml: |- #log config logging: path: /opt/logs/ #eureka config eureka: instance: prefer-ip-address: true instance-id: ${spring.cloud.client.ip-address}:${server.port} client: service-url: #defaultZone: http://192.168.2.11:31011/eureka/ 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 中。
$ kubectl apply -f admin-configmap.yaml -n mydlqcloud3、创建 SpringBoot Admin 的 Kubernetes 部署文件
(1)、创建 SpringBoot Admin 部署文件
admin-server.yaml
apiVersion: v1kind: Servicemetadata: name: springboot-admin-serverspec: type: NodePort ports: - name: server nodePort: 31083 port: 8080 targetPort: 8080 - name: management nodePort: 31084 port: 8081 targetPort: 8081 selector: app: springboot-admin-server---apiVersion: apps/v1kind: Deploymentmetadata: name: springboot-admin-server labels: app: springboot-admin-serverspec: replicas: 1 selector: matchLabels: app: springboot-admin-server template: metadata: name: springboot-admin-server labels: app: springboot-admin-server spec: serviceAccountName: springboot-admin containers: - name: springboot-admin-server image: mydlqclub/springboot-admin-server:0.0.1 #imagePullPolicy: Always ports: - name: server containerPort: 8080 - name: management containerPort: 8081 resources: limits: memory: 1024Mi cpu: 1000m requests: memory: 1024Mi cpu: 1000m 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 volumeMounts: - name: log mountPath: /opt/logs volumes: - name: log hostPath: type: DirectoryOrCreate path: /data/apps/logs(2)、在Kubernetes 中部署应用
-n:创建应用到指定的 Namespace 中。
$ 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 界面。

