Docker03 - Docker Compose 和 Docker Swarm

Docker Compose 和 Docker Swarm

文章目录

一:Docker Compose

官网:https://www.docker.com/

文档地址: https://docs.docker.com/ (Docker 官网文档超级详细)

仓库地址:https://hub.docker.com/

容器单独没有什么意义,有意义的是容器编排

1:简介

Compose是一个用于定义和运行多容器Docker应用程序的工具。

使用Compose,您可以使用yaml文件配置应用程序的服务。然后,使用一个命令,从配置中创建并启动所有服务

使用Compose基本上是一个三步过程:

  • 使用定义应用的环境,以便可以在任何位置重现它。Dockerfile
  • 定义构成应用的服务,以便它们可以在隔离的环境中一起运行。docker-compose.yml
  • 运行,Docker 撰写命令将启动并运行整个应用。您也可以使用 docker-compose 二进制文件运行

它是一个容器编排助手,用于集中管理多个 Docker 容器的启动和协同工作。

可以在一个配置文件中集中定义所有容器以及它们的关系。

然后,可以使用一行命令启动所有容器,而不需要手动运行多个命令。

在这里插入图片描述
需要注意的是,Docker Compose 通常适用于把所有微服务部署在同一台服务器的场景

在真实的企业级项目中,往往会使用 K8S 等更专业的容器编排和自动化部署工具,更方便地在多个服务器上部署容器。

2:docker Compose安装

Install Docker Compose | Docker Documentation

官方下载地址慢,不推荐官方的下载地址,使用国内的镜像

运行以下命令下载 Docker Compose 的当前稳定版本:

curl -L https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

将可以执行的权限应用于二进制文件

chmod +x /usr/local/bin/docker-compose

安装成功

> docker-compose version
# 如果安装成功,将会有下面的提示信息
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l  10 Sep 2019

3:如何编写docker compose

和 Dockerfile 一样,直接去网上找现成的 Docker Compose file,复制粘贴过来略做修改就能使用了~

再配合以下 2 个网站,完全无需记忆 Docker Compose 的写法!

  • Docker Compose file 官方文档:https://docs.docker.com/compose/compose-file/

在这里插入图片描述

  • 搜索现成的 Docker 镜像:https://hub.docker.com/

当然,现在 AI 时代了,还有更简单的方式!让 AI 帮我们生成配置即可~

在这里插入图片描述

Docker Engine 与 docker-compose version 之间的有以下关系:

Compose file formatDocker Engine
11.9.0+
2.01.10.0+
2.11.12.0+
2.2, 3.0, 3.1, 3.21.13.0+
2.3, 3.3, 3.4, 3.517.06.0+
2.417.12.0+
3.618.02.0+
3.718.06.0+

1.25.5版本开始,可以直接按操作系统平台下载安装包:

项目地址:https://github.com/docker/compose/releases

二:微服务部署实战

1:梳理服务部署表格

在部署微服务项目前,首先要规划好要部署哪些服务、以及各服务的关键信息,比如服务名称、版本号、占用端口号、关键配置等。

服务名称英文名端口号版本号服务类别
数据库mysql3306v8环境依赖
缓存redis6379v6环境依赖
消息队列rabbitmq5672, 15672v3.12.6环境依赖
注册中心nacos8848v2.2.0环境依赖
网关服务gateway8101java 8业务服务
用户服务yuoj-backend-user-service8102java 8业务服务
题目服务yuoj-backend-question-service8103java 8业务服务
判题服务yuoj-backend-judge-service8104java 8业务服务

为什么这里我要划分服务类别为 “环境依赖” 和 “业务服务” 呢?

因为在启动服务时,必须要先启动环境依赖,才能启动业务服务,否则就会报类似 “无法连接数据库” 之类的错误。

2:Maven 子父模块打包

对于微服务项目,我们通常是使用 Maven 的子父模块功能进行管理的。

需要部署项目时,不用针对每个子服务单独执行 mvn package 命令进行打包,而是可以一键打包所有服务。

