基于Eureka搭建Springcloud微服务-19.使用rancher管理docker和Kubernetes

lingwh原创2020年7月24日大约 8 分钟约 2316 字

19.使用rancher管理docker和Kubernetes

19.1.章节内容概述

本章节涉及主要内容有:
 19.1.章节内容概述
 19.2.章节内容大纲
 19.3.使用rancher管理docker
 19.4.使用rancher管理Kubernetes
具体每个小节中包含的内容可使通过下面的章节内容大纲进行查看。

19.2.章节内容大纲

19.3.使用rancher管理docker

19.3.1.搭建rancher

在192.168.0.4上搭建rancher

详细参考-> 搭建rancher

19.3.2.搭建用于测试使用rancher管理docker的微服务

19.3.2.1.模块简介

测试持续集成微服务到docker中使用到的微服务

19.3.2.2.模块目录结构

springcloud-ci-docker-rancher80
|-- docker
|   •-- Dockerfile
|-- src
|   •-- main
|       |-- java
|       |   •-- org
|       |       •-- openatom
|       |           •-- springcloud
|       |               |-- config
|       |               |   •-- VirtualIpConfig.java
|       |               |-- controller
|       |               |   •-- CiDockerRancherController.java
|       |               •-- CiDockerRancher80.java
|       •-- resources
|           |-- application.yml
|           •-- logback-custom.xml
•-- pom.xml

19.3.2.3.创建模块

在父工程(springcloud-eureka)中创建一个名为springcloud-ci-docker-rancher80的maven模块,注意:当前模块创建成功后,在父工程pom.xml中<modules></modules>中会自动生成有关当前模块的信息

19.3.2.4.编写模块pom.xml

