Spring cloud + Swarm mode 实战二:部署微服务

原创 2017年09月29日 17:30:58

简介

将基于spring cloud的微服务架构应用于docker swarm mode,基本系统结构图:

所需基础知识

  • docker、docker compose、docker machine
  • docker swarm mode
  • spring cloud

环境简介

  • 三台CentOS7 VM:reg(192.168.245.137)、docker1(192.168.245.139)、docker2(192.168.245.140)
  • Win7:安装了dockertoolbox,使用docker-machine管理三台docker宿主机

工程实例

swarm-spring-cloud-test

docker-machine管理三台VM

在win7的“Docker Quickstart Terminal”中分别执行以下命令:

docker-machine -D create -d generic --generic-ip-address=192.168.245.137 --engine-registry-mirror=https://registry.docker-cn.com reg --engine-insecure-registry=myrepo.com:5000

docker-machine -D create -d generic --generic-ip-address=192.168.245.139 --engine-registry-mirror=https://registry.docker-cn.com docker1 --engine-insecure-registry=myrepo.com:5000

docker-machine -D create -d generic --generic-ip-address=192.168.245.140 --engine-registry-mirror=https://registry.docker-cn.com docker2 --engine-insecure-registry=myrepo.com:5000

说明:

  • 如果创建过程很慢,请手动在三台机子上安装docker后,再执行上述命令进行关联。
  • 使用Docker中国官方镜像加速
  • 使用http模式下的私有仓库
  • 创建成功后,使用docker info 查看Registry Mirrors和Insecure Registries是否配置成功。

创建集群

切换到reg

eval $(docker-machine env reg)

初始化reg为管理节点:

docker swarm init

查看工作节点的join-token

docker swarm join-token worker  

加入工作节点:

docker-machine ssh docker1 docker swarm join --token SWMTKN-1-0yuuj2o7mi6gzcy54u6ayhqwr0989u2cb3xbswbc94k4pmcqmi-48q7mw60esyl18ttgwo07t870 192.168.245.137:2377

docker-machine ssh docker2 docker swarm join --token SWMTKN-1-0yuuj2o7mi6gzcy54u6ayhqwr0989u2cb3xbswbc94k4pmcqmi-48q7mw60esyl18ttgwo07t870 192.168.245.137:2377

查看节点:

$ docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
aom77kgv9y530n63c6schlebl     docker2             Ready               Active
h6p4tp2uozk2xd2bwpnue05pl *   reg                 Ready               Active              Leader
te527c08gqbipwhdcv8aa3bab     docker1             Ready               Active

集群已创建成功。

制作镜像,存入私有仓库

为什么使用私有仓库

因为在创建service时,swarm manager会下发task到各个node上去执行,这样每个node都会去pull相同的镜像,重复操作,如果使用外网会很耗时间,所以必须先搭建私服。

本文中使用的镜像都是预先pull后再push到私有仓库的

1.制作基础镜像

Dockerfile:

FROM openjdk:8-jre-alpine

# Install base packages
RUN apk update && apk add curl bash tree tzdata \
    && cp -r -f /usr/share/zoneinfo/Hongkong /etc/localtime \
    && echo -ne "Alpine Linux 3.6 image. (`uname -rsv`)\n" >> /root/.built

# Install dockerize
RUN apk add --no-cache openssl
ENV DOCKERIZE_VERSION v0.5.0
RUN wget https://github.com/jwilder/dockerize/releases/download/$DOCKERIZE_VERSION/dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && tar -C /usr/local/bin -xzvf dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz \
    && rm dockerize-alpine-linux-amd64-$DOCKERIZE_VERSION.tar.gz

# Define bash as default command
CMD ["/bin/bash"]

添加常用工具,修正时区,dockerize(容器启动检测),构建镜像并存入私服:

docker build -t myrepo.com:5000/openjdk:dockerize .
docker push myrepo.com:5000/openjdk:dockerize

2.高可用服务注册发现及配置中心

使用jhipster-registry进行搭建,详介请看:http://www.jhipster.tech/jhipster-registry/

cd /swarm-spring-cloud-test/jhipster-registry:

mvmw package
docker build -f src/main/docker/Dockerfile -t myrepo.com:5000/jhipster-registry:3.1.2 .
docker push myrepo.com:5000/jhipster-registry:3.1.2

关键配置项:

通过服务发现的方式使用Config Server,请参考:spring_cloud_config_client中的“Discovery First Bootstrap”描述。

eureka:
    instance:
        instance-id: ${HOSTNAME:}:${spring.cloud.client.ipAddress}:${server.port} #swarm集群中对应 [容器短ID]:[overlay IP]:[port]
        prefer-ip-address: true
        metadataMap: #客户端通过服务发现的方式获取Config server服务后,会使用这些参数来获取应用配置信息
            configPath: /config
            user: admin
            password: admin
    server:
        enable-self-preservation: false
        eviction-interval-timer-in-ms: 15000
    client:
        fetch-registry: true
        register-with-eureka: true
        serviceUrl:
            defaultZone: ${ADDITIONAL_EUREKA_SERVER_LIST} #不写死,通过compose file的 Enviroment传递

spring:
    application:
        name: jhipster-registry
    profiles:
        active: docker
        include: native
    cloud:
        config:
            server:
                git:
                    uri: https://github.com/jhipster/jhipster-registry-sample-config
                native:
                    search-locations: ${NATIVE_SEARCH_LOCATIONS}
                prefix: /config
                bootstrap: true
            fail-fast: true

2.服务提供者

cd /swarm-spring-cloud-test/sc-service:

mvmw package
docker build -t myrepo.com:5000/sc-service .
docker push myrepo.com:5000/sc-service

关键配置项:

bootstrap-docker.yml:

eureka:
    client:
        serviceUrl:
            defaultZone: ${EUREKA_SERVER_ADDRESS}

spring:
    application:
      name: bookservice
    cloud:
        config:
            fail-fast: true
            discovery: #通过服务发现的方式获取应用配置
              enabled: true
              serviceId: jhipster-registry
            username: admin #与config server的eureka.instance.metadataMap.user实际上重复了,使用一种即可
            password: admin #与config server的eureka.instance.metadataMap.password实际上重复了,使用一种即可
            name: bookservice #配置文件名及profile,对应bookservice-docker.yml
            profile: docker

application-docker.yml:

server:
    port: 8091

eureka:
    client:
        enabled: true
        fetch-registry: true
        register-with-eureka: true
        registry-fetch-interval-seconds: 10
    instance:
        prefer-ip-address: true
        instanceId: ${HOSTNAME:}:${spring.cloud.client.ipAddress}:${server.port}
        lease-renewal-interval-in-seconds: 5
        lease-expiration-duration-in-seconds: 10

3.服务消费者

cd /swarm-spring-cloud-test/sc-web:

mvmw package
docker build -t myrepo.com:5000/sc-web .
docker push myrepo.com:5000/sc-web

部署服务栈

1.创建overlay网络

docker network create -d overlay --subnet 10.0.3.0/24  springcloud-overlay

注意:指定了子网段,用于服务注册时网卡的选择,具体请看之后的“关键问题描述”

2.部署高可用服务注册发现及配置中心

cd /swarm-spring-cloud-test/sc-compose中执行:

$ docker stack deploy -c registry.yml registry

$ docker stack services registry
ID                  NAME                 MODE                REPLICAS            IMAGE                                     PORTS
k56bh2zvtt4i        registry_registry1   replicated          1/1                 myrepo.com:5000/jhipster-registry:3.1.2   *:8761->8761/tcp
ubg8l6fkvgcy        registry_registry3   replicated          1/1                 myrepo.com:5000/jhipster-registry:3.1.2   *:8763->8761/tcp
xswokdol6auk        registry_registry2   replicated          1/1                 myrepo.com:5000/jhipster-registry:3.1.2   *:8762->8761/tcp

启动成功,http随意访问reg,docker1,docker2的8761端口,都能看到eureka1有两个副本eureka2,eureka3。同理访问8762和8763,都能看到其他两个副本,说明高可用成功部署。

2.服务提供者和消费者

cd /swarm-spring-cloud-test/sc-compose中执行:

$ docker stack deploy -c demoweb.yml demoweb

$ docker stack services demoweb
ID                  NAME                  MODE                REPLICAS            IMAGE                        PORTS
ncule9r38qor        demoweb_web           replicated          1/1                 myrepo.com:5000/sc-web       *:8090->8090/tcp
xo6wgnegs1sh        demoweb_bookservice   replicated          3/3                 myrepo.com:5000/sc-service   *:8091->8091/tcp 

访问:http://192.168.245.137:8090/,ctrl+F5不断刷新,注意观察container的短ID,可以看到已经负载均衡到了所有的demoweb_bookservice

部署集群管理工具

使用portainer+visualizer,提供web界面方式对集群进行管理。

cd /swarm-spring-cloud-test/sc-compose中执行:

$ docker stack deploy -c management.yml manage

$ docker stack services manage
ID                  NAME                MODE                REPLICAS            IMAGE                              PORTS
glnh3ddq73he        manage_viz          replicated          1/1                 myrepo.com:5000/visualizer         *:8080->8080/tcp
jrnuxyr700mh        manage_portainer    replicated          1/1                 myrepo.com:5000/portainer:1.14.2   *:9000->9000/tcp

viz:

portainer:

portainer相关配置

添加远程docker主机的endpoints

由于是在manager节点上启动,所以当前只能管理manager节点,需要添加其他远程节点。在“Endpoints ”中,添加其他远程docker主机,注意“TLS ”的配置,使用win7上的docker machine客户端证书,位置:C:\Users\Administrator.docker\machine\certs

参考:Protect the Docker daemon socket

添加私有仓库

“Registries”中可以添加私有仓库,由于私有仓库使用protus进行鉴权,所以认证部分需要填写protus认证用户。


附加注意事项:

.dockerignore:

build镜像时,docker client会将当前上下文全部发送到docker daemon,可以通过.dockerignore忽略不必要的内容,如:

*
!target/*.war
!target/*.jar

容器启动顺序的问题

参考:

Better Docker experience with Dockerize

dockerize

使用dockerize工具,在启动容器时,对依赖容器进行连通性测试。之前已经安装到基础镜像,如:

version: '3'
services:
  web:
    image: ${REG_SLA:-myrepo.com/}sc-web${TAG_COL}
    command: dockerize -wait http://eureka:8761 -wait http://bookservice:8091 -timeout 10s ...
    deploy:
      restart_policy:
        condition: on-failure
        delay: 3s
        max_attempts: 2
...

配合修改重启策略,默认会一直不停重启。

在compose file中使用环境变量

如镜像使用了环境变量及三元表达式:

image: ${REG_SLA:-myrepo.com:5000/}sc-web${TAG_COL}

在执行compose file前,先设置环境变量:

export TAG_COL=:v0.1 

如果是environment中的变量,则可以在当前目录下创建.env文件(默认读.env,可以通过env_file指定)

.env:

EUREKA_SERVER_ADDRESS=http://admin:admin@registry1:8761/eureka/,http://admin:admin@registry2:8761/eureka/,http://admin:admin@registry3:8761/eureka/

限制容器的资源使用

deploy:
  resources:
    limits:
      cpus: '0.2'
      memory: 100M
    reservations:
      cpus: '0.1'
      memory: 50M

滚动更新

deploy:
  update_config:
    parallelism: 1
    delay: 10s

性能监控

可以使用cAdvisor+InfluxDB+Grafana搭建一个简单的swarm性能监控平台:

  • cAdvisor用来分析运行中的Docker容器的资源占用以及性能特性的工具。用来收集swarm节点性能数据保存到infuxdb中.
  • InfuxDB是一个开源分布式时序数据库, 用来保存性能数据.
  • Grafana性能绘图仪表盘工具, 读取Influxdb性能数据,绘图展示.

日志监控

可以使用elk

使用maven插件构建镜像并push到私有仓库

参考:
使用docker-maven-plugin插件实现Docker构建并提交到私有仓库

注册服务的实例id配置

eureka.instanceId.instanceId: HOSTNAME:{spring.cloud.client.ipAddress}:${server.port}

方便查看,swarm集群中的注册服务的信息:

  • ${HOSTNAME}:容器短ID
  • spring.cloud.client.ipAddress{server.port}:集群中网络地址(如使用的网络:springcloud-overlay)

关键问题描述:

在swarm mode 集群中,所有服务都挂接到自定义的overlay网络上,但是在服务注册到eureka的时候,会出现服务A注册到eureka时候,有些服务A的实例使用ingress网络地址,有些服务A的实例使用自定义的overlay网络地址。使用ingress网络地址的服务A实例不能被其他服务访问,例如:

[10.255.0.17:10.255.0.17:8091][10.255.0.16:10.255.0.16:8091][0fba7e6f8db1:10.0.2.11:8091]
  • 10.255.xx.xx的是ingress网络地址,不能被其他服务访问
  • 10.0.2.xx的是自创的overlay网络地址,可以被其他服务访问

原因:

如果服务对外公布了端口,那么服务就会被挂接到ingress网络,因此服务会使用有多个网卡(ingress的,自定义网络的),所以在服务注册时,需要指定使用的网卡(或通过网段)来确保服务的可访问性。

解决方案:

1.创建overlay网络时,指定网段:

 docker network create -d overlay --subnet 10.0.3.0/24  springcloud-overlay

2.微服务指定网段:

eureka.instance.prefer-ip-address=true
spring.cloud.inetutils.preferred-networks=10.0.3

相同的问题:

https://stackoverflow.com/questions/43903496/swarm-networking-and-spring-cloud-apps

参考:

jhipster-registry

Dockerfile reference

Compose file version 3 reference

Docker Swarm运行Spring Cloud应用(二):Eureka高可用

Spring Cloud Eureka 多网卡配置最终版

Docker Swarm 和Swarm mode 是两个概念!!

有了新的功能强大、简单易用的Swarm mode集群,基本就不需要老的Docker Swarm主机集群了。两个概念一定要区分开!使用Docker machine create 命令自带的--swarm...
  • CSDN_duomaomao
  • CSDN_duomaomao
  • 2017年06月21日 23:35
  • 2036

Swarm mode(Docker第二代swarm)实验

1、实验环境 1)三台虚拟(Ubuntu14.04) 2)Docker版本 v-1.12.1 3)三台虚拟机的ip分别是:192.168.110.132(manager)、192.168.110.13...
  • xuguokun1986
  • xuguokun1986
  • 2016年09月07日 17:23
  • 2318

Swarm mode环境模型-小结篇

环境准备:1)搭建一个swarm mode集群环境 root@docker1:/home/docker/xu/swarm# docker node ls ID ...
  • xuguokun1986
  • xuguokun1986
  • 2017年01月04日 12:19
  • 1577

docker-docker swarm mode 的技术性总结

趁着五一长假闲着,今天起床后,决定写点东西,想了想,就总结一下自己的过去一段时间里学习docker swarm mode 的一些知识。 swarm(集群)是docker容器的的一个很重要的功能,可以...
  • u012979009
  • u012979009
  • 2017年05月01日 09:44
  • 418

搭建Docker Swarm集群实战(三)(swarm mode)

前言docker在1.12版本之后,把swarm的功能内置到docker engine本身,因此之前使用consul等第三方服务发现和键值服务的方法就可以作古了。这篇就是用docker自带的swarm...
  • leon_wzm
  • leon_wzm
  • 2017年10月07日 19:45
  • 405

几种常见的微服务架构方案——ZeroC IceGrid、Spring Cloud、基于消息队列、Docker Swarm

微服务架构是当前很热门的一个概念,它不是凭空产生的,是技术发展的必然结果。虽然微服务架构没有公认的技术标准和规范草案,但业界已经有一些很有影响力的开源微服务架构平台,架构师可以根据公司的技术实力并结合...
  • broadview2006
  • broadview2006
  • 2017年07月25日 11:31
  • 1616

开始试用docker的swarm模式

开始试用docker的swarm模式docker 1.12以及之后的版本集成了swarmkit等编排服务,现在docker的版本为1.12-rc2版本。本文来尝试试用此种模式建立原生的docker集群...
  • shenshouer
  • shenshouer
  • 2016年06月21日 15:05
  • 13015

jhipster学习心得

Jhipster初识本文基于自己根据jhipster的初次接触,write down下一些笔记心得,以及一些操作步骤。一、Jhipster介绍1.大神语录 一个代码生成器而已 核心是Spring Bo...
  • dongfangyihaolan
  • dongfangyihaolan
  • 2016年05月15日 10:07
  • 11236

Java全栈开发框架JHipster,Java架构师必读

  • 2017年08月17日 14:22
  • 10.04MB
  • 下载

JHipster使用前的环境配置-JHipster学习(一)

JHipster使用前的环境配置-JHipster学习(一)JHipster或者称Java Hipster,是一个应用代码产生器,能够创建Spring Boot + AngularJS + Boots...
  • u014604691
  • u014604691
  • 2016年07月15日 15:42
  • 3936
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spring cloud + Swarm mode 实战二:部署微服务
举报原因:
原因补充:

(最多只允许输入30个字)