docker+docker-compose搭建高可用集群
maven+docker+docker-compose搭建高可用集群
首先搭建eurake+gateway+client
eurake项目
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">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xx</groupId>
<artifactId>xx-eurake</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>${project.artifactId}</name>
<description>注册中心服务</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
<docker.image.prefix>xx</docker.image.prefix>
</properties>
<profiles>
<profile>
<id>dev</id>
<properties>
<profiles.active>dev</profiles.active>
</properties>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<id>test</id>
<properties>
<profiles.active>test</profiles.active>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<profiles.active>prod</profiles.active>
</properties>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<finalName>${project.name}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/classes</outputDirectory>
<resources>
<resource>
<directory>src/main/resources/profiles</directory>
<filtering>true</filtering>
<includes>
<include>${profiles.active}-bootstrap.yml</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>1.1.1</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 资源根目录排除各环境的配置,使用单独的资源目录来指定 -->
<excludes>
<exclude>profiles/*.yml</exclude>
</excludes>
</resource>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>bootstrap.yml</include>
<include>${profiles.active}-bootstrap.yml</include>
</includes>
</resource>
</resources>
</build>
</project>
- 这里面我用了一个dockerfile的插件,可以自动构建服务镜像的
Dockerfile内容如下:
FROM ascdc/jdk8
RUN mkdir -p /data /workspace
VOLUME ["/data"]
WORKDIR /workspace
ADD ./target/xx-eurake.jar app.jar
#RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Dport=8888","app.jar"]
EXPOSE 8888
eurake集群配置
bootstrap.yml:
server:
port: ${port}
spring:
application:
name: marketing-eurake
profiles:
active: @profiles.active@
eureka:
instance:
hostname: ${HOST_NAME}
prefer-ip-address: false
instance-id: ${eureka.instance.hostname}:${server.port}
appname: ${spring.application.name}
client:
#默认情况下,应用会向注册中心(也是它自己)注册它自己,设置为false表示禁止这种默认行为
register-withEureka: true
#表示不去检索其他的Eureka Server获取注册信息,因为服务注册中心本身的职责就是维护服务实例,它也不需要去检索其他服务
fetch-registry: false
service-url:
#对外暴露的地址
defaultZone: http://${EUREKA_SERVER_ADDRESS}:8888/eureka
registry-fetch-interval-seconds: 5
spring.cloud.vault.discovery:
enabled: true
service-id: my-server
spring.cloud.vault:
config.lifecycle.enabled: true
- eurake集群配置必要配置
eureka.instance.appname 必须等于 spring.application.name 并且不可缺省,所以直接占位符 appname: ${spring.application.name}
prefer-ip-address: 必须为false 或者缺省
fetch-registry 必须为false 或者缺省
register-withEureka 必须为true
service-url.defaultZone 必须互相注册(A<—>B)
启动后的状态结果必须为可用才行:
![paste image][image-1]
构建eurake镜像文件
两种方式,
命令行:
docker build -t xx/eurake:latest .
这种方式烦就烦在天天记命令。
maven 插件形式
mvn clean package docker:build
这种方式又回到了亲爱的maven构建方式了,插件的具体其它用法,可参见官网:
[docker-maven插件][1]
gateway项目
maven 的pom.xml同eurake
Dockfile
FROM ascdc/jdk8
RUN mkdir -p /data /workspace
VOLUME ["/data"]
WORKDIR /workspace
ADD ./target/xx-gateway.jar app.jar
#RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","-Dport=8888","app.jar"]
EXPOSE 8888
配置文件
server:
port: ${port}
spring:
application:
name: xx-gateway
cloud:
config:
uri: http://localhost:8761/
label: master
eureka:
instance:
hostname: ${HOST_NAME}
prefer-ip-address: true
instance-id: ${eureka.instance.hostname}:${server.port}
nonSecurePort: 80
client:
service-url:
defaultZone: http://${EUREKA_SERVER_ADDRESS}:8888/eureka
构建gateway镜像文件
mvn clean package docker:build
镜像文件构建完成后,查看一下:
docker images
![paste image][image-2]
使用docker-compose启动实例
安装这里就不说了,自己官网安装去。
新建一个目录,叫dockerCompose:
mkdir dockerCompose
进入目录,执行:
docker swarm init
后面的容器将会按照swarm模型核心去执行(注,docker-compose方式自建网络目录只支持swarm)
docker-compose.yml:
version: "3"
services:
eurake1:
# replace username/repo:tag with your name and image details
image: xx/eurake:latest
command: ifconfig
environment:
- EUREKA_SERVER_ADDRESS=190.100.0.3
- HOST_NAME=190.100.0.2
ports:
- "9001:8888"
networks:
app_net:
ipv4_address: 190.100.0.2
eurake2:
# replace username/repo:tag with your name and image details
image: xx/eurake:latest
environment:
- EUREKA_SERVER_ADDRESS=190.100.0.2
- HOST_NAME=190.100.0.3
ports:
- "9002:8888"
networks:
app_net:
ipv4_address: 190.100.0.3
gateway1:
# replace username/repo:tag with your name and image details
image: xx/gateway:latest
command: ifconfig
environment:
- EUREKA_SERVER_ADDRESS=190.100.0.2
- HOST_NAME=180.100.0.4
ports:
- "10001:8888"
networks:
app_net:
ipv4_address: 190.100.0.4
gatewa2:
# replace username/repo:tag with your name and image details
image: xx/gateway:latest
environment:
- EUREKA_SERVER_ADDRESS=190.100.0.2
- HOST_NAME=180.100.0.5
ports:
- "10002:8888"
networks:
app_net:
ipv4_address: 190.100.0.5
networks:
app_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 190.100.0.0/24
最后启动服务器容器:
docker-compose -f docker-compose.yml up -d
![paste image][image-3]
停止服务:
docker-compose down
![paste image][image-4]
其实如果不用docker-compose组建网络固定IP,用docker run的形式也是可以的,但是必须是这样:
自定义桥接网络(默认是bridge)
docker network create --subnet=172.100.0.0/16 xxNetwork
启动实例
docker run -itd --name xx-eurake1 --net xxNetwork --ip 172.100.0.1 -p 8888:8888 xx/eurake --eureka.instance.hostname=172.100.0.1 --eureka.client.serviceUrl.defaultZone=http://172.100.0.2:8888/eureka/
部署集群服务
- 建立一个管理虚机m1
docker-machine create –virtualbox-boot2docker-url=/Users/sam/boot2docker_iso/boot2docker.iso m1
- 建立两个node虚机w1,w2
docker-machine create –virtualbox-boot2docker-url=/Users/sam/boot2docker_iso/boot2docker.iso w1 w2
进入m1,初始化swarm
docker-machine ssh m1
docker swarm init –advertise-addr [m1主机的IP]
![paste image][image-5]
将w1,w2加入m1管理,组成一个小型集群
docker-machine ssh w1
docker swarm join –token SWMTKN-1-0pbw9ult7vdycem4db6436nyti716m33tak1rwg1iv6y2sfn1z-d92emox2ae1k1cqqjfc06o067 192.168.99.100:2377
最后,把docker-compose.yml copy到m1里,然后部署:
docker stack deploy --compose-file=stack-compose.yml [集群名称]
只需要以上步骤,Docker Swarm 会全自动地将所有服务以负载均衡的方式部署在不同的主机上,几乎不需要人工干预,通过以下命令可以在m1主机查看集群和服务的部署情况
docker stack ls
docker service ls
图形化界面查看集群
![集群图][image-6]
拓展服务的部署数量非常简单,只需在m1执行如下命令
docker service scale [需要拓展的服务]=3
删除部署
如果不希望保留集群,执行下面命令即可清理
docker stack rm [集群名称]
[1]: https://github.com/spotify/docker-maven-plugin#specify-build-info-in-the-pom
[image-1]: http://clockcoder.com/images/1532264970231dwup0qt6.png?imageslim
[image-2]: http://clockcoder.com/images/15322657678779h70jqhd.png?imageslim
[image-3]: http://clockcoder.com/images/1532267017830fi8hvn68.png?imageslim
[image-4]: http://clockcoder.com/images/1532267223066u7as2c1k.png?imageslim
[image-5]: http://clockcoder.com/images/1532275393584iwc3n9yv.png?imageslim
[image-6]: http://clockcoder.com/images/1532275823759kh2f47hu.png?imageslim