想要实现这个功能,需要给子父模块的依赖文件(pom.xml)进行一些配置,主要包括:

2.1:父模块配置

在父模块的 pom.xml 文件中引入 spring-boot-maven-plugin 即可

⚠️ 一定不要配置 configuration 和 repackage!

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>${spring-boot.version}</version>
</plugin>
2.2:子模块配置

修改所有需要启动 Spring Boot 的服务(用户服务、题目服务、判题服务、网关服务)的子模块 pom.xml 文件。

主要是增加 executions 配置,使用 spring-boot-maven-plugin 的 repackage 命令来构建子模块

从而自动在构建时将公共模块的依赖打入 jar 包。

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <executions>
        <execution>
            <id>repackage</id>
            <goals>
                <goal>repackage</goal>
            </goals>
        </execution>
    </executions>
</plugin>

3:Dockerfile 编写

我们需要给每个 Spring Boot 服务(用户服务、题目服务、判题服务、网关服务)都编写一个 Dockerfile,放到每个子服务的根目录下。

在这里插入图片描述
以用户服务为例,示例代码如下:

# 基础镜像
FROM openjdk:8-jdk-alpine
  
# 指定工作目录
WORKDIR /app
  
# 将 jar 包添加到工作目录,比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar .
  
# 暴露端口
EXPOSE 8102
  
# 启动命令
ENTRYPOINT ["java","-jar","/app/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar","--spring.profiles.active=prod"]

🎉 建议先在本地利用 IDEA 开发工具调通镜像构建流程,确保每个 Dockerfile 都是可以成功制作镜像的

在这里插入图片描述
查看容器的启动日志,发现能够启动服务、看到 Spring 图标即可:

在这里插入图片描述

4:env docker compose编写

之前我们已经梳理了服务部署表格,将服务划分为了 “环境依赖” 和 “业务服务”。

由于业务服务依赖 MySQL 等环境依赖,所以需要拆分 2 套 Docker Compose 的配置文件:

分别为 docker-compose.env.yml 环境配置和 docker-compose.service.yml 业务服务配置,保证先成功启动依赖,再启动服务。

Docker Compose 中的 depends_on 配置,也能决定服务的启动顺序。

但是depends_on 并不会等待服务完全就绪,只是确保它们在启动时的顺序,并不稳定。

4.1:MySQL docker Compose

我们不仅要创建一个 MySQL 服务,还要在创建服务后自动创建我们需要的库表结构。

所以需要先准备数据库 SQL 脚本文件,里面包含了建库、建表语句,我们把它放在微服务项目根目录的 mysql-init 文件夹中:

每个项目都提供了现成的建表语句,这是一个非常好的开发习惯,便于其他人快速启动你的项目。

在这里插入图片描述
由于要在本地启动 MySQL,还需要定义一个文件夹 .mysql-data 来存放 MySQL 的持久化数据,防止容器重启后数据丢失。

做好这两点后,就可以编写 docker-compose.env.yml 文件了,先只写一个 MySQL 服务,示例代码如下:

version: '3'
services:
  mysql:
    image: mysql:8 # 使用的镜像
    container_name: yuoj-mysql # 启动的实例名称
    environment:
      MYSQL_ROOT_PASSWORD: 123456 # root 用户密码
    ports:
      - "3306:3306" # 端口映射
    volumes:
      - ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化
      - ./mysql-init:/docker-entrypoint-initdb.d # 自动执行启动脚本
    restart: always # 崩溃后自动重启
    networks:
      - mynetwork # 指定网络
networks:
  mynetwork: # 自定义网络,实现网络互通和隔离

写好配置文件后,可以直接在 IDEA 里执行 Docker Compose 文件,调试 MySQL 的运行:

在这里插入图片描述
运行成功后,我们可以在本地成功连接数据库:

在这里插入图片描述

4.2:redis docker Compose

Redis 服务的定义和启动操作和 MySQL 服务几乎一致,Redis 的 Docker Compose 配置示例代码如下:

