文章首发于公众号《程序员果果》
地址:https://mp.weixin.qq.com/s/E_gJFbRaWOE-mnVR1lsYfQ

一、简介

Docker的出现让容器化技术得以普及,更快的部署和维护与Spring Cloud的结合,能让我们不再像以前一样为了某一个模块的增加而服务器上大动干戈,还需要考虑环境的问题。在这一篇中会讲到 SpringCloud 项目 Docker 化 。

二、创建一个 SpringCloud 项目

创建一个springcloud项目 ,包含eureka-server、service-hi、service-ribbon。

1. eureka-server 项目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.gf</groupId> <artifactId>eureka-server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>eureka-server</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.gf</groupId> <artifactId>chapter02</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</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-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>application.yml

server: port: 8761eureka: client: register-with-eureka: false fetch-registry: false service-url: defaultZone: http://eureka-server:8761/eureka/spring: application: name: eureka-serverEurekaServerApplication

@EnableEurekaServer@SpringBootApplicationpublic class EurekaServerApplication { public static void main(String[] args) { SpringApplication.run(EurekaServerApplication.class, args); }}2. service-hi 项目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.gf</groupId> <artifactId>service-hi</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>service-hi</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.gf</groupId> <artifactId>chapter02</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</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-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>application.yml

server: port: 8763spring: application: name: service-hieureka: client: service-url: defaultZone: http://eureka-server:8761/eureka/ServiceHiApplication

@EnableEurekaClient@SpringBootApplication@RestControllerpublic class ServiceHiApplication { public static void main(String[] args) { SpringApplication.run(ServiceHiApplication.class, args); } @Value( "${server.port}" ) private String port; @GetMapping("/hi") public String hi() { return "hello , port is " + port; }}3. service-ribbon 项目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.gf</groupId> <artifactId>service-ribbon</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>service-ribbon</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.gf</groupId> <artifactId>chapter02</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build></project>application.yml

server: port: 8764spring: application: name: service-ribboneureka: client: service-url: defaultZone: http://eureka-server:8761/eureka/HelloService

@Servicepublic class HelloService { @Autowired private RestTemplate restTemplate; public String hiService() { return restTemplate.getForObject( "http://SERVICE-HI/hi" , String.class ); }}HelloControler

@RestControllerpublic class HelloControler { @Autowired private HelloService helloService; @GetMapping(value = "/hi") public String hi() { return helloService.hiService(); }}ServiceRibbonApplication

@SpringBootApplication@EnableEurekaClient@EnableDiscoveryClientpublic class ServiceRibbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceRibbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate() { return new RestTemplate(); }}三、构建镜像1. Dockerfile

编写Dockerfile ,把项目构建成镜像,需要把 项目jar包 复制到 镜像中,而且镜像中要有java的运行环境,所以现在给每个项目都创建一个Dockerfile,内容如下:

eureka-server 项目的 Dockerfile

FROM 192.168.31.143:9090/jdk/openjdk:8-jreMAINTAINER gf gf@163.comCOPY target/eureka-server-0.0.1-SNAPSHOT.jar /eureka-server-0.0.1-SNAPSHOT.jarENTRYPOINT ["java" , "-jar" , "/eureka-server-0.0.1-SNAPSHOT.jar"]

service-hi 项目的 Dockerfile

FROM openjdk:8-jreMAINTAINER gf 782969359@qq.comCOPY target/service-hi-0.0.1-SNAPSHOT.jar /service-hi-0.0.1-SNAPSHOT.jarENTRYPOINT ["java" , "-jar" , "/service-hi-0.0.1-SNAPSHOT.jar"]

service-ribbon 项目的 Dockerfile

FROM openjdk:8-jreMAINTAINER gf gf@163.comCOPY target/service-ribbon-0.0.1-SNAPSHOT.jar /service-ribbon-0.0.1-SNAPSHOT.jarENTRYPOINT ["java" , "-jar" , "/service-ribbon-0.0.1-SNAPSHOT.jar"]

分别在各个项目根目录下,通过 mvn packge 命令来,把项目打成jar包 ,并通过 docker build 命令来构建镜像:

mvn package -Dmaven.test.skip=true

docker build -t 项目名:版本号例如:docker build -t eureka-server:latest

我们通过 docker image 命令,查看我们本地的镜像,发现镜像已经构建到本地了:

$ docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEservice-ribbon latest 81b61a359e23 39 hours ago 487MBservice-hi latest f893c76be99d 39 hours ago 487MBeureka-server latest 41997de8006f 40 hours ago 487MBopenjdk 8-jre e01608fba686 12 days ago 442MB

根据这三个镜像运行容器 ,来检查服务容器化后 ,是否访问正常,值得注意的是 注册中心的地址为 http://eureka-server:8761/eureka/ ,我们使用容器名作为地址 ,这就需要,我们在启动eureka-server 的容器时,指定指定一个名称eureka-server ,否则会找不到注册中心。

docker run -it -d -p 8761:8761 --name eureka-server 41997de8006f

docker run -it -d --name service-hi f893c76be99d

docker run -it -d -p 8764:8764 --name service-ribbon 81b61a359e23

访问 127.0.0.1:8761 注册中心正常。

访问 127.0.0.1:8764/hi 服务正常。

欢迎关注我的公众号《程序员果果》,关注有惊喜~~