spring cloud/mesos:在mesos上运行spring cloud config配置服务

施俊明
2023-12-01

之前已经说明如何在mesos上运行eureka服务发现,下面介绍如何在mesos上运行spring cloud config配置服务,并将配置服务注册到eureka上。eureka客户端注册服务时使用主机名,也可以通过spring cloud的配置eureka.instance.prefer-ip-address: true指定使用IP地址,配置服务默认注册到erueka上的是docker的主机名(没有指定主机名,一般显示的为docker容器的ID),如果配置eureka.instance.prefer-ip-address: true则显示docker容器的IP,而这些信息对于其他服务是没法使用的(因为mesos不支持docker的网络配置,除非使用docker swarm on mesos,但目前它不是成熟产品),由于访问mesos上运行docker容器使用的都是主机的IP,我们需要通过eureka.instance.ip-address属性指定配置服务的IP。

1 创建maven项目

spring cloud使用的版本是Brixton.M5,docker-maven-plugin使用的版本是0.4.1。

<?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>

    <groupId>com.szss.genisys</groupId>
    <artifactId>config</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>config</name>
    <description>spring cloud config</description>

    <parent>
        <groupId>com.szss.genisys</groupId>
        <artifactId>genisys-parent</artifactId>
        <version>1.0.0-SNAPSHOT</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-config-server</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>

        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>${docker.plugin.version}</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

2 创建配置服务

程序入口:

@SpringBootApplication
@EnableEurekaClient
@EnableConfigServer
public class ConfigApplication {

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

resources/bootstrap.xml:

---
spring:
  profiles: native
  cloud:
    config:
      server:
        native:
          search-locations: classpath:/config

eureka:
  instance:
    prefer-ip-address: true
    metadata-map:
      instanceId: ${spring.application.name}:${random.value}
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://${eureka.username:zcg}:${eureka.password:123456}@localhost:8761/eureka/

---
spring:
  profiles: mesos
  cloud:
    config:
      server:
        git:
          uri: https://github.com/zhuchuangang/spring-cloud-genisys-repo.git

eureka:
  instance:
    prefer-ip-address: true
    ip-address: ${HOST}
    metadata-map:
      instanceId: ${spring.application.name}:${random.value}
  client:
    fetch-registry: true
    register-with-eureka: true
    service-url:
      defaultZone: http://${eureka.username:zcg}:${eureka.password:123456}@${eureka.peer01.host}:${eureka.peer01.port}/eureka/
      replicasZone: http://${eureka.username:zcg}:${eureka.password:123456}@${eureka.peer02.host}:${eureka.peer02.port}/eureka/

注意:ip-address: ${HOST} 此处的配置是引用mesos的环境变量HOST,HOST的值是主机的IP地址,通过这个设置覆盖docker容器的IP地址,让服务可以直接通过主机IP访问。eureka.peer01.host和eureka.peer01.port通过mesos环境变量指定。


resources/application.yml:
info:
  name: config-service
  version: ${project.version}

spring:
  profiles:
    active: native
  application:
    name: config

server:
  port: 8888

security:
  user:
    name: zcg
    password: 123456

注意:此处默认激活的是native配置,只做开发使用,后面会通过mesos环境变量开启其他配置。


docker/Dockerfile:

#使用daocloud的java8镜像
FROM daocloud.io/library/java:8
#镜像创建人
MAINTAINER zcg
#附加卷
VOLUME /tmp
#添加jar包
ADD config-1.0.0-SNAPSHOT.jar app.jar
#修改jar包日期
RUN bash -c "touch app.jar"
#运行app,并指定端口号
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -jar /app.jar --server.port=$PORT0

注意:此处没有使用EXPOSE指定暴露端口,而是使用spring boot的程序参数server.port来设置端口号,$PORT0为mesos的环境变量,表示分配给容器的一组主机端口号中的第一个,这样可以让容器内部的端口号和主机端口号保持一致。

3 打包镜像

需要事先准备docker环境,进入docker命令行,在项目目录下执行mvn package命令,打包maven项目,同时生成该程序的镜像。

将镜像推送到registry服务上,本过程不再累述。如何在mesos运行docker registry请参看文章http://blog.csdn.net/zhuchuangang/article/details/51286308

4 在mesos上运行配置服务

环境准备:mesos/marathon/docker的安装和环境配置请参考http://blog.csdn.net/zhuchuangang/article/details/51043864
在marathon上执行下面代码:

{
    "id":"config",
    "cpus":1,
    "mem":256,
    "instances":1,
    "container":{
        "type":"DOCKER",
        "docker":{
            "network":"BRIDGE",
            "image":"172.16.120.136:31000/config",
            "portMappings":[
                {
                    "containerPort":0,
                    "hostPort":31888,
                    "servicePort":0,
                    "protocol":"tcp",
                    "name":"http"
                }
            ]
        }
    },
    "env":{
        "spring.profiles.active":"mesos",
        "eureka.peer01.host":"172.16.120.137",
        "eureka.peer01.port":"31761",
        "eureka.peer02.host":"172.16.120.138",
        "eureka.peer02.port":"31762"
    },
    "healthChecks":[
        {
            "protocol":"HTTP",
            "path":"/health",
            "portIndex":0,
            "gracePeriodSeconds":300,
            "intervalSeconds":60,
            "timeoutSeconds":20,
            "maxConsecutiveFailures":3
        }
    ]
}

配置详解:

"portMappings":[
                {
                    "containerPort":0,
                    "hostPort":0,
                    "servicePort":0,
                    "protocol":"tcp",
                    "name":"http"
                }
            ]

hostPort、containerPort设为0表示容器内部端口号和主机端口号保持一致并且随机分配,hostPort端口号取值范围为31000~32000。

"env":{
        "spring.profiles.active":"mesos",
        "eureka.peer01.host":"172.16.120.137",
        "eureka.peer01.port":"31761",
        "eureka.peer02.host":"172.16.120.138",
        "eureka.peer02.port":"31762"
    }

通过环境变量spring.profiles.active开启application.yml文件中mesos配置。

有关marathon端口配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51167845

有关marathon约束配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51147967

有关marathon健康检查配置请参考:http://blog.csdn.net/zhuchuangang/article/details/51120177

 类似资料: