DockerSwarm 微服务部署

本文涉及的产品
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
简介: 在《DockerSwarm集群环境搭建》中,我们使用docker service create 来部署服务时,一次只能部署一个服务,这一节就讲解 DockerSwarm 集群环境中, 使用 docker-compose.yml 一次启动多个关联的服务。

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

一、简介

之前《服务Docker化》中,使用 docker-compose.yml 来一次配置启动多个容器,在 Swarm 集群中也可以使用 compose 文件 (docker-compose.yml) 来配置、启动多个服务。
在《DockerSwarm集群环境搭建》中,我们使用docker service create 来部署服务时,一次只能部署一个服务,这一节就讲解 DockerSwarm 集群环境中, 使用 docker-compose.yml 一次启动多个关联的服务。

二、创建 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: 8761
spring:
  application:
    name: eureka-server
eureka:
  client:
    register-with-eureka: false
    fetch-registry: false
    service-url:
      defaultZone: http://eureka-server:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: eureka-server:8761

EurekaServerApplication

@EnableEurekaServer
@SpringBootApplication
public 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: 8763
spring:
  application:
    name: service-hi
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-server:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: service-hi:8763

ServiceHiApplication

@EnableEurekaClient
@SpringBootApplication
@RestController
public 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: 8764
spring:
  application:
    name: service-ribbon
eureka:
  client:
    serviceUrl:
      defaultZone: http://eureka-server:8761/eureka/
  instance:
    prefer-ip-address: true
    instance-id: eureka-server:8764

HelloService

@Service
public class HelloService {

    @Autowired
    private RestTemplate restTemplate;

    public String hiService() {
        return restTemplate.getForObject( "http://service-hi:8763/hi" , String.class );
    }

}

HelloControler

@RestController
public class HelloControler {

    @Autowired
    private HelloService helloService;

    @GetMapping(value = "/hi")
    public String hi() {
        return helloService.hiService();
    }

}

ServiceRibbonApplication

@SpringBootApplication
@EnableEurekaClient
@EnableDiscoveryClient
public 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 hub.gf.com:9090/jdk/openjdk:8-jre

MAINTAINER gf gf@163.com

COPY target/eureka-server-0.0.1-SNAPSHOT.jar /eureka-server-0.0.1-SNAPSHOT.jar

ENTRYPOINT ["java" , "-jar" , "/eureka-server-0.0.1-SNAPSHOT.jar"]

service-hi 项目的 Dockerfile

FROM hub.gf.com:9090/jdk/openjdk:8-jre

MAINTAINER gf gf@163.com

COPY target/service-hi-0.0.1-SNAPSHOT.jar /service-hi-0.0.1-SNAPSHOT.jar

ENTRYPOINT ["java" , "-jar" , "/service-hi-0.0.1-SNAPSHOT.jar"]

service-ribbon 项目的 Dockerfile

#!/usr/bin/env bash

mvn package -Dmaven.test.skip=true

docker build -t hub.gf.com:9090/springcloud-ribbon/service-ribbon:latest .

docker login -u admin -p Harbor12345 hub.gf.com:9090

docker push hub.gf.com:9090/springcloud-ribbon/service-ribbon:latest

2. 创建 build.sh

为了方便,三个项目根目录下创建 build.sh 脚本,来一键执行项目的打jar包、构建镜像、推送到私有仓库。

eureka-server 项目的 build.sh

#!/usr/bin/env bash

mvn package -Dmaven.test.skip=true


docker build -t hub.gf.com:9090/springboot-ribbon/eureka-server:latest .

docker login -u admin -p Harbor12345 hub.gf.com:9090

docker push hub.gf.com:9090/springboot-ribbon/eureka-server:latest

service-hi 项目的 build.sh

#!/usr/bin/env bash

mvn package -Dmaven.test.skip=true

docker build -t hub.gf.com:9090/springboot-ribbon/service-hi:latest .

docker login -u admin -p Harbor12345 hub.gf.com:9090

docker push hub.gf.com:9090/springboot-ribbon/service-hi:latest

service-ribbon 项目的 build.sh

#!/usr/bin/env bash

mvn package -Dmaven.test.skip=true

docker build -t hub.gf.com:9090/springboot-ribbon/service-ribbon:latest .

docker login -u admin -p Harbor12345 hub.gf.com:9090

docker push hub.gf.com:9090/springboot-ribbon/service-ribbon:latest

分别执行三个 build.sh 脚本,这样私有仓库就有三个项目的镜像了,如图:

三、部署服务

1. 启动集群环境

启动之前搭建好的 docker swarm 集群环境:

docker-machine start myvm-1 myvm-2 myvm-3

要在管理节点下部署服务,所以需要知道哪台是管理节点,随便连接一台机器,通过 docker node 命令查看节点信息:

docker-machine ssh myvm-1
docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
ib1498ex2q18i7gznb2zgicqq *   myvm-1              Ready               Active              Leader              18.09.1-beta2
vels0fe3eh5s5cxj1s573v9wx     myvm-2              Ready               Active              Reachable           18.09.1-beta2
obxnnqelh4p16wajrwvyn6j8v     myvm-3              Ready               Active              Reachable           18.09.1-beta2

myvm-1 就是管理节点,不需要切换节点了。

2. 编写 services.yml