version: '3'
services:
  redis:
    image: redis:6 # 指定镜像是redis6
    container_name: yuoj-redis # 声明容器名称
    ports:
      - "6379:6379" # 端口映射
    networks:
      - mynetwork # 指定网络
    volumes:
      - ./.redis-data:/data # 持久化
networks:
  mynetwork: # 自定义网络,实现网络互通和隔离

然后在本地执行 Docker Compose 文件,启动 Redis 服务,并且尝试进入 Terminal 来调试 Redis:

在这里插入图片描述

4.3:rabbitMQ docker Compose

大体都一样,不在赘述

version: '3'
services:
  rabbitmq:
    image: rabbitmq:3.12.6-management # 支持管理面板的消息队列
    container_name: yuoj-rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest # 用户名和密码
    ports:
      - "5672:5672"
      - "15672:15672" # RabbitMQ Dashboard 端口
    volumes:
      - ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
    networks:
      - mynetwork
networks:
  mynetwork:

本地执行 Docker Compose 文件,启动 RabbitMQ 服务,然后可以访问 localhost:15672 查看到管理面板,就表示启动成功了

在这里插入图片描述

4.4:nacos docker Compose

在选择 Nacos 镜像时必须要注意,建议选择支持 linux/arm64 架构的镜像版本,比如 v2.2.0-slim,否则后面可能会无法运行:

在这里插入图片描述

version: '3'
services:
  nacos:
    image: nacos/nacos-server:v2.2.0-slim
    container_name: yuoj-nacos
    ports:
      - "8848:8848"
    volumes:
      - ./.nacos-data:/home/nacos/data
    networks:
      - mynetwork
    environment:
      - MODE=standalone # 单节点模式启动
      - PREFER_HOST_MODE=hostname # 支持 hostname
      - TZ=Asia/Shanghai # 控制时区
networks:
  mynetwork:

然后在本地执行 Docker Compose 启动 Nacos,访问 localhost:8848/nacos 能够看到管理页面,就表示运行成功了

管理页面的账号和密码默认都是 nacos

在这里插入图片描述

4.5:环境compose整合

分别调试完上述服务后,我们把所有的配置拼在一起,就得到了完整的文件,文件名为 docker-compose.env.yml

version: '3'
services:
  mysql:
    image: mysql:8 # 使用的镜像
    container_name: yuoj-mysql # 启动的实例名称
    environment:
      MYSQL_ROOT_PASSWORD: 123456 # root 用户密码
    ports:
      - "3306:3306" # 端口映射
    volumes:
      - ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化
      - ./mysql-init:/docker-entrypoint-initdb.d # 启动脚本
    restart: always # 崩溃后自动重启
    networks:
      - mynetwork # 指定网络
  redis:
    image: redis:6
    container_name: yuoj-redis
    ports:
      - "6379:6379"
    networks:
      - mynetwork
    volumes:
      - ./.redis-data:/data # 持久化
  rabbitmq:
    image: rabbitmq:3.12.6-management # 支持管理面板的消息队列
    container_name: yuoj-rabbitmq
    environment:
      RABBITMQ_DEFAULT_USER: guest
      RABBITMQ_DEFAULT_PASS: guest
    ports:
      - "5672:5672"
      - "15672:15672" # RabbitMQ Dashboard 端口
    volumes:
      - ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
    networks:
      - mynetwork
  nacos:
    image: nacos/nacos-server:v2.2.0-slim
    container_name: yuoj-nacos
    ports:
      - "8848:8848"
    volumes:
      - ./.nacos-data:/home/nacos/data
    networks:
      - mynetwork
    environment:
      - MODE=standalone # 单节点模式启动
      - PREFER_HOST_MODE=hostname # 支持 hostname
      - TZ=Asia/Shanghai # 控制时区
networks:
  mynetwork:

5:service docker compose编写

示例代码如下,其中需要格外关注的配置是 build 和 depends_on:

version: '3'
services:
  yuoj-backend-gateway:
    container_name: yuoj-backend-gateway # 指定容器名称
    build: # 服务的 Docker 构建文件位置
      context: ./yuoj-backend-gateway # 指定目录
      dockerfile: Dockerfile  # 指定dockerfile
    ports:
      - "8101:8101" # 端口映射
    networks:
      - mynetwork # 指定网络
  
  yuoj-backend-user-service:
    container_name: yuoj-backend-user-service # 指定容器名称
    build:
      context: ./yuoj-backend-user-service # 指定目录
      dockerfile: Dockerfile # 指定dockerfile
    ports:
      - "8102:8102" # 端口映射
    networks:
      - mynetwork # 指定网络
    depends_on: # 本服务依赖的服务,控制启动先后顺序
      - yuoj-backend-gateway # 用户服务依赖于网关服务

  yuoj-backend-question-service:
    container_name: yuoj-backend-question-service # 指定容器名称
    build:
      context: ./yuoj-backend-question-service # 指定目录
      dockerfile: Dockerfile # 指定dockerfile
    ports:
      - "8103:8103" # 端口映射
    networks:
      - mynetwork  # 指定网络
    depends_on: 
      - yuoj-backend-user-service # 问题服务依赖于用户服务
      - yuoj-backend-gateway # 问题服务依赖于网关服务

  yuoj-backend-judge-service:
    container_name: yuoj-backend-judge-service # 指定容器名称
    build:
      context: ./yuoj-backend-judge-service # 指定目录
      dockerfile: Dockerfile # 指定dockerfile
    ports:
      - "8104:8104" # 端口映射
    networks:
      - mynetwork # 指定网络
    depends_on:
      - yuoj-backend-user-service # 判题服务依赖于用户服务
      - yuoj-backend-question-service # 判题服务依赖于问题服务
      - yuoj-backend-gateway # 判题服务依赖于网关服务

# 网络,不定义的话就是默认网络
networks:
  mynetwork:

6:调整程序配置

编写好上述配置文件后,本地尝试运行 Docker Compose 业务服务,结果发现:报错啦!依赖服务的地址访问不通!

这是由于之前我们的项目访问依赖服务时,全部是使用了固定的 IP 地址(比如 localhost)

而容器内部的 localhost(或 127.0.0.1)通常指向容器本身,而不是宿主主机。

所以为了在容器内访问其他服务,程序中应该使用服务名称而不是 localhost

我们给每个 Spring Boot 服务都增加一套 prod 上线配置,在配置中更改服务调用地址。

用户服务、题目服务和判题服务的 application-prod.yml 配置修改如下:

# 生产环境配置文件
spring:
  # 数据库配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://mysql:3306/yuoj # localhost 改为 mysql
    username: root
    password: 123456
  # Redis 配置
  redis:
    database: 1
    host: redis # localhost 改为 redis
    port: 6379
    timeout: 5000
  cloud:
    nacos:
      discovery:
        server-addr: nacos:8848 # localhost 改为 nacos
  rabbitmq:
    host: rabbitmq # localhost 改为 rabbitmq
    port: 5672
    password: guest
    username: guest

Gateway 网关服务的配置修改如下:

spring:
  cloud:
    nacos:
      discovery:
        server-addr: nacos:8848 # localhost 改为 nacos
    gateway:
      # ------> 指定网关映射 <------
      routes:
        - id: yuoj-backend-user-service
          uri: lb://yuoj-backend-user-service
          predicates:
            - Path=/api/user/**
        - id: yuoj-backend-question-service
          uri: lb://yuoj-backend-question-service
          predicates:
            - Path=/api/question/**
        - id: yuoj-backend-judge-service
          uri: lb://yuoj-backend-judge-service
          predicates:
            - Path=/api/judge/**
  application:
    name: yuoj-backend-gateway
  main:
    web-application-type: reactive
server:
  port: 8101
# 网关层支持swagger
knife4j:
  gateway:
    enabled: true
    strategy: discover
    discover:
      enabled: true
      version: swagger2

然后执行 mvn package 命令重新打包、执行 Docker Compose。

🎉 一定不要在项目中写死ip, 最好读取配置的方式,例如

/**
 * 用于创建测试程序用到的交换机和队列(只用在程序启动前执行一次)
 */
