Docker Swarm
实践中会发现,生产环境中使用单个 Docker 节点是远远不够的,搭建 Docker 集群势在必行。然而,面对 Kubernetes, Mesos 以及 Swarm 等众多容器集群系统,我们该如何选择呢?它们之中,Swarm 是 Docker 原生的,同时也是最简单,最易学,最节省资源的,比较适合中小型公司使用。
Docker Swarm 介绍
Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。
Docker Swarm 是一个为 IT 运维团队提供集群和调度能力的编排工具。用户可以把集群中所有 Docker Engine 整合进一个「虚拟 Engine」的资源池,通过执行命令与单一的主 Swarm 进行沟通,而不必分别和每个 Docker Engine 沟通。在灵活的调度策略下,IT 团队可以更好地管理可用的主机资源,保证应用容器的高效运行。
Docker Swarm 优点
任何规模都有高性能表现
对于企业级的 Docker Engine 集群和容器调度而言,可拓展性是关键。任何规模的公司——不论是拥有五个还是上千个服务器——都能在其环境下有效使用 Swarm。
经过测试,Swarm 可拓展性的极限是在 1000 个节点上运行 50000 个部署容器,每个容器的启动时间为亚秒级,同时性能无减损。
灵活的容器调度
Swarm 帮助 IT 运维团队在有限条件下将性能表现和资源利用最优化。Swarm 的内置调度器(scheduler)支持多种过滤器,包括:节点标签,亲和性和多种容器部策略如 binpack、spread、random 等等。
服务的持续可用性
Docker Swarm 由 Swarm Manager 提供高可用性,通过创建多个 Swarm master 节点和制定主 master 节点宕机时的备选策略。如果一个 master 节点宕机,那么一个 slave 节点就会被升格为 master 节点,直到原来的 master 节点恢复正常。
此外,如果某个节点无法加入集群,Swarm 会继续尝试加入,并提供错误警报和日志。在节点出错时,Swarm 现在可以尝试把容器重新调度到正常的节点上去。
和 Docker API 及整合支持的兼容性
Swarm 对 Docker API 完全支持,这意味着它能为使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用户提供无缝衔接的使用体验。
Docker Swarm 为 Docker 化应用的核心功能(诸如多主机网络和存储卷管理)提供原生支持。开发的 Compose 文件能(通过 docker-compose up )轻易地部署到测试服务器或 Swarm 集群上。Docker Swarm 还可以从 Docker Trusted Registry 或 Hub 里 pull 并 run 镜像。
综上所述,Docker Swarm 提供了一套高可用 Docker 集群管理的解决方案,完全支持标准的 Docker API,方便管理调度集群 Docker 容器,合理充分利用集群主机资源。
** 并非所有服务都应该部署在Swarm集群内。数据库以及其它有状态服务就不适合部署在Swarm集群内。**
相关概念
节点
运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。节点分为管理 (manager) 节点和工作 (worker) 节点。
管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。下图展示了集群中管理节点与工作节点的关系。
服务和任务
任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:
- replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
- global services 每个工作节点上运行一个任务
两种模式通过 docker service create 的 --mode 参数指定。下图展示了容器、任务、服务的关系。
-
Swarm主要概念
开始使用Swarm模式
- 本教程进行如下指导:
- 在swarm模式下初始化一个基于docker引擎的swarm集群
- 在swarm集群中添加节点
- 部署应用服务到swarm集群中
- 管理swarm集群
-
本教程使用docker命令行的方式交互
安装
- 安装环境要求:
- 3台可以网络通信的Linux主机,并且安装了docker
- 安装1.12.0以上的docker
- 管理节点的IP地址
-
主机之间开放端口
准备3台主机
-
3台主机可以是物理机,虚拟机,云主机,甚至是docker machine创建的主机。并安装docker。三台主机分别是manager1,work1和worker2.
安装1.12.0以上的docker
-
管理节点的IP地址
-
所有swarm集群中的节点都会连接到管理节点的IP地址
主机间开放端口
- 以下端口必须是开放的:
- TCP port 2377为集群管理通信
- TCP and UDP port 7946 为节点间通信
- UDP port 4789 为网络间流量
-
如果你想使用加密网络(--opt encrypted)也需要确保ip protocol 50 (ESP)是可用的
创建 Swarm 集群
我们知道 Swarm 集群由管理节点和工作节点组成。我们来创建一个包含一个管理节点和三个工作节点的 Swarm 集群。
主机名 | ip | docker版本 |
docker-01 | 192.168.1.220 | Docker version 19.03.5, build 633a0ea |
docker-02 | 192.168.1.221 | Docker version 19.03.5, build 633a0ea |
docker-3 | 192.168.1.222 | Docker version 19.03.5, build 633a0ea |
Swarm安装
最简单的安装Swarm的方式就是用Docker官方提供的Swarm镜像:
在docker-01上创建swarm集群:
[root@docker-01 ~]# docker pull swarm Using default tag: latest latest: Pulling from library/swarm d85c18077b82: Pull complete 1e6bb16f8cb1: Pull complete 85bac13497d7: Pull complete Digest: sha256:b866583a3b8791bcd705b7bc0fd94c66b695a1a2dbaeb5f59ed29940e5015dc8 Status: Downloaded newer image for swarm:latest docker.io/library/swarm:latest
[root@docker-01 ~]# docker swarm init --advertise-addr 192.168.1.220 Swarm initialized: current node (1uq9yw9myh00euj03q7cxbrcf) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-32dpobcq80dznz72zxhfbsgcjgxn727qj5ribneljr146wdbrf-da7lj2na0pir82tu445v84794 192.168.1.220:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
- --advertise-addr选项表示管理节点公布它的IP是多少。其它节点必须能通过这个IP找到管理节点。
- 命令输出了加入swarm集群的命令。通过--token选项来判断是加入为管理节点还是工作节点
docker-01上运行docker info来查看当前swarm集群的状态:
[root@docker-01 ~]# docker info Client: Debug Mode: false Server: Containers: 0 Running: 0 Paused: 0 Stopped: 0 Images: 2 Server Version: 19.03.5 Storage Driver: overlay2 Backing Filesystem: xfs Supports d_type: true Native Overlay Diff: true Logging Driver: json-file Cgroup Driver: cgroupfs Plugins: Volume: local Network: bridge host ipvlan macvlan null overlay Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog Swarm: active NodeID: 1uq9yw9myh00euj03q7cxbrcf Is Manager: true ClusterID: ofgwmoilz3v44fbjeyvjkw0ba Managers: 1 Nodes: 1 Default Address Pool: 10.0.0.0/8 SubnetSize: 24 Data Path Port: 4789 Orchestration: Task History Retention Limit: 5 Raft: Snapshot Interval: 10000 Number of Old Snapshots to Retain: 0 Heartbeat Tick: 1 Election Tick: 10 Dispatcher: Heartbeat Period: 5 seconds CA Configuration: Expiry Duration: 3 months Force Rotate: 0 Autolock Managers: false Root Rotation In Progress: false Node Address: 192.168.1.220 Manager Addresses: 192.168.1.220:2377 Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: b34a5c8af56e510852c35414db4c1f4fa6172339 runc version: 3e425f80a8c931f88e6d94a8c831b9d5aa481657 init version: fec3683 Security Options: seccomp Profile: default Kernel Version: 3.10.0-693.el7.x86_64 Operating System: CentOS Linux 7 (Core) OSType: linux Architecture: x86_64 CPUs: 1 Total Memory: 472.3MiB Name: docker-01 ID: KNRU:KXQ4:LJ3E:7XNP:6HEF:K444:SUBM:OUPS:JIEC:KXIT:GLPT:42MD Docker Root Dir: /var/lib/docker Debug Mode: false Registry: https://index.docker.io/v1/ Labels: Experimental: false Insecure Registries: 127.0.0.0/8 Registry Mirrors: https://4ym6pzzt.mirror.aliyuncs.com/ Live Restore Enabled: false WARNING: bridge-nf-call-ip6tables is disabled
解决WARNING: bridge-nf-call-ip6tables is disabled
[root@docker-01 ~]# vi /etc/sysctl.conf net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 [root@docker-01 ~]# sysctl -p
docker-01运行docker node ls来查看节点信息:
[root@docker-01 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 1uq9yw9myh00euj03q7cxbrcf * docker-01 Ready Active Leader 19.03.5
nodeId旁边的*号表示你当前连接到的节点。
docker引擎的swarm模式自动使用宿主机的主机名作为节点名。
将节点加入到swarm集群中
一旦前面的创建swarm集群完成,你就可以加入工作节点了。
运行创建swarm集群时候产生的命令来将woker1加入到集群中:
docker-02上执行
[root@docker-02 ~]# docker swarm join --token SWMTKN-1-32dpobcq80dznz72zxhfbsgcjgxn727qj5ribneljr146wdbrf-da7lj2na0pir82tu445v84794 192.168.1.220:2377 This node joined a swarm as a worker.
docker-02上执行
[root@docker-03 ~]# docker swarm join --token SWMTKN-1-32dpobcq80dznz72zxhfbsgcjgxn727qj5ribneljr146wdbrf-da7lj2na0pir82tu445v84794 192.168.1.220:2377 This node joined a swarm as a worker.
如果你找不到加入命令了,可以在管理节点(docker-o1)运行下列命令找回加入命令:
[root@docker-01 ~]# docker swarm join-token worker To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-32dpobcq80dznz72zxhfbsgcjgxn727qj5ribneljr146wdbrf-da7lj2na0pir82tu445v84794 192.168.1.220:2377
到docker-01节点运行docker node ls命令来查看集群节点情况
[root@docker-01 ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION 1uq9yw9myh00euj03q7cxbrcf * docker-01 Ready Active Leader 19.03.5 iv7pd6c9cek3jgubyunpodhr2 docker-02 Ready Active 19.03.5 e9sgwrqdpkec42goqtjijgxjm docker-03 Ready Active 19.03.5 [root@docker-01 ~]#
MANAGER列表明了集群中的管理节点。worker节点的空意味着它们是工作节点