之后用 docker stack 部署服务,所以需要编写服务编排文件,内容如下:

version: "3.4"
services:
  eureka-server:
    image: hub.gf.com:9090/springcloud-ribbon/eureka-server:latest
    deploy:
      endpoint_mode: vip
      resources:
        limits:
          cpus: "0.5"
          memory: "1024M"
    ports:
      - "8761:8761"

  service-hi:
    image: hub.gf.com:9090/springcloud-ribbon/service-hi:latest
    deploy:
      endpoint_mode: vip
      resources:
        limits:
          cpus: "0.5"
          memory: "1024M"
    ports:
      - "8763:8763"
    depends_on:
      - eureka-server

  service-ribbon:
    image: hub.gf.com:9090/springcloud-ribbon/service-ribbon:latest
    deploy:
      endpoint_mode: vip
      resources:
        limits:
          cpus: "0.5"
          memory: "1024M"
    ports:
      - "8764:8764"
    depends_on:
      - eureka-server
      - service-hi

networks:
  default:
    external:
      name: my-overlay

文件详细说明,这里就不说了,可以网上查一下。

3. 启动服务

通过 docker stack deploy 命令 启动服务:

docker stack deploy -c services.yml ms

通过 docker service ls 查看服务启动状态:

docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE                                                      PORTS
q99gd5rquv3f        ms_eureka-server    replicated          1/1                 hub.gf.com:9090/springcloud-ribbon/eureka-server:latest    *:8761->8761/tcp
wjsv5s6fce6k        ms_service-hi       replicated          1/1                 hub.gf.com:9090/springcloud-ribbon/service-hi:latest       *:8763->8763/tcp
zjwe7cnpn42y        ms_service-ribbon   replicated          1/1                 hub.gf.com:9090/springcloud-ribbon/service-ribbon:latest   *:8764->8764/tcp

服务启动后 ,访问 192.168.99.100:8761 , 192.168.99.100:8763/hi , 192.168.99.100:8764/hi ,都可以正常访问,说明已经部署成功了。

相关文章
|
16天前
|
SQL Kubernetes 监控
微服务从代码到k8s部署应有尽有系列(九、事务精讲)
微服务从代码到k8s部署应有尽有系列(九、事务精讲)
微服务从代码到k8s部署应有尽有系列(九、事务精讲)
|
3天前
|
运维 Kubernetes Cloud Native
云原生时代下,如何高效构建与部署微服务
【9月更文挑战第8天】随着云计算技术的飞速发展,云原生已成为现代软件架构的重要趋势。本文将深入浅出地介绍云原生概念、微服务架构的优势以及如何在云平台上高效构建和部署微服务。我们将通过实际的代码示例,展示在Kubernetes集群上部署一个简单的微服务应用的过程,帮助读者理解云原生环境下的微服务开发和运维实践。
|
16天前
|
Kubernetes jenkins 持续交付
微服务从代码到k8s部署应有尽有系列(十四、部署环境搭建)
微服务从代码到k8s部署应有尽有系列(十四、部署环境搭建)
|
15天前
|
负载均衡 应用服务中间件 持续交付
微服务架构下的Web服务器部署
【8月更文第28天】随着互联网应用的不断发展,传统的单体应用架构逐渐显露出其局限性,特别是在可扩展性和维护性方面。为了解决这些问题,微服务架构应运而生。微服务架构通过将应用程序分解成一系列小型、独立的服务来提高系统的灵活性和可维护性。本文将探讨如何在微服务架构中有效部署和管理Web服务器实例,并提供一些实际的代码示例。
46 0
|
16天前
|
Kubernetes 监控 中间件
微服务从代码到k8s部署应有尽有系列全集
微服务从代码到k8s部署应有尽有系列全集
|
16天前
|
消息中间件 Kubernetes Kafka
微服务从代码到k8s部署应有尽有系列(八、各种队列)
微服务从代码到k8s部署应有尽有系列(八、各种队列)
|
16天前
|
Kubernetes NoSQL API
微服务从代码到k8s部署应有尽有系列(五、民宿服务)
微服务从代码到k8s部署应有尽有系列(五、民宿服务)
|
8天前
|
Dubbo Java 应用服务中间件
微服务框架Dubbo环境部署实战
微服务框架Dubbo环境部署的实战指南,涵盖了Dubbo的概述、服务部署、以及Dubbo web管理页面的部署,旨在指导读者如何搭建和使用Dubbo框架。
56 17
微服务框架Dubbo环境部署实战
|
6天前
|
缓存 Java 应用服务中间件
随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架
【9月更文挑战第6天】随着微服务架构的兴起,Spring Boot凭借其快速开发和易部署的特点,成为构建RESTful API的首选框架。Nginx作为高性能的HTTP反向代理服务器,常用于前端负载均衡,提升应用的可用性和响应速度。本文详细介绍如何通过合理配置实现Spring Boot与Nginx的高效协同工作,包括负载均衡策略、静态资源缓存、数据压缩传输及Spring Boot内部优化(如线程池配置、缓存策略等)。通过这些方法,开发者可以显著提升系统的整体性能,打造高性能、高可用的Web应用。
27 2
|
9天前
|
Ubuntu Linux Docker
docker swarm快速入门篇
关于Docker Swarm集群部署和验证高可用性的快速入门教程。
12 2