@Slf4j
@Component
public class InitRabbitMqBean {

    @Value("${spring.rabbitmq.host:localhost}")
    private String host;

    @PostConstruct
    public void init() {
        try {
            ConnectionFactory factory = new ConnectionFactory();
            factory.setHost(host);
            Connection connection = factory.newConnection();
            Channel channel = connection.createChannel();
            String EXCHANGE_NAME = "code_exchange";
            channel.exchangeDeclare(EXCHANGE_NAME, "direct");

            // 创建队列,随机分配一个队列名称
            String queueName = "code_queue";
            channel.queueDeclare(queueName, true, false, false, null);
            channel.queueBind(queueName, EXCHANGE_NAME, "my_routingKey");
            log.info("消息队列启动成功");
        } catch (Exception e) {
            log.error("消息队列启动失败");
        }
    }
}

7:测试访问

修复上述问题后,所有服务都可以通过 Docker Compose 文件启动了。

然后我们访问 localhost:8101/doc.html 网关地址,能够看到 Swagger 聚合接口文档。

在这里插入图片描述

8:服务器部署

8.1:Docker Compose 安装

有了服务器后,直接参考 Docker Compose 官方文档来安装。

这里我们使用 Docker Compose V2 版本,相比 V1 版本统一了命令,使用更方便:

Docker Compose V2 地址:https://docs.docker.com/compose/migrate/

Docker Compose Linux 安装:https://docs.docker.com/compose/install/linux/#install-using-the-repository

安装过程很简单,跟着官方文档来就行了,主要包括以下几个步骤:

1)设定安装来源:

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

2)安装 Docker 和 Docker Compose:

sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

3)启动 Docker:

sudo systemctl start docker

4)测试 Docker:

systemctl status docker
sudo docker run hello-world
8.2:同步文件

接下来,我们需要把本地折腾好的微服务项目源码上传到服务器上,可以选择用 FTP 或 SSH 连接文件手动上传文件。

在这里插入图片描述

8.3:获取 jar 包

光把代码上传到服务器还是不够的,因为我们构建 Docker 镜像需要 jar 包。

有 2 种方式得到 jar 包:

  1. 本地执行 mvn package 打好 jar 包,然后再上传
  2. 服务器上装 Maven,在服务器上打包

但是因为 jar 包比较大,频繁改动的话同步速度会比较慢,所以更建议第二种方式,步骤如下:

1)安装 Maven:

sudo yum install maven

2)安装好后,执行打包:

sudo mvn package

打包成功:

在这里插入图片描述

8.4:服务启动
8.4.1:启动环境依赖

先使用 docker compose 一行命令启动环境依赖:

# 老版本使用 "docker-compose" 替代 "docker compose"
# 如果没有权限,命令前加上 "sudo"或者编程超级用户
docker compose -f docker-compose.env.yml up

启动成功后,我们可以通过公网 IP 来尝试访问服务。

先进入到云服务商的服务器配置页,修改服务器的防火墙配置,放通以下端口:

在这里插入图片描述

8.4.2:后台运行进程

由于进程在前台启动会影响我们的操作,所以先按 ctrl + c 退出,加上 -d 参数让容器在后台启动:

sudo docker compose -f docker-compose.env.yml up -d

试着查看下 docker 容器的状态:

sudo docker stats

在这里插入图片描述

8.4.3:启动业务服务

确保环境依赖都启动成功后,接下来启动业务服务:

docker compose -f docker-compose.service.yml up

在这里插入图片描述
如果某个服务启动失败,可以再次单独只启动它,比如网关服务:

sudo docker compose 
	-f docker-compose.service.yml 
	up 
	yuoj-backend-gateway # 单独启动网关服务
8.5:测试访问

在这里插入图片描述

三:Docker Swarm

1:Docker Swarm简介

1.1:概述和作用

