如何在生产环境中使用 Docker Swarm 调度容器?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
网络型负载均衡 NLB,每月750个小时 15LCU
简介: 随着我们的业务规模越来越大,我们的容器规模也逐渐增大时,数量庞大的容器管理将给我们带来许多挑战。Docker 官方为了解决多容器管理的问题推出了 Docker Swarm ,我们可以用它来管理规模更大的容器集群。

随着我们的业务规模越来越大,我们的容器规模也逐渐增大时,数量庞大的容器管理将给我们带来许多挑战。Docker 官方为了解决多容器管理的问题推出了 Docker Swarm ,我们可以用它来管理规模更大的容器集群。


Swarm 的前生今世

2014 年 Docker 在容器界越来越火,这时容器的编排工具 Mesos 和 Kubernetes 也开始崭露头角。此时,Docker 公司也开始筹划容器的编排和集群管理工具,推出了自己的通信协议项目 Beam。后来,通过改进 Beam,Beam 成为一个允许使用 Docker API 来控制的一种分布式系统,之后项目被重命名为 libswarm。然而在 2014 年 11 月,Docker 公司又对 libswarm 进行了重新设计,支持了远程调用 API,并且被重新命名为 Swarm。到此我们称之为 Swarm V1。


在 2016 年,为了解决中央服务可扩展性的问题,Docker 团队重新设计了 Swarm,并称之为 Swarm V2。此时的 Docker Swarm 已经可以支持超过 1000 多个节点的集群规模,并且 Docker 团队在发布 Docker 1.12 版本时,将 Docker Swarm 默认集成到了 Docker 引擎中。


由于 Swarm 是 Docker 官方推出的容器集群管理工具,因此 Swarm 最大的优势之一就是原生支持 Docker API,给用户带来了极大的便利,原来的 Docker 用户可以很方便地将服务迁移到 Swarm 中来。


与此同时,Swarm 还内置了对 Docker 网络插件的支持,因此用户可以很方便地部署需要跨主机通信的容器集群。其实 Swarm 的优点远远不止这些,还有很多,例如以下优点。


分布式: Swarm 使用Raft(一种分布式一致性协议)协议来做集群间数据一致性保障,使用多个容器节点组成管理集群,从而避免单点故障。


安全: Swarm 使用 TLS 双向认证来确保节点之间通信的安全,它可以利用双向 TLS 进行节点之间的身份认证,角色授权和加密传输,并且可以自动执行证书的颁发和更换。


简单: Swarm 的操作非常简单,并且除 Docker 外基本无其他外部依赖,而且从 Docker 1.12 版本后, Swarm 直接被内置到了 Docker 中,可以说真正做到了开箱即用。


Swarm 的这些优点得益于它优美的架构设计,下面我们来了解一下 Swarm 的架构。


Swarm 的架构

Swarm 的架构整体分为管理节点(Manager Nodes)和工作节点(Worker Nodes),整体架构如下图:


图 1 Swarm 架构图


管理节点: 管理节点负责接受用户的请求,用户的请求中包含用户定义的容器运行状态描述,然后 Swarm 负责调度和管理容器,并且努力达到用户所期望的状态。


工作节点: 工作节点运行执行器(Executor)负责执行具体的容器管理任务(Task),例如容器的启动、停止、删除等操作。


管理节点和工作节点的角色并不是一成不变的,你可以手动将工作节点转换为管理节点,也可以将管理节点转换为工作节点。


Swarm 核心概念

在真正使用 Swarm 之前,我们需要了解几个 Swarm 的核心概念,这些核心概念可以帮助我们更好地学习和理解 Swarm 的设计理念。


Swarm 集群

Swarm 集群是一组被 Swarm 统一管理和调度的节点,被 Swarm纳管的节点可以是物理机或者虚拟机。其中一部分节点作为管理节点,负责集群状态的管理和协调,另一部分作为工作节点,负责执行具体的任务来管理容器,实现用户服务的启停等功能。