<?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">
    <parent>
        <artifactId>springcloud-eureka</artifactId>
        <groupId>org.openatom</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>springcloud-ci-docker-rancher80</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <docker.registry.uri>192.168.0.5:5000</docker.registry.uri>
        <docker.registry.username>admin</docker.registry.username>
        <docker.registry.password>123456</docker.registry.password>
        <docker.host>tcp://192.168.0.4:2375</docker.host>
        <!--设置当前服务端口-->
        <docker.container.port>80</docker.container.port>
        <!--docker容器端口映射-->
        <docker.port.mapping>${docker.container.port}:${docker.container.port}</docker.port.mapping>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!--引入公共的工程-->
        <dependency>
            <groupId>org.openatom</groupId>
            <artifactId>springcloud-api-commons</artifactId>
        </dependency>
        <dependency>
            <groupId>net.logstash.logback</groupId>
            <artifactId>logstash-logback-encoder</artifactId>
        </dependency>
    </dependencies>

    <!--热部署需要加这个-->
    <build>
        <finalName>${project.artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <!--把当前插件repackage命令和maven的package绑定-->
                        <id>repackage-original</id>
                        <phase>package</phase>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <fork>true</fork>
                    <addResources>true</addResources>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <configuration>
                    <encoding>UTF-8</encoding>
                    <delimiters>
                        <delimiter>@</delimiter>
                    </delimiters>
                    <useDefaultDelimiters>false</useDefaultDelimiters>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-antrun-plugin</artifactId>
                <executions>
                    <execution>
                        <id>del-jar</id>
                        <phase>clean</phase>
                        <configuration>
                            <tasks>
                                <!-- 这是将当前模块下的target下的jar包删除-->
                                <delete file="docker/${build.finalName}.jar"/>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>copy-jar</id>
                        <phase>install</phase>
                        <configuration>
                            <tasks>
                                <!-- 这是将当前模块下的target下的jar包copy到当前模块根目录下docker目录中-->
                                <copy todir="docker" file="target/${build.finalName}.jar"></copy>
                            </tasks>
                        </configuration>
                        <goals>
                            <goal>run</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>io.fabric8</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <configuration>
                    <dockerHost>${docker.host}</dockerHost>
                    <removeMode>true</removeMode>
                    <!--
                        harbor镜像仓库认证配置
                        注意:不管是harbor中是公开项目还是私密项目,这个配置都要加,不加无法push成功
                    -->
                    <authConfig>
                        <username>${docker.registry.username}</username>
                        <password>${docker.registry.password}</password>
                    </authConfig>
                    <images>
                        <image>
                            <!--显示日志的时候-->
                            <!--<alias>spring-cloud-eureka</alias>-->
                            <!--如果只给docker本地镜像库中推送,格式为 命名空间/项目名称:tags名称,示例:项目artifactId/模块artifactId-->
                            <!--<name>${project.parent.artifactId}/${project.name}</name>-->
                            <!--
                                如果要同时给私服中推送,格式为 registry的ip:命名空间/项目名称:tags名称,示例:私服的ip:项目artifactId/模块artifactId
                                也可将registry单独写在下面
                            -->
                            <!--<name>镜像名称:${docker.registry}/${project.parent.artifactId}/${project.name}</name>-->
                            <name>${project.parent.artifactId}/${project.name}:latest</name>
                            <registry>${docker.registry.uri}</registry>
                            <!--定义镜像构建行为-->
                            <build>
                                <!-- 指定dockerfile文件的位置-->
                                <dockerFile>${project.basedir}/docker/Dockerfile</dockerFile>
                            </build>
                            <!-- 定义容器启动行为-->
                            <run>
                                <!--设置容器名,可采用通配符-->
                                <containerNamePattern>${project.parent.artifactId}_${project.build.finalName}</containerNamePattern>
                                <!--设置端口映射-->
                                <ports>
                                    <port>${docker.port.mapping}</port>
                                </ports>
                            </run>
                        </image>
                    </images>
                    <buildArgs>
                        <!--docker私服地址-->
                        <DOCKER_REGISTRY_URL>${docker.registry.uri}</DOCKER_REGISTRY_URL>
                    </buildArgs>
                </configuration>
                <executions>
                    <!--如果想在项目install时构建镜像添加-->
                    <execution>
                        <id>build-image</id>
                        <phase>install</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                    <!--如果想在项目install时构建镜像添加-->
                    <execution>
                        <id>tag-image</id>
                        <phase>install</phase>
                        <goals>
                            <goal>tag</goal>
                        </goals>
                    </execution>
                    <!--如果想在项目install时推送镜像到私服添加-->
                    <execution>
                        <id>push-image</id>
                        <phase>install</phase>
                        <goals>
                            <goal>push</goal>
                        </goals>
                    </execution>
                    <!--如果想在项目install时推送镜像到私服后删除并docker中本地build的镜像添加-->
                    <execution>
                        <id>remove-image</id>
                        <phase>install</phase>
                        <goals>
                            <goal>remove</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
        <!--打包多环境-->
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <!--引入所需环境的配置文件-->
                <filtering>true</filtering>
                <includes>
                    <include>application.yml</include>
                    <include>*.xml</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

19.3.2.5.编写模块配置文件

application.yml
server:
  port: 80 #访问端口
spring:
  devtools: #热部署开关
    restart:
      enabled: true

#配置文件修改说明-------------------------------------------------:开始
#注意:不同的部署环境需要修改的配置
#   1.${logback.path}  #修改日志存放位置,Linxu为/,Windows为\
#       修改原因: Linux和Windows目录结构不同
#配置文件修改说明-------------------------------------------------:结束

#自定义日志配置文件路径
logging:
  config: classpath:logback-custom.xml
  path: /logs #所有日志存放在位置,加上\方便Linux环境下配置
  level:
    root: info #全局日志输出级别

logback:
  log-name: springcloud-ci-docker-rancher80
  append: false #是否启用append(追加到已经存在日志文件尾部),true:重启项目会追加新日志到之前日志,false:重启项目会清空之前的日志
  immediate-flush: true #是否启用immediateFlush(立即刷新),true:重启项目自动追加,false:重启项目会情况之前的日志
  deploy-machine-ip: 192.168.0.5 #当前微服务所在部署机器ip

#logstash相关配置:开始
logstash:
  enable: true #默认为false
  host: 192.168.0.5:5044 # logstash地址
  index: '@project.parent.artifactId@' # es中index名称
#logstash相关配置:结束

logback-custom.xml
<?xml version="1.0" encoding="UTF-8"?>

<!--
    scan: 当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。
    scanPeriod: 设置监测配置文件是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。
    debug: 当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。
-->
<!-- 输出logback内部日志信息,每隔30s判断一下配置文件有没有更新,若更新,则重新加载 -->
<configuration scan="true" scanPeriod="30 seconds" debug="true">
    <!--从java代码中获取虚拟ip的值-->
    <!--获取当前微服务部署虚拟IP,如rancher为当前微服务分配的ip-->
    <define name="VIRTUAL_IP" class="org.openatom.springcloud.config.VirtualIpConfig"/>

    <!--从Spring容器中获取配置(Spring配置文件加载顺序:bootstrap.yml->logback.xml->application.yml)-->
    <!--获取当前微服务部署机器ip-->
    <springProperty name="MACHINE_IP" scope="context" source="logback.deploy-machine-ip"/>
    <!--应用名称-->
    <springProperty name="LOG_NAME" scope="context" source="logback.log-name"/>
    <!--是否启用append-->
    <springProperty name="IS_APPEND" scope="context" source="logback.append"/>
    <!--是否启用立即刷新-->
    <springProperty name="IS_IMMEDIATEFLUSH" scope="context" source="logback.immediate-flush"/>
    <springProperty name="LOG_PATH" scope="context" source="logging.path"/>
    <!--logstash地址-->
    <springProperty name="LOGSTASH_HOST" scope="context" source="logstash.host"/>
    <!--索引名称-->
    <springProperty name="INDEX_NAME" scope="context" source="logstash.index"/>


    <!-- name:变量的名称,可以随意起名,但建议名字要简明直译;value:变量的值;在配置文件中,我们可以用 ${} 的方式来使用,将变量引入到其他节点中去。-->
    <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度 %msg:日志消息,%n是换行符-->
    <!--控制台日志输出预选样式-->
    <property name="CONSOLE_LOG_PATTERN_1" value="%red(%d{yyyy-MM-dd HH:mm:ss.SSS}) %green([%thread]) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight(%-5level) %boldMagenta(%logger{10}): %cyan(%msg%n)"/>
    <property name="CONSOLE_LOG_PATTERN_2" value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} %highlight([%-5level]) %green(%logger) %msg%n"/>
    <property name="CONSOLE_LOG_PATTERN_3" value="%date{yyyy-MM-dd HH:mm:ss} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} Span-Export:%X{X-Span-Export:-}]  %green(%-5level) %boldMagenta(${PID:-}) -- [%+20thread] %cyan(%logger{20}) %line       : %msg%n"/>
    <!--文件中日志输出预选样式-->
    <property name="FILE_LOG_PATTERN_1" value="%d{yyyyMMdd:HH:mm:ss.SSS} [machineIp:${MACHINE_IP} virtualIp:${VIRTUAL_IP}] [TraceId:%X{X-B3-TraceId:-} SpanId:%X{X-B3-SpanId:-} [%thread] %-5level  %msg%n"/>

    <!--控制台日志输出格式-->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN_3}"/>
    <!--文件中日志输出格式-->
    <property name="FILE_LOG_PATTERN" value="${FILE_LOG_PATTERN_1}"/>
    <!--日志名称-->
    <!--定义默认日志输出级别-->
    <property name="LOG_OUTPUT_LEVEL" value="${LOG_LEVEL}" />
    <!--定义默认日志输出编码-->
    <property name="ENCODING" value="UTF-8" />

    <!-- 控制台输出:开始 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 用来设置日志的输入格式,使用“%+转换符”的方式,如果要输出”%”则必须使用”\”进行转义。-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!-- 格式化输出:https://logback.qos.ch/manual/layouts.html
                 %d 表示日期,
                 %thread 表示线程名,
                 %level 日志级别从左显示5个字符宽度,
                 %t 线程名
                 %file:%line 文件名+行号,
                 %m 日志消息,%n是换行符
                 %X{traceId}:自定义设置的参数,后面会说。
            -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>
    <!-- 控制台输出:结束 -->

    <!--输出到文件:开始-->
    <!-- 将项目本次运行INFO日志同步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.core.FileAppender">
        <!-- 过滤器,只记录 info 级别以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
        <file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-info.log</file>
        <!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
        <append>${IS_APPEND}</append>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 将项目本次运行INFO日志异步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="ASYNC-APPENDER-FILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-FILEAPPENDER-INFO" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>${IS_IMMEDIATEFLUSH}</neverBlock>
    </appender>

    <!-- 将项目本次运行DEBUG日志同步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.core.FileAppender">
        <!-- 过滤器,只记录 info 级别以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
        <file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-debug.log</file>
        <!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
        <append>${IS_APPEND}</append>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>true</immediateFlush>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 将项目本次运行DEBUG日志异步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="ASYNC-APPENDER-FILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-FILEAPPENDER-DEBUG" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>

    <!-- 将项目本次运行ERROR日志同步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.core.FileAppender">
        <!-- 过滤器,只记录 info 级别以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <!-- 写入的日志文件名,可以使相对目录也可以是绝对目录,如果上级目录不存在则自动创建 -->
        <file>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/${LOG_NAME}-error.log</file>
        <!-- 如果为true表示日志被追加到文件结尾,如果是false表示清空文件 -->
        <append>${IS_APPEND}</append>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>${IS_IMMEDIATEFLUSH}</immediateFlush>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 将项目本次运行ERROR日志异步输出到文件,会自动清空文件中上一次的日志 -->
    <appender name="ASYNC-APPENDER-FILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-FILEAPPENDER-ERROR" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>
    <!--输出到文件:结束-->


    <!--滚动输出到文件(按照天保存):开始-->
    <!-- 将项目本次运行INFO日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录 info 级别以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>false</immediateFlush>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件输出的文件名:
                %d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
                %i:自增数字
            -->
            <fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-info-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
            <!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
            <maxHistory>10</maxHistory>
            <!-- 文件大小超过100MB归档 -->
            <maxFileSize>20MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 将项目本次运行INFO日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-INFO" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>

    <!-- 将项目本次运行DEBUG日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录 info 级别以上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>false</immediateFlush>
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件输出的文件名:
                %d:可以包含一个Java.text.SimpleDateFormat指定的时间格式
                %i:自增数字
            -->
            <fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-debug-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
            <!-- 日志文件保存历史数量:控制保留的归档文件的最大数量,如果超出数量就删除旧文件 -->
            <maxHistory>10</maxHistory>
            <!-- 文件大小超过100MB归档 -->
            <maxFileSize>20MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>${ENCODING}</charset>
        </encoder>
    </appender>

    <!-- 将项目本次运行DEBUG日志异步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-DEBUG" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>

    <!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 过滤器,只记录error级别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--立即刷新,设置成false可以提高日志吞吐量-->
        <immediateFlush>false</immediateFlush>
        <!-- 每天生成一个日志文件,保存30天的日志文件 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!-- 日志文件输出的文件名:按天回滚 daily -->
            <fileNamePattern>${LOG_PATH}/${MACHINE_IP}/${VIRTUAL_IP}/HISTORY/${LOG_NAME}-error-%d{yyyy-MM-dd}-index%i.log</fileNamePattern>
            <!-- 日志文件保留天数 -->
            <maxHistory>10</maxHistory>
            <!-- 文件大小超过100MB归档 -->
            <maxFileSize>20MB</maxFileSize>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset>utf8</charset>
        </encoder>
    </appender>

    <appender name="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-ROLLINGFILEAPPENDER-ERROR" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>
    <!--滚动输出到文件(按照天保存):结束-->

    <!--输出到LOGSTASH:开始-->
    <!-- 将项目本次运行ERROR日志同步输出到文件,按照每天生成日志文件,会自动拼接上一次日志 -->
    <appender name="APPENDER-LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        <!--  logstash服务器地址-->
        <destination>${LOGSTASH_HOST}</destination>
        <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <pattern>
                        {
                        "appName":"${INDEX_NAME}",
                        "machineIp":"${MACHINE_IP}",
                        "virtualIp":"${VIRTUAL_IP}",
                        "serviceName":"${LOG_NAME}",
                        "timestamp": "%date{\"yyyy-MM-dd'T'HH:mm:ss,SSSZ\"}",
                        "logLevel":"%level",
                        "message":"%msg%n",
                        "traceId": "%X{X-B3-TraceId:-}",
                        "spanId": "%X{X-B3-SpanId:-}",
                        "spanExport": "%X{X-Span-Export:-}"
                        }
                    </pattern>
                </pattern>
            </providers>
        </encoder>
    </appender>
    <appender name="ASYNC-APPENDER-LOGSTASH" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="APPENDER-LOGSTASH" />
        <!-- 设置异步阻塞队列的大小,为了不丢失日志建议设置的大一些,单机压测时100000是没问题的,应该不用担心OOM -->
        <queueSize>10000</queueSize>
        <!-- 设置丢弃DEBUG、TRACE、INFO日志的阀值,不丢失 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 设置队列入队时非阻塞,当队列满时会直接丢弃日志,但是对性能提升极大 -->
        <neverBlock>true</neverBlock>
    </appender>
    <!--输出到logstash:结束-->

    <root>
        <!--输出到控制台-->
        <appender-ref ref="STDOUT"/>
        <!--异步非滚动输出到文件-->
        <appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-INFO"/>
        <appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-DEBUG"/>
        <appender-ref ref="ASYNC-APPENDER-FILEAPPENDER-ERROR"/>
        <!--异步滚动输出到文件-->
        <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-INFO"/>
        <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-DEBUG"/>
        <appender-ref ref="ASYNC-APPENDER-ROLLINGFILEAPPENDER-ERROR"/>
        <!--异步滚动输出到logstash-->
        <appender-ref ref="ASYNC-APPENDER-LOGSTASH"/>
    </root>