Docker Swarm是Docker官方提供的一个容器编排工具,用于管理Docker容器集群。

它提供了一组API以及命令行工具,使得用户可以轻松地创建、启动、停止以及扩展应用程序。

Docker Swarm的作用在于,它可以帮助用户管理多个Docker容器,简化应用程序的部署和管理

Docker Swarm将多个Docker主机组成一个集群,用户可以将应用程序部署到集群中,Docker Swarm会自动将应用程序部署到可用的Docker主机上

当集群中的某个Docker主机出现故障时,Docker Swarm会自动将受影响的容器重新部署到其他可用的主机上

在这里插入图片描述

1.2:Docker Swarm与Kubernetes

Docker Swarm和Kubernetes都是容器编排工具,它们都可以用于管理容器集群。下面是它们的比较优缺点:

Docker Swarm的优点:

  • Docker Swarm功能相对简单,易于上手。
  • Docker Swarm1.12后,Docker原生支持Swarm,无需再额外安装,使用更加便捷。
  • Docker Swarm的性能比较高,可以快速地利用集群中的资源进行部署。

Kubernetes的优点:

  • Kubernetes的功能非常强大,可以满足各种复杂的部署和管理需求。
  • Kubernetes有很多插件和第三方工具,可以满足各种不同的需求。
  • Kubernetes在容器编排方面的功能比Docker Swarm更加强大和灵活。

Docker Swarm的缺点:

  • 相对于Kubernetes的高度可定制化,Docker Swarm的功能相对简单,可能无法满足高度定制化的需求。
  • Docker Swarm并没有像Kubernetes那样支持多集群。

Kubernetes的缺点:

  • Kubernetes的学习曲线较陡峭,需要更多的学习和时间投入。
  • Kubernetes架构复杂,运维成本相对高一些。
1.3:安装Docker Swarm

安装 Docker Engine 取决于你的操作系统。以下是 Docker Engine 的安装步骤:

在 Linux 中安装 Docker Engine:

sudo apt-get remove 
	docker
	docker-engine
    docker.io containerd runc

安装docker Engine:

$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
1.4:需要关注的步骤
1.4.1:配置主节点

首先,需要选择其中一个节点作为Docker Swarm的主节点。该节点应安装Docker,并运行以下命令以初始化Swarm

docker swarm init --advertise-addr <MANAGER-IP>

🎉 在这里会生成token,可以进行抓取,token作用在日志中

1.4.2:其他节点加入

现在可以将其他节点加入到Docker Swarm中。在各个节点上,运行以下命令以加入集群:

docker swarm join --token <TOKEN> <MANAGER-IP>:2377
1.5:部署服务

一旦Docker Swarm集群已准备就绪,可以利用docker stack命令将应用程序部署到集群中。

可以使用Docker Compose YAML文件定义服务和网络,如以下示例:

version: '3'
services:
  web:
    image: nginx
    ports:
    - "80:80"
  redis:
    image: redis

执行以下命令以启动应用程序:

# 需要使用docker-compose.yml文件和指定的服务名称。
docker stack deploy -c <docker-compose.yml> <SERVICE-NAME>
1.6:核心概念

在这里插入图片描述

1.7:生命周期

在这里插入图片描述

2:核心使用

2.1 用法的基础知识

Docker Swarm是Docker官方提供的一个用于管理Docker集群的工具。

它可以将多个Docker主机组合为一个虚拟的Docker主机,并将容器应用程序无缝地在多个Docker主机之间分配和调度

Docker Swarm使用了多个构建块并提供了一些重要的概念,其中包括节点角色、服务概念以及集群网络。

2.2:节点角色

Docker Swarm节点分为主节点和工作节点两种,其角色有所不同。

在这里插入图片描述

  • 主节点:是Swarm管理者,负责配置、调度和协调服务,管理节点和排除故障等。主节点拥有Swarm集群的全图和完整的状态信息。
  • 工作节点:运行容器。通过监听主节点访问请求接收服务部署信息并运行容器服务。工作节点可以是物理服务器、虚拟机等其他Docker主机。