节点

Swarm 集群中的每一台物理机或者虚拟机称为节点。节点按照工作职责分为管理节点和工作节点,管理节点由于需要使用 Raft 协议来协商节点状态,生产环境中通常建议将管理节点的数量设置为奇数个,一般为 3 个、5 个或 7 个。


服务

服务是为了支持容器编排所提出的概念,它是一系列复杂容器环境互相协作的统称。一个服务的声明通常包含容器的启动方式、启动的副本数、环境变量、存储、配置、网络等一系列配置,用户通过声明一个服务,将它交给 Swarm,Swarm 负责将用户声明的服务实现。


服务分为全局服务(global services)和副本服务(replicated services)。


全局服务:每个工作节点上都会运行一个任务,类似于 Kubernetes 中的 Daemonset。


副本服务:按照指定的副本数在整个集群中调度运行。


任务

任务是集群中的最小调度单位,它包含一个真正运行中的 Docker 容器。当管理节点根据服务中声明的副本数将任务调度到节点时,任务则开始在该节点启动和运行,当节点出现异常时,任务会运行失败。此时调度器会把失败的任务重新调度到其他正常的节点上正常运行,以确保运行中的容器副本数满足用户所期望的副本数。


服务外部访问

由于容器的 IP 只能在集群内部访问到,而且容器又是用后马上销毁,这样容器的 IP 也会动态变化,因此容器集群内部的服务想要被集群外部的用户访问到,服务必须要映射到主机上的固定端口。Swarm 使用入口负载均衡(ingress load balancing)的模式将服务暴露在主机上,该模式下,每一个服务会被分配一个公开端口(PublishedPort),你可以指定使用某个未被占用的公开端口,也可以让 Swarm 自动分配一个。


Swarm 集群的公开端口可以从集群内的任意节点上访问到,当请求达到集群中的一个节点时,如果该节点没有要请求的服务,则会将请求转发到实际运行该服务的节点上,从而响应用户的请求。公有云的云负载均衡器(cloud load balancers)可以利用这一特性将流量导入到集群中的一个或多个节点,从而实现利用公有云的云负载均衡器将流量导入到集群中的服务。


搭建 Swarm 集群

1f169c1971cc4ff991fdae2771a01987.png

要想使用 Swarm 集群有如下一些要求:


Docker 版本大于 1.12,推荐使用最新稳定版 Docker;


主机需要开放一些端口(TCP:2377 UDP:4789 TCP 和 UDP:7946)。


下面我通过四台机器来搭建一个 Swarm 集群,演示的节点规划如下:


生产环境中推荐使用至少三个 manager 作为管理节点。


第一步:初始化集群


Docker 1.12 版本后, Swarm 已经默认集成到了 Docker 中,因此我们可以直接使用 Docker 命令来初始化 Swarm,集群初始化的命令格式如下:

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

advertise-addr 一般用于主机有多块网卡的情况,如果你的主机只有一块网卡,可以忽略此参数。


在管理节点上,通过以下命令初始化集群:

$ docker swarm init
Swarm initialized: current node (1ehtnlcf3emncktgjzpoux5ga) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-1kal5b1iozbfmnnhx3kjfd3y6yqcjjjpcftrlg69pm2g8hw5vx-8j4l0t2is9ok9jwwc3tovtxbp 192.168.31.100:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

集群初始化后, Swarm 会提示我们当前节点已经作为一个管理节点了,并且提示了如何把一台主机加入集群成为工作节点。


第二步:加入工作节点


按照第一步集群初始化后输出的提示,只需要复制其中的命令即可,然后在剩余的三台工作节点上分别执行如下命令:

$ docker swarm join --token SWMTKN-1-1kal5b1iozbfmnnhx3kjfd3y6yqcjjjpcftrlg69pm2g8hw5vx-8j4l0t2is9ok9jwwc3tovtxbp 192.168.31.100:2377
This node joined a swarm as a worker.