</configuration>

19.3.2.6.编写模块controller

package org.openatom.springcloud.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.openatom.springcloud.entities.CommonResult;
import org.openatom.springcloud.entities.Payment;


@RestController
public class CiDockerRancherController {

    @GetMapping("/ci/docker/rancher")
    public CommonResult<String> create(Payment payment) {
        return new CommonResult(200,"持续集成","测试持续集成到Docker+测试Racnehr");
    }

}

19.3.2.7.编写模块config

package org.openatom.springcloud.config;

import ch.qos.logback.core.PropertyDefinerBase;
import lombok.extern.slf4j.Slf4j;

import java.net.InetAddress;
import java.net.UnknownHostException;

@Slf4j
public class VirtualIpConfig extends PropertyDefinerBase {
    private static String virtualIp;
    static {
        try {
            virtualIp = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
            log.error("获取日志Ip异常", e);
            virtualIp = null;
        }
    }

    @Override
    public String getPropertyValue() {
        return virtualIp;
    }
}

19.3.2.8.编写模块主启动类

package org.openatom.springcloud;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class CiDockerRancher80 {
    public static void main(String[] args) {
        SpringApplication.run(CiDockerRancher80.class, args);
    }

}

19.3.2.9.编写模块Dockerfile

注意:需要先在 项目根目录/springcloud-ci-docker-rancher80下创建docker文件夹