2.3:服务概念

服务是Swarm集群的基本单位。

一个服务可以由多个副本组成。每一个副本运行在集群的不同节点上,间接提供应用程序的容错能力和可扩展性。

同时,通过对服务的定制化配置,还可以支持服务发现、负载均衡、升级和滚动回滚等操作。

2.4:创建Docker Swarm集群
2.4.1:操作步骤

创建Docker Swarm集群需要按照以下步骤操作:

  1. 创建一个Swarm管理节点:使用docker swarm init命令创建Swarm管理节点,并获取token。

  2. 加入工作节点:使用docker swarm join命令将工作节点加入到Swarm集群中,使用之前获取的token和主机IP地址加入节点。

  3. 用户配置网络和服务。

⚠️ Swarm集群的规模可根据需要扩展,而在扩展时,必须将新的工作节点加入到现有的Swarm集群中。

⚠️ 要加入新节点,必须在新节点上运行docker swarm join命令,并将新节点的令牌提供给Swarm管理节点。

创建Docker Swarm集群的详细步骤

  1. 在主节点上使用以下命令初始化Swarm:
docker swarm init --advertise-addr <MANAGER-IP> # 注意在这里的日志中抓取token

在这里插入图片描述

  1. 检查是否成功初始化Swarm集群,可通过以下命令查看状态:
docker node ls
  1. 在工作节点上通过以下命令加入Swarm集群:
docker swarm join --token <TOKEN> <MANAGER-IP>:2377

在这里插入图片描述

  1. 加入集群之后,可通过执行以下命令在Swarm集群上创建一个名为nginx-web服务并运行两个实例
docker service create # 声明创建服务
	--name nginx-web # 服务的名称
	--replicas 2 # 指定副本数为2,表示运行两个实例
	-p 8080:80 # 端口映射-宿主机端口8080,容器端口80
	nginx # 指定镜像

该服务将nginx容器映射到集群中的两个工作节点,并将服务的监听端口从容器的80号端口到Swarm集群中任意一个节点的8080端口进行转发。

在这里插入图片描述

查看服务的信息docker service inspect --pretty <service id>

  • –pretty 参数可以简化输出內容
  • docker service ps <service id>可以查看运行中的服务信息
  • 进入工作节点通过 docker ps 可以查看容器运行状态
    在这里插入图片描述
2.4.2:弹性伸缩

更新服务的实例个数:docker service update --replicas <num> <service id/name>

在这里插入图片描述

添加新的 Docker 节点,执行 docker swarm join 命令可以加入集群

执行 docker swarm leave 可以退出集群,也可以带上 --force 参数强制退出集群

在这里插入图片描述

2.5 部署和管理应用程序
2.5.1 部署和管理应用程序

Docker Compose是一种工具,可以通过一个单独的YAML文件来定义、部署和运行由多个容器组成的应用程序。

使用Docker Compose可以简化多个Docker容器的部署,并且可以通过一个文件来定义容器之间的依赖关系。

Docker Compose允许在单个主机上运行应用程序,而Docker Stack则扩展并在Swarm集群中运行应用程序。

2.5.2 扩展应用程序

Swarm允许在多台主机之间扩展应用程序,并自动管理应用程序的多个实例。

利用Docker Compose和Docker Stack文件中所定义的服务和副本数

Swarm集群会在集群中的多个Docker宿主机上创建相应数量的“副本”容器实例。

# 需要使用docker-compose.yml文件和指定的服务名称。
docker stack deploy -c <docker-compose.yml> <SERVICE-NAME>

3:深入了解&高级部分

3.1:Docker Swarm的高级特性
3.1.1 滚动更新和回滚服务

在更新应用程序时,Swarm集群支持滚动更新和回滚服务的功能。

这意味着服务的所有实例会被逐步替换,从而可以保持应用程序的可用性。回滚操作可以撤消任何滚动更新

使用滚动更新时,Swarm会同时启动新的副本与现有的副本一起运行。

一旦新的副本被设置为正在运行,Swarm将逐步停止现有副本。此过程将自动应用于所有Swarm服务。

3.1.2 每个部署延迟

Swarm支持一个deploy.delay选项,该选项确定在多个主机上进行部署时每个任务的最长延迟。

在部署新服务或更新现有服务时,Swarm将保持“旧”服务的状态,直到它已准备好接受请求。

如果在滚动更新服务时任何问题发生,新版本的服务可以立即回滚,从而保证了可用性。

3.1.3 保护敏感信息

Docker Secrets是Docker Swarm提供的一种安全管理敏感信息的方式,可用于安全地管理和传递密钥、密码和其他保密信息。

Docker Secrets收到Docker Swarm的保护,因此可以更安全地处理密钥和其他类型数据,从而更好地保护应用程序。

Docker Secrets是用于管理敏感信息的指令,它将加密用于生产环境的信息,并确保仅在需要时才向所需容器提供访问。

使用Docker Secrets,可以轻松地传递敏感信息,而无需在代码之外保留此类信息。

使用Docker Secrets的步骤:

  1. 创建要保护的数据:常用的管理密码方法包括传统的密码存储库,密钥管理服务,密码管理器,甚至包括环境变量或命令行参数
  2. 创建一个Secret对象
docker secret create <name> <file> # name是您要创建的受保护数据的名称,file是包含敏感信息的文件路径。
  1. 在服务中使用Secret
# 可以在Docker Compose文件或Docker Stack文件中定义如何在服务中使用Secret。
# 需要将Secret的名称添加到文件中的适当位置。
# 以下是使用db_password Secret的Docker Compose文件的示例
# 这段代码将db_password Secret注入到名为db的MySQL数据库容器中。
version: "3.2"
services:
  db:
    image: mysql
    secrets:
      - db_password
secrets:
  db_password:
    external: true
3.2: 监控Docker Swarm集群
3.2.1:日志记录系统

Docker Swarm集群提供了内置的日志记录系统来帮助诊断问题。

通过使用docker service logs命令查看服务的日志文件,可以在Swarm集群中找到各个服务的问题所在。

例如,以下命令将打印名为web服务的日志:

docker service logs web
3.2.2:监控集群

Prometheus可以用来收集和监控Swarm集群的应用程序和容器的性能指标。

Grafana是一种数据可视化工具,可以与Prometheus一起使用,动态监视Swarm集群的性能和运行情况。

要使用Prometheus和Grafana监控Swarm集群,需要在集群中安装并配置Prometheus,然后使用Grafana dashboard可视化数据

在这里插入图片描述

3.3:错误排除和故障恢复
3.3.1 排查故障的方法
  • 检查Swarm节点状态:运行docker node ls命令查看节点状态,确保所有节点正常工作。

  • 检查Swarm服务状态:运行docker service ls命令以检查所有服务的状态,并确认它们正在集群中的工作节点上运行。

  • 检查容器日志:运行docker service logs命令以查看服务的容器日志。

  • 检查Docker Swarm事件:运行docker service events命令以查看集群中的所有事件,从而识别问题并解决它。

3.3.2 处理容器故障

Swarm支持健康检查和自适应调度功能,可自动检测和处理容器故障。

Swarm通常使用健康检查来检测容器的运行状况,并在必要时自动替换故障容器的实例。

健康检查的类型包括:命令、HTTP请求、TCP端口

在出现容器故障时,Swarm会从Docker Registry中检索新的镜像,并使用存在的容器映像来替换故障

3.4:可视化工具portainer

安装portainer:

  • 基于docker ->
docker run 
	-d 
	-p 9000:9000 
	--restart=always
	-v /var/run/docker.sock:/var/run/docker.sock
	-v portainer_data:/data
	portainer/portainer
  • 基于docker swarm ->
docker service create
	-p 9000:9000
	--replace 1
	--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock
	--mount type=volume,src=portainer_data,dst=/data
	portainer/portainer

在这里插入图片描述

访问docker swarm任意节点地址都可以访问

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值