默认加入的节点为工作节点,如果是生产环境,我们可以使用docker swarm join-token manager命令来查看如何加入管理节点:

$ docker swarm join-to ken manager
To add a manager to this swarm, run the following command:
    docker swarm join --token SWMTKN-1-1kal5b1iozbfmnnhx3kjfd3y6yqcjjjpcftrlg69pm2g8hw5vx-8fq89jxo2axwggryvom5a337t 192.168.31.100:2377

复制 Swarm 输出的结果即可加入管理节点到集群中。


注意:管理节点的数量必须为奇数,生产环境推荐使用3个、5个或7个管理节点来管理 Swarm 集群。


第三步:节点查看


节点添加完成后,我们使用以下命令可以查看当前节点的状态:

$ ]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
1ehtnlcf3emncktgjzpoux5ga *   swarm-manager       Ready               Active              Leader              19.03.12
pn7gdm847sfzydqhcv3vma97y *   swarm-node1         Ready               Active                                        19.03.12
4dtc9pw5quyjs5yf25ccgr8uh *   swarm-node2         Ready               Active                                        19.03.12
est7ww3gngna4u7td22g9m2k5 *   swarm-node3         Ready               Active                                        19.03.12

到此,一个包含 1 个管理节点,3 个工作节点的 Swarm 集群已经搭建完成。


使用 Swarm

集群搭建完成后,我们就可以在 Swarm 集群中创建服务了,Swarm 集群中常用的服务部署方式有以下两种。


(1)通过 docker service 命令创建服务

使用docker service create命令可以创建服务,创建服务的命令如下:

$ docker service create --replicas 1 --name hello-world nginx
24f9ng83m9sq4ml3e92k4g5by
overall progress: 1 out of 1 tasks
1/1: running   [==================================================>]
verify: Service converged

此时我们已经创建好了一个服务,使用docker service ls命令可以查看已经启动的服务:

$ docker service ls
ID                  NAME                  MODE                REPLICAS            IMAGE               PORTS
24f9ng83m9sq        hello-world           replicated          1/1                 nginx:latest

当我们不再需要这个服务了,可以使用docker service rm命令来删除服务:

$ docker service rm hello-world
hello-world

此时 hello-world 这个服务已经成功地从集群中删除。

想要了解更多的docker service命令的相关操作,可以参考这里。


生产环境中,我们推荐使用 docker-compose 模板文件来部署服务,这样服务的管理会更加方便并且可追踪,而且可以同时创建和管理多个服务,更加适合生产环境中依赖关系较复杂的部署模式。


(2)通过 docker stack 命令创建服务

我们在 19 课时中创建了 docker-compose 的模板文件,成功的使用该模板文件创建并启动了 MySQL 服务和 WordPress 两个服务。这里我们将 19 讲中的 docker-compose 模板文件略微改造一下:

version: '3'
services:
   mysql:
     image: mysql:5.7
     volumes:
       - mysql_data:/var/lib/mysql
     restart: always
     environment:
       MYSQL_ROOT_PASSWORD: root
       MYSQL_DATABASE: mywordpress
       MYSQL_USER: mywordpress
       MYSQL_PASSWORD: mywordpress
   wordpress:
     depends_on:
       - mysql
     image: wordpress:php7.4
     deploy:
       mode: replicated
       replicas: 2
     ports:
       - "8080:80"
     restart: always
     environment:
       WORDPRESS_DB_HOST: mysql:3306
       WORDPRESS_DB_USER: mywordpress
       WORDPRESS_DB_PASSWORD: mywordpress
       WORDPRESS_DB_NAME: mywordpress
volumes:
    mysql_data: {}
————————————————
版权声明:本文为CSDN博主「MyySophia」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/MyySophia/article/details/121116073