#指定基础镜像,必须为第一个命令 FROM java:8 #用于指定持久化目录 VOLUME /software #维护者信息 MAINTAINER lingwh

将当前maven目录生成的文件复制到docker容器的/目录下

COPY ${project.build.finalName}.jar app.jar

指定docker容器启动时运行jar包

ENTRYPOINT ["java","-jar","/app.jar"]

### 19.3.3.配置rancher连接docker
    访问rancher->点击右下角切换语言处切换为中文环境

http://192.168.0.4:9003/

::: center
<div class="imgbg-customer">
<img src="../images/rancher-9003.png"  width="100%"/>
</div>
:::

    添加主机
```mermaid
flowchart LR
    访问rancher-->点击基础架构
    点击基础架构-->点击主机
    点击主机-->点击添加主机
    点击添加主机-->根据情况输入主机注册地址
    根据情况输入主机注册地址-->点击保存
在docker主机上注册rancher
上面步骤执行完成之后,复制弹出界面中第五步(将下列脚本拷贝到每一台主机上运行以注册 Rancher:)的代码到docker安装的主机上执行,执行完成后点击关闭按钮
sudo docker run --rm --privileged -v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/rancher:/var/lib/rancher rancher/agent:v1.2.11 \
http://192.168.0.4:9003/v1/scripts/9F1C7A21277B3BBB9357:1640908800000:wdp8qKpCKNvXMXY3IYsICf0ovk

19.3.4.配置rancher连接harbor使用的认证

镜像库信息
a.地址*
192.168.0.5:5000
b.用户名
admin
c.密码
123456

19.3.5.使用docker的maven插件推送镜像到harbor

启动相关服务
在项目根目录下执行打包命令
mvn clean install
在项目根目录下执行复制生成的jar包到指定位置
cp springcloud-ci-docker80/target/springcloud-ci-docker-rancher80.jar springcloud-ci-docker-rancher80/docker
在idea中打开docker的maven插件操作面板
制作Docker镜像并上传镜像到docker制作Docker镜像
点击docker:build

在harbor私服中创建springcloud-eureka项目
推送到harbor私服
点击docker:build->点击docker:push
登录harbor私服查看刚才推送上去的的服务
http://192.168.0.5:5000/harbor/projects
点击springcloud-eureka这个项目
可以看到当前模块微服务已经被推送到了harbor私服中

19.3.6.使用rancher管理docker容器

19.3.6.1.添加docker容器

访问rancher
http://192.168.0.4:9003/
添加容器
填写容器信息
a.名称
springcloud-ci-docker-rancher80
b.选择镜像*
192.168.0.5:5000/springcloud-eureka/springcloud-ci-docker-rancher80:latest
c.端口映射
公开主机端口 80
私有容器端口 80
协议 TCP
最后点击页面底部创建

19.3.6.2.测试使用rancher管理docker容器

浏览器访问
http://192.168.0.4/ci/docker/rancher
返回结果
{"code":200,"message":"持续集成","data":"测试持续集成到Docker+测试Racnehr"}

19.3.7.使用rancher对应用进行扩容

19.3.7.1.添加应用

访问rancher
http://192.168.0.4:9003/
添加应用
填写应用信息
a.名称
springcloud-eureka

进入界面后选择添加服务->填写容器信息
a.名称
springcloud-ci-docker-rancher80-plus
b.选择镜像*
192.168.0.5:5000/springcloud-eureka/springcloud-ci-docker-rancher80:latest
c.端口映射
特别注意: 这里不要配置端口映射

19.3.7.2.配置WebHooks

访问rancher
http://192.168.0.4:9003/
添加接收器
点击创建后来到如下界面,点击复制按钮即可获取扩容触发api

19.3.7.3.使用postman触发扩容

使用postman触发扩容(点击两次,注意:请求方式一定是post方式)
查看扩容效果
即可查看到应用已经扩容为三份,缩容不再演示,详细请参考扩容自动配置

19.3.7.4.为扩容后的应用添加负载均衡器

在刚才创建应用的时候,没有配置端口映射,外部是无法访问这个服务的,如果外部要访问这个服务,则要配置负载均衡器
在浏览器访问
http://192.168.0.4/ci/docker/rancher
返回结果
{"code":200,"message":"持续集成","data":"测试持续集成到Docker+测试Racnehr"}

19.3.7.5.查看扩容后每个节点的日志

19.3.7.5.1.在kibana为日志创建索引
访问kibana
http://192.168.0.5:5601/
为推送到ELK中的日志文件创建索引
注意:如果点击Discover没有显示日志,请确定ELK部署机器中的时区和时间是否正确,如果不正确,将时区和时间修改正确后再次启动项目,重新执行创建索引的操作,可以看到kibana中展示出来了推送到elk中日志
19.3.7.5.2.获取扩容后节点的ip
查看服务所有节点详细信息
可以看到扩容后所有节点的ip信息
19.3.7.5.3.查看日志
根据ip信息可以在kibana中过滤出不同节点的日志

19.3.7.6.为rancher设计扩容缩容算法

使用java程序触发rancher的扩容或缩容,如根据时间节点扩容缩容,8:00-12:00这个时间范围内扩容,12:00-20:00这个时间内缩容,这只是一种思路,其他的更复杂的扩容缩容算法请自行根据业务设计

19.4.使用rancher管理Kubernetes

上次编辑于: 2022/9/9 06:18:47
贡献者: lingwh
评论