系统环境
- Kubernetes 版本:1.5.3
- SpringBoot Admin 版本:2.1.6
- SpringCloud 版本:Greenwich.SR2
- SpringCloud Kubernetes 版本:1.0.2.RELEASE
参考地址
- 示例 Github 地址:https://mirrors.infvie.org/blog-example/springcloud/springboot-admin-demo
一版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! 、概念简介
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.infviecloud:8080/eureka/,
http://eureka-1.eureka.infviecloud:8080/eureka/,
http://eureka-2.eureka.infviecloud:8080/eureka/
2、配置中心
在 SpringCloud 微服务框架中,我们需要一个配置中心来管理整个微服务的配置,并且实现动态刷新配置。
我们常用的做法是部署 SpringCloud Config 组件,但是由于 SpringCloud Config 需要将
由于 SpringCloud 各个组件和服务都是部署在 Kubernetes 环境下,而 Kubernetes 自己也有个配置管理的 ConfigMap。考虑到这点 SpringCloud 也有 SpringCloud Kubernetes Config项目,可以从 ConfigMap 动态读取配置信息,只要 Kubernetes 整个集群不宕机,那么配置就可以得到保障,这是目前比较推荐的组件。
关于如何使用 SpringCloud Kubernetes Config 完成动态配置,之前文章中也有写,需要了解的可以查看下。当然,如果你使用不是该组件,而是另一款比较流行的配置中心 Apollo 也是可以的。
使用 SpringCloud Kubernetes Config 配置中心非常简单,只需要:
- (1)、SpringBoot 项目 Maven 引入 spring-cloud-starter-kubernetes-conf
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! ig 组件。 - (2)、SpringBoot 项目 Maven 引入 spring-boot-starter-actuator 组件,并开启 management.endpoint.restart.enabled 选项。
- (3)、将 SpringBoot 项目中的 Application.yml 配置内容存入 ConfigMap。
- (4)、Spring
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! Boot 项目中的 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: ConfigMap
apiVersion: v1
metadata:
name: springcloud-zuul-config
data:
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 Config
management:
server:
port: 8081
endpoint:
restart:
enabled: true
#Read ConfigMap Config
server:
port: 8080
spring:
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: infviecloud
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.infvie</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 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.infviecloud:8080/eureka/,http://eureka-1.eureka.infviecloud:8080/eureka/,http://eureka-2.eureka.infviecloud: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 Config
management:
server:
port: 8081
endpoint:
restart:
enabled: true
health:
show-details: always
endpoints:
web:
exposure:
include: "*"
#Base Config
server:
port: 8080
spring:
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: infviecloud #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
@EnableAdminServer
public 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 install
2、准备 Dockerfile
创建构建 Docker 镜像需要的 Dockerfile 文件,放置到项目根目录中,将 Maven 编译的 JAR 复制到镜像内部,然后设置三个变量,分别是:
- JVM_OPTS 设置一些必要的 JVM 启动参数。
- JAVA_OPTS: Java JVM 启动参数变量,这里需要在这里加一个时区参数。
- APP_
版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作! OPTS: Spring 容器启动参数变量,方便后续操作时能通过此变量配置 Spring 参数。
Dockerfile:
FROM openjdk:8u222-jre-slim
VOLUME /tmp
ADD target/*.jar app.jar
RUN 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 infvieclub/springboot-admin-server:0.0.1 .
# 推送镜像
$ docker push infvieclub/springboot-admin-server:0.0.1
五、Kubernetes 部署 SpringBoot Admin
1、创建应用权限 RBAC
(1)、创建 RBAC 部署文件
由于程序需要读取 ConfigMap 中的配置,需要一定的权限,这里提前创建一个 RBAC 对象来供程序绑定以获取读取的权限,下面是 RBAC 对象的部署文件。
- 注意:需要修改下面的全部 Namespace 参数为你自己 Kubernetes 集群的 Namespace 名称。
admin-rbac.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: springboot-admin
namespace: infviecloud
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: springboot-admin
subjects:
- kind: ServiceAccount
name: springboot-admin
namespace: infviecloud
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
(2)、在 Kubernetes 中部署应用配置 RBAC
-n:创建应用到指定的 Namespace 中。
$ kubectl apply -f admin-rbac.yaml -n infviecloud
2、创建应用配置 ConfigMap
(1)、创建 ConfigMap 部署文件
创建 application-configmap.yaml 配置文件,将示例项目中 application.yml 配置文件中的配置项复制到 ConfigMap 中。
admin-configmap.yaml
kind: ConfigMap
apiVersion: v1
metadata:
name: springboot-admin
data:
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.infviecloud:8080/eureka/,http://eureka-1.eureka.infviecloud:8080/eureka/,http://eureka-2.eureka.infviecloud:8080/eureka/
(2)、在 Kubernetes 中部署应用配置 ConfigMap
-n:创建应用到指定的 Namespace 中。
$ kubectl apply -f admin-configmap.yaml -n infviecloud
3、创建 SpringBoot Admin 的 Kubernetes 部署文件
(1)、创建 SpringBoot Admin 部署文件
admin-server.yaml
apiVersion: v1
kind: Service
metadata:
name: springboot-admin-server
spec:
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/v1
kind: Deployment
metadata:
name: springboot-admin-server
labels:
app: springboot-admin-server
spec:
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: infvieclub/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 infviecloud
六、测试部署的应用接口
将 SpringBoot Admin 部署到 Kubernetes 后,我们可以通过访问在部署文件中配置的 Service 的 NodePort 端口 31083 ,且 Kubernetes 集群地址为 192.168.2.11。所以输入地址:http://192.168.2.11:31083 访问 Admin UI 界面。