简介

通过springboot 搭建微服务项目,使用docker容器化部署,通过maven插件,结合maven命令,实现打包、生成镜像、推送到私有镜像仓库功能。

微服务项目

搭建

docker swarm部署springboot项目 docker部署springboot微服务_docker

pom.xml文件配置

项目代码比较简单,如上图所示,只需在项目pom.xml文件添加docker插件

<plugin>
				<groupId>com.spotify</groupId>
				<artifactId>docker-maven-plugin</artifactId>
				<version>1.0.0</version>
				<configuration>
					<serverId>xl-docker-registry</serverId>
					<imageName>192.168.5.217:5000/${project.parent.artifactId}/${project.artifactId}:v${project.version}</imageName>
					<!--docker文件所在的目录-->
					<dockerDirectory>docker</dockerDirectory>
					<dockerHost>http://192.168.5.217:2375</dockerHost>
					<resources>
						<resource>
							<targetPath>/</targetPath>
							<directory>${project.build.directory}</directory>
							<include>${project.build.finalName}.jar</include>
						</resource>
					</resources>
				</configuration>
	</plugin>

settings.xml配置

<server>
		  <id>xl-docker-registry</id>
		  <username>admin</username>
		  <password>Harbor12345</password>
		  <configuration>
			<email>147293059@qq.com</email>
		  </configuration>
</server>

DockerFile

# 指定基础镜像 openjdk
FROM openjdk:8
# 维护作者信息
MAINTAINER docker-demo rom date UTC by Asia/Shanghai "C.X.L"
# 设置环境变量
ENV TZ Asia/Shanghai
# 暴露镜像端口
EXPOSE 8099
# 指定挂载目录
VOLUME /data/log/docker/docker-demo
# VOLUME /tmp/tomcat
ARG JAR_FILE
# 将本地文件添加到容器中
COPY docker-demo-*.jar docker-demo.jar
#提供容器运行的默认命令
ENTRYPOINT ["java","-Xms256m","-Xmx1g","-Xss256k","-Djava.security.egd=file:/dev/./urandom","-jar","/docker-demo.jar"]

推送镜像至私服

docker基础使用、harbor镜像私服搭建以及idea集成docker等等相关知识请参考我之前写的博客:
Docker容器虚拟化技术

maven命令

搭建完环境之后就可以愉快的使用maven命令,实现打包、生成镜像、推送到私有镜像仓库功能了;

## 通过dockerfile构建镜像
mvn docker::build
## 将镜像推至harbor镜像私服
mvn docker::push

idea插件

当然也可以使用idea插件构建、推送镜像

docker swarm部署springboot项目 docker部署springboot微服务_负载均衡_02


docker swarm部署springboot项目 docker部署springboot微服务_负载均衡_03

问题排查

  1. Exception caught: denied: requested access to the resource is denied

    解决: 需在私有仓库建立好对应的项目,或者将构建好的镜像通过docker tag 打好对应项目的镜像,再推送至私服
docker tag 192.168.5.217:5000/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT 192.168.5.217:5000/xl/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT

项目启动

docker run

## 停止运行的容器
docker stop docker-demo
## 删除旧容器
docker rm docker-demo
##删除本地旧镜像
docker rmi 192.168.5.217:5000/xl/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT
##拉取项目最新镜像并运行容器
docker run -d --restart=always --name docker-demo -v /data/log/docker/docker-demo:/data/log/docker/docker-demo
 -p 8099:8099 -e TZ="Asia/Shanghai" 192.168.5.217:5000/xl/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT

Docker-Compose

version: '3'
services:
  docker-demo:
    image:  192.168.5.217:5000/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT
    container_name: docker-demo
    restart: always
    ports:
    - 8099:8099
    volumes:
    - /data/log/docker/docker-demo:/data/log/docker/docker-demo
    environment:
      - "TZ=Asia/Shanghai"
networks:
  demo-net:
    driver: overlay

运行容器

## 停止容器
docker-compose down
##删除本地旧镜像
docker rmi 192.168.5.217:5000/xl/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT
##拉取项目最新镜像并运行容器
docker-compose pull & docker-compose up -d

集群部署

通过docker-swarm实现docker集群,若对docker-swarm还不了解的可以参考我之前写的博客:Docker-Swarm

初始化管理节点

master 192.168.150.128

node1 192.168.150.129

node2 192.168.150.136

docker swarm部署springboot项目 docker部署springboot微服务_DNS_04


docker swarm部署springboot项目 docker部署springboot微服务_DNS_05


