本文学习前提: Java, Spring Boot, Docker, Spring Cloud
一, 准备工作
1.1 安装 Docker 环境
这一部分请参考我的另一篇文章《ASP.NET Core on Docker》, 本文不再赘述. 需要注意的是, 如果你是 Windows 想要安装 Docker,Docker for Windows 需要 64bit Windows 10 Pro, 且需要开启 Hyper-V. 如果你不想开启 Hyper-V, 而又事先安装了 VMware Workstation, 可以参考晓晨的《Docker for Windows 使用 VMware Station》.
1.2 准备 Java 镜像
(1)拉取 java 镜像
- # docker pull java => 默认为最新版本的镜像
- # docker pull java:8 => 标签为 8 的 java 镜像版本
(2)查看 java 镜像
# docker images java
PS:java 镜像有点大啊, 643MB
二, 部署 Spring Boot 微服务到 Docker
2.1 Spring Boot 示例准备
这里以一个 spring boot 应用程序: eureka-service 来介绍, 它是基于 spring cloud eureka 的一个服务注册与发现的微服务应用程序, 你可以从这里获取其源码.
2.2 快速借助 Dockerfile 部署到 Docker
(1)使用 Maven 打包项目: 执行下面的命令, 将其构建成 jar 包
MVN> mvn clean package
(2)在 jar 包所在目录, 创建 Dockerfile 文件, 并添加以下内容
- # 基于 Java8 镜像
- FROM java:8
- # 将本地文件夹挂在到当前容器
- VOLUME /tmp
- # 复制文件到容器
- ADD eureka-service-sn-0.0.1-SNAPSHOT.jar app.jar
- RUN bash -c 'touch /app.jar'
- # 声明需要暴露的端口
- EXPOSE 9000
- # 配置容器启动后执行的命令
- ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
(3)通过 FTP 工具将 jar 包和 Dockerfile 文件一起传送到服务器端, 然后通过 Shell 工具登录并跳转到这个目录下, 执行以下命令打包镜像:
# docker build -t edc/discovery-service-eureka:0.0.1 . => 不要忘记这里有个 .
# docker images => 可以看到在 Java8 的镜像基础之上, 针对 eureka-service 的镜像已准备好
(4)启动镜像:
# docker run --name eureka-service -d -p 8761:8761 edc/service-discovery-eureka:0.0.1
(5)验证是否已成功启动: 访问 http://docker 宿主机 IP:8761/, 可以正常显示 Eureka Server 首页.
三, 使用 Docker Compose 编排微服务
3.1 Docker Compose 简介
在实际的微服务架构中, 一般包含很多个微服务, 而且每个微服务都会部署多个实例, 如果每个微服务都需要手动启停, 那么效率会很低下, 维护量也会很大.
Compose 是一个用于定义和运行多容器的 Docker 应用程序的工具, 非常适合在开发, 测试, 构建 CI 工作流等场景.
Compose 的安装请参考:
安装后验证如下:# docker-compose --version
PS: 我这里使用的 Compose 版本是 1.22.0
3.2 Docker Compose 快速入门示例
首先, 我们来了解下使用 Compose 的 3 个基本步骤:
使用 Dockerfile(或其他方式)定义应用程序环境, 以便于在任何地方重现该环境
在 docker-compose.yml 文件中定义组成应用程序的服务, 以便各个服务在一个隔离的环境中一起运行
运行 docker-compose up 命令, 启动并运行整个应用程序
其次, 我们仍然以上面的 eureka-service 为例, 来快速实践一下 Compose 的基本步骤:
(1)打包 eureka-service, 同上, 不再赘述
(2)创建 Dockerfile 文件, 同上, 不再赘述
(3)在 Dockerfile 同一路径下创建 docker-compose.yml, 并添加以下内容:
- version: '3'
- services:
- eureka: # 指定服务的名称
- build: . # 指定 Dockerfile 所在路径, 注意这里是个 .
- ports:
- - "8761:8761" # 指定端口映射, 类似 docker run 的 - p 选项, 注意使用字符串形式
(4)通过 FTP 工具将 jar 包, dockerfile 以及 docker-compose.yml 一同拷贝到 docker 宿主机指定文件夹中
(5)在这个目录下执行以下命令, 启动容器.
# docker-compose up
PS: 也可以使用 docker-compose up -d 来通过后台运行的方式启动并运行这些容器
(6)验证容器是否成功启动: 访问 http://docker 宿主机 IP:8761/, 可以正常显示 Eureka Server 首页.
最后, 说说 Docker Compose 将所管理的容器分为三层, 分别是工程 (Project), 服务(Service) 以及容器 (Container).Docker Compose 运行目录下的所有文件(docker-compose.yml,extends 文件或环境变量文件等) 组成一个工程(默认为 docker-compose.yml 所在目录的目录名称). 一个工程可以包含多个服务, 每个服务定义了容器运行的镜像, 参数和依赖, 一个服务可以包括多个容器实例.
对应上图中的名称, 工程名称是 eureka-service(对应 docker 宿主机上的目录名称), 该工程包含了 1 个服务, 服务名称是 eureka. 当执行 docker-compose up 命令时, 启动了 eureka 服务的 1 个容器实例 eureka_1.
3.3 Docker Compose 编排 Spring Cloud 微服务
这里仍然会采用在 2.1 节提到的部分示例来 (详情请参见 github 的 part5 部分) 演示, 将要编排的微服务列表如下表所示:
微服务项目名称 | 项目微服务中的角色 |
eureka-service | 服务发现 & amp; 注册组件 |
zuul-service | API 网关 |
user-service | 服务提供者 |
movie-service | 服务提供者 |
(1)分别通过 maven 打成 jar 包, 不再赘述.
PS: 可以通过使用 maven 插件来构建 docker 镜像, 需要在 pom.xml 添加一些内容, 这里不阐述, 有兴趣的可以百度一下. 此外, 由于 Docker 默认网络模式是 bridge, 各个容器的 IP 都不相同, 因此如果在服务提供者的配置文件中设置了 http://localhost:8761/eureka / 会无法满足要求. 这时, 我们可以为 Eureka Server 所在容器配置一个主机名(例如 discover), 并让各个微服务使用主机名来访问 Eureka Server. 所以, 这里讲所有微服务关于 Eureka 地址的配置改为如下内容:
- eureka:
- client:
- serviceUrl:
- defaultZone: http://discovery:8761/eureka/
(2)依次进行 build 打包 docker 镜像, 这里仍然借助 dockerfile, 即每个微服务一个 dockerfile
(3)编写 docker-compose.yml 文件
- version: '3'
- services:
- # 指定服务名称
- eureka-service:
- # 指定服务所使用的的镜像, 后续不再赘述
- image: edc/eureka-service:0.0.1
- # 暴露端口信息
- ports:
- - "8761:8761"
- zuul-service:
- image: edc/zuul-service:0.0.1
- # 连接到 eureka-service, 这里使用的是 SERVICE:ALIAS 的形式
- links:
- - eureka-service:discovery
- user-service:
- image: edc/user-service:0.0.1
- links:
- - eureka-service:discovery
- movie-service:
- image: edc/movie-service:0.0.1
- links:
- - eureka-service:discovery
(4)执行以下命令启动项目
# docker-compose up -d
PS: 这里加上了 - d, 表示后台运行, 否则你的整个屏幕都是日志输出...
最终效果如下图所示:
3.4 Docker Compose 编排高可用的 Eureka Server
针对 Eureka Server, 实现高可用的话, 也可以通过 Compose 来编排 Eureka Server 集群(比如一个 2 个节点的高可用最小规模集群).
首先, 需要针对 Eureka Service 的配置文件进行改造, 以便通过同样的配置属性就可以实现两个节点的配置, 这里仍然使用 2.1 节中的 github 中的示例(参见 part1 部分). 下面是 eureka-service-ha-1 的配置项, eureka-service-ha-2 同理, 不再赘述.
- spring:
- application:
- name: eureka-service-ha-1
- ---
- spring:
- # profile=peer1
- profiles: peer1
- server:
- port: 8761
- eureka:
- instance:
- # when profile=peer1, hostname=peer1
- hostname: peer1
- client:
- service-url:
- # register self to peer2
- defaultZone: http://peer2:8762/eureka
- ---
- spring:
- # profile=peer2
- profiles: peer2
- server:
- port: 8762
- eureka:
- instance:
- # when profile=peer2, hostname=peer2
- hostname: peer2
- client:
- service-url:
- # register self to peer1
- defaultZone: http://peer1:8761/eureka
从上面的配置文件中, 两个节点是通过 spring.profiles.active 来区分配置属性的.
然后, 再来编写一个针对高可用 eureka server 的 docker-compose.yml 文件:
- version: '3'
- services:
- # 指定服务名称
- eureka-service-ha-1:
- hostname: peer1 # 指定 hostname
- image: edc/eureka-service-ha:0.0.1-SNAPSHOT
- links:
- - eureka-service-ha-2 # 注册到另一个 eureka-service 中
- ports:
- - "8761:8761"
- environment:
- - spring.profiles.active=peer1
- # 指定服务名称
- eureka-service-ha-2:
- hostname: peer2 # 指定 hostname
- image: edc/eureka-service-ha:0.0.1-SNAPSHOT
- links:
- - eureka-service-ha-1 # 注册到另一个 eureka-service 中
- ports:
- - "8762:8762"
- environment:
- - spring.profiles.active=peer2
其他步骤如 3.3 所述, 这里不再进行演示.
3.5 Docker Compose 编排可伸缩的微服务
这里仍然以 3.3 中的 movie-service 为例, 执行以下命令来达到微服务节点的扩展(这里从 1 个节点变为 2 个节点):
# docker-compose scale movie-service=2
从上图可以看出, movie-service 实例已从 1 个变为了 2 个.
同理, 要伸缩为 1 个节点, 只需要将 2 改为 1 即可, 不再赘述.
四, 小结
本文极简地介绍了如何通过借助 dockerfile 的方式部署一个 spring boot 应用程序到 docker,docker compose 的快速入门示例以及如何通过 docker compose 编排 spring cloud 微服务应用程序, 还介绍了实现编排高可用 eureka server 以及可伸缩的微服务的实现思路. 关于 docker 与 docker compose, 还有许许多多的内容, 其官方文档已经写得非常详细, 并对常见的问题也已经有了很多详细的总结, 大家可以参见: https://doc.docker.com/compose/faq/ 浏览. 此外, 十分感谢本文参考资料周立老师著的《Spring Cloud 与 Docker 微服务架构实战(第二版)》, 带我快速入门 Spring Cloud 的世界, 谢谢!
来源: https://www.cnblogs.com/edisonchou/p/springboot_on_docker_foundation.html