我在服务模板文件中添加了 deploy 指令,并且指定使用副本服务(replicated)的方式启动两个 WordPress 实例。


准备好启动 WordPress 服务的配置后,我们在 /tmp 目下新建 docker-compose.yml 文件,并且写入以上的内容,然后我们使用以下命令启动服务:

$ docker stack deploy -c docker-compose.yml wordpress
Ignoring unsupported options: restart
Creating network wordpress_default
Creating service wordpress_mysql
Creating service wordpress_wordpress

执行完以上命令后,我们成功启动了两个服务:


MySQL 服务,默认启动了一个副本。


WordPress 服务,根据我们 docker-compose 模板的定义启动了两个副本。


下面我们用docker service ls命令查看一下当前启动的服务。

$ docker service ls
ID                  NAME                  MODE                REPLICAS            IMAGE               PORTS
v8i0pzb4e3tc        wordpress_mysql       replicated          1/1                 mysql:5.7
96m8xfyeqzr5        wordpress_wordpress   replicated          2/2                 wordpress:php7.4    *:8080->80/tcp

可以看到,Swarm 已经为我们成功启动了一个 MySQL 服务,并且启动了两个 WordPress 实例。WordPress 实例通过 8080 端口暴露在了主机上,我们通过访问集群中的任意节点的 IP 加 8080 端口即可访问到 WordPress 服务。例如,我们访问http://192.168.31.101:8080即可成功访问到我们搭建的 WordPress 服务。


结语

Docker Swarm 是一个用来定义复杂应用的集群编排工具,可以帮我们把多台主机组成一个 Swarm 集群,并且帮助我们管理和调度复杂的容器服务。由于 Swarm 已经被内置于 Docker 中,因此 Swarm 的安装和使用也变得非常简单,只要你有 Docker 的使用经验,就可以很快地将你的应用迁移到 Swarm 集群中。


相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
1月前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
224 93
|
4天前
|
网络协议 API Docker
Docker+consul容器服务的更新与发现
通过本文的介绍,我们详细探讨了如何结合Docker和Consul来实现容器服务的更新与发现。通过Consul的服务注册和发现功能,可以高效地管理和监控容器化服务,确保系统的高可用性和可扩展性。希望本文能帮助您在实际项目中更好地应用Docker和Consul,提高系统的可靠性和管理效率。
37 23
|
4天前
|
Ubuntu API 网络虚拟化
ubuntu22 编译安装docker,和docker容器方式安装 deepseek
本脚本适用于Ubuntu 22.04,主要功能包括编译安装Docker和安装DeepSeek模型。首先通过Apt源配置安装Docker,确保网络稳定(建议使用VPN)。接着下载并配置Docker二进制文件,创建Docker用户组并设置守护进程。随后拉取Debian 12镜像,安装系统必备工具,配置Ollama模型管理器,并最终部署和运行DeepSeek模型,提供API接口进行交互测试。
90 15
|
2月前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
299 78
|
1月前
|
Ubuntu NoSQL Linux
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
157 6
《docker基础篇:3.Docker常用命令》包括帮助启动类命令、镜像命令、有镜像才能创建容器,这是根本前提(下载一个CentOS或者ubuntu镜像演示)、容器命令、小总结
|
2月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
2月前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
193 35
|
1月前
|
数据库 Docker 容器
docker容器为啥会开机自启动
通过配置适当的重启策略,Docker容器可以在主机系统重启后自动启动。这对于保持关键服务的高可用性和自动恢复能力非常有用。选择适合的重启策略(如 `always`或 `unless-stopped`),可以确保应用程序在各种情况下保持运行。理解并配置这些策略是确保Docker容器化应用可靠性的关键。
62 17
|
2月前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
96 8
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
1月前
|
运维 Java 虚拟化
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
《docker基础篇:1.Docker简介》,包括Docker是什么、容器与虚拟机比较、能干嘛、去哪下
117 12