提前在各个节点均已拉取了docker-demo 镜像

创建3个docker-demo微服务集群

将镜像tag修改为xl/docker-demo:v1.0.0-SNAPSHOT

docker tag 192.168.5.217:5000/xl/spring-boot-starter-parent/docker-demo:v1.0.0-SNAPSHOT xl/docker-demo:v1.0.0-SNAPSHOT

在master节点中创建overlay网络

docker network create -d overlay demo-net

docker swarm部署springboot项目 docker部署springboot微服务_docker_06

创建服务

docker service创建服务

docker service create  --name docker-demo --network demo-net -p 8100:8099  --mount=type=bind,src=/data/log/docker/docker-demo,dst=/data/log/docker/docker-demo  -e TZ="Asia/Shanghai" --replicas 3 xl/docker-demo:v1.0.0-SNAPSHOT

docker swarm部署springboot项目 docker部署springboot微服务_DNS_07


docker swarm部署springboot项目 docker部署springboot微服务_DNS_08

docker stack创建服务

docker-compose.yml
version: '3'
services:
  docker-demo:
    image:   xl/docker-demo:v1.0.0-SNAPSHOT
    container_name: docker-demo
    restart: always
    ports:
    - 8099:8099
    volumes:
    - /data/log/docker/docker-demo:/data/log/docker/docker-demo
    environment:
      - "TZ=Asia/Shanghai"
    deploy:
	    replicas: 3
networks:
  demo-net:
    driver: overlay
运行
docker stack deploy docker-demo -c docker-compose.yml
查看stack服务运行情况。执行如下命令:
docker stack services docker-demo

docker swarm部署springboot项目 docker部署springboot微服务_微服务_09


docker swarm部署springboot项目 docker部署springboot微服务_微服务_10

测试

docker swarm部署springboot项目 docker部署springboot微服务_微服务_11


docker swarm部署springboot项目 docker部署springboot微服务_DNS_12


docker swarm部署springboot项目 docker部署springboot微服务_spring boot_13


docker swarm部署springboot项目 docker部署springboot微服务_DNS_14

Docker Swarm 负载均衡详解

  • Swarm模式内置DNS组件,可以自动为集群中的每个服务分配DNS记录。
  • Swarm manager使用内部负载均衡,根据服务的DNS名称在集群内的服务之间分发请求。
  • Swarm manager使用 ingress load blancing暴露你想从外部访问集群提供的服务。
  • Swarm manager自动为服务分配一个范围30000-32767端口的Published Port,也可以为该服务指定一个Published Port。

ingress network是一个特殊的overlay网络,便于服务的节点直接负载均衡。当任何swarm节点在已发布的端口上接收到请求时,它将该请求转发给调用的IPVS模块,IPVS跟踪参与该服务的所有容器IP地址,选择其中一个,并通过ingress network将请求路由给它。

docker swarm部署springboot项目 docker部署springboot微服务_docker_15

Docker Swarm 负载均衡模式选择

负载均衡有两种模式:VIP、DNSRR

  • VIP:分配独立的虚拟IP,DNS记录解析到服务名中作为代理IP。
  • dnsrr:DNS记录不解析VIP,而去解析每个容器内的IP。dnsrr模式不支持端口对外暴露。

管理节点:通过查看服务详细信息筛选当前模式负载均衡模式

docker service inspect  docker-demo|grep 'EndpointSpec' -C10

docker swarm部署springboot项目 docker部署springboot微服务_spring boot_16


注:当前模式为VIP模式

管理节点:设置DNS轮询模式

docker service update --endpoint-mode dnsrr docker-demo

推荐使用VIP模式
基于DNS负载均衡存在如下问题:

  • 某些应用程序将DNS主机名缓存 到IP地址映射,这会导致应用程序在映射更改时超时。
  • 具有非零DNS ttl值 会导致DNS条目反映最新的详细信息时,发生延迟。

基于VIP的负载均衡克服了基于DNS负载均衡的一些问题
在这种方法中,每个服务都有一个虚拟IP地址,并且该IP地址映射到与该服务关联的多个容器的IP地址。在这种情况下,与服务关联的服务IP不会改变,即使与改服务关联的容器死亡并重新启动。

Docker Swarm 负载均衡模扩展知识

可在容器Swarm负载均衡之上在建立一层负载均衡。HAProxy可代理工作节点端暴露的端口进行再次代理,做到双层负载均衡的作用。保证高可用与大规模的应用。

docker swarm部署springboot项目 docker部署springboot微服务_微服务_17