Kubernetes / Linux Note / 运维笔记

Kubernetes (七) SpringCloud Admin Eureka 监控微服务

Einic Yeo · 9月15日 · 2019年 · · · · ·

系统环境

  • 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

一、概念简介

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 功能

常见的功能如下:

  • 显示健康状况
  • 显示详版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!细信息,例如
    • 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 需要将配置存放于 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: 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 引入版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!相关依赖

<?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: 日志配置信息版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!,如果不设置 loggging.path 参数,那么 SpringBoot Admin UI 中不能查看到应用的日志信息。

(2)、配置文件 bootstrap.yml

这里主要是设置 SpringCloud Kub版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!ernetes 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_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 后,我们可以通过访问在部署文件中配置的 版权声明:本文遵循 CC 4.0 BY-SA 版权协议,若要转载请务必附上原文出处链接及本声明,谢谢合作!Service 的 NodePort 端口 31083 ,且 Kubernetes 集群地址为 192.168.2.11。所以输入地址:http://192.168.2.11:31083 访问 Admin UI 界面。

0 条回应