Spring cloud + Swarm mode 实战二:部署微服务
来源:互联网 发布:2014matlab中对角矩阵 编辑:程序博客网 时间:2024/06/07 22:20
简介
将基于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:5000docker-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:5000docker-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:2377docker-machine ssh docker2 docker swarm join --token SWMTKN-1-0yuuj2o7mi6gzcy54u6ayhqwr0989u2cb3xbswbc94k4pmcqmi-48q7mw60esyl18ttgwo07t870 192.168.245.137:2377
查看节点:
$ docker node lsID HOSTNAME STATUS AVAILABILITY MANAGER STATUSaom77kgv9y530n63c6schlebl docker2 Ready Activeh6p4tp2uozk2xd2bwpnue05pl * reg Ready Active Leaderte527c08gqbipwhdcv8aa3bab docker1 Ready Active
集群已创建成功。
制作镜像,存入私有仓库
为什么使用私有仓库
因为在创建service时,swarm manager会下发task到各个node上去执行,这样每个node都会去pull相同的镜像,重复操作,如果使用外网会很耗时间,所以必须先搭建私服。
本文中使用的镜像都是预先pull后再push到私有仓库的
1.制作基础镜像
Dockerfile:
FROM openjdk:8-jre-alpine# Install base packagesRUN 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 dockerizeRUN apk add --no-cache opensslENV DOCKERIZE_VERSION v0.5.0RUN 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 commandCMD ["/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 packagedocker 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 packagedocker 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: 8091eureka: 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 packagedocker 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 registryID NAME MODE REPLICAS IMAGE PORTSk56bh2zvtt4i registry_registry1 replicated 1/1 myrepo.com:5000/jhipster-registry:3.1.2 *:8761->8761/tcpubg8l6fkvgcy registry_registry3 replicated 1/1 myrepo.com:5000/jhipster-registry:3.1.2 *:8763->8761/tcpxswokdol6auk 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 demowebID NAME MODE REPLICAS IMAGE PORTSncule9r38qor demoweb_web replicated 1/1 myrepo.com:5000/sc-web *:8090->8090/tcpxo6wgnegs1sh 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 manageID NAME MODE REPLICAS IMAGE PORTSglnh3ddq73he manage_viz replicated 1/1 myrepo.com:5000/visualizer *:8080->8080/tcpjrnuxyr700mh 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:
方便查看,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=truespring.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 多网卡配置最终版
- Spring cloud + Swarm mode 实战二:部署微服务
- Spring cloud + Swarm mode 实战一:portus/harbor部署镜像私有仓库
- Docker Swarm mode 微服务部署及调用
- Spring Cloud实战(二):微服务集成-ZUUL
- 部署微服务:Spring Cloud vs. Kubernetes
- 部署微服务:Spring Cloud vs. Kubernetes
- 部署微服务:Spring Cloud vs. Kubernetes
- Spring Cloud微服务
- spring cloud 微服务
- Docker Swarm 集群 微服务部署
- 《Spring Cloud与Docker微服务架构实战》内容介绍
- Spring Cloud实战(四):微服务质量监控-Hystrix仪表盘
- 《疯狂Spring Cloud微服务架构实战》电子书
- Kubernetes和Spring Cloud哪个部署微服务更好?
- Kubernetes和Spring Cloud哪个部署微服务更好?
- Kubernetes和Spring Cloud哪个部署微服务更好?
- Kubernetes和Spring Cloud哪个部署微服务更好?
- Kubernetes和Spring Cloud哪个部署微服务更好?
- 使用eclipse 制作javadoc 文档
- 个人笔记6
- CentOS安装微软雅黑,解决drawImage中文乱码问题
- Gym
- @RequestMapping注解的用法
- Spring cloud + Swarm mode 实战二:部署微服务
- EmptyRecyclerView 数据为空时显示指定view
- select动态添加option与动态设置下拉框默认选项(selected)的问题(原创)
- Genymotion配置和安装
- IP协议的主要特点与格式
- 20170929在stm32f103zet6 RTT上扩展外部SRAM
- iOS开发 ☞ 关于带系统导航栏坐标的问题
- 20行代码能干嘛?
- Android中建造者(builder)模式