一、简介
1. 什么是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 团队可以更好地管理可用的主机资源,保证应用容器的高效运行。
Swarm的基本架构如下图所示:
2. 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 镜像。
二、相关概念
1. 节点
有两种类型的节点: managers 和 workers.
管理节点(managers)
管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
为了利用swarm模式的容错功能,Docker建议您根据组织的高可用性要求实现奇数个节点。当您拥有多个管理器时,您可以从管理器节点的故障中恢复而无需停机。
- N个管理节点的集群容忍最多损失 (N-1)/2 个管理节点。
- Docker建议一个集群最多7个管理器节点。
重要说明:添加更多管理节点并不意味着可扩展性更高或性能更高。一般而言,情况正好相反。
工作节点(workers)
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。下图展示了集群中管理节点与工作节点的关系。
2. 服务和任务
任务 (Task)是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
服务 (Services) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式:
- replicated services (复制服务)按照一定规则在各个工作节点上运行指定个数的任务。
- global services (全局服务)每个工作节点上运行一个任务。
两种模式通过 docker service create 的 --mode 参数指定。下图展示了容器、任务、服务的关系。
三、Swarm 集群
准备工作
- 三个可以通过网络进行通信的Linux主机或虚拟机,并安装了Docker,或者使用docker-machine 创建三台虚拟机。
- 已安装Docker Engine 1.12或更高版本
- 在主机之间打开端口(2377、7946、4789)
创建一个集群
1. 创建虚拟机(已经有Linux主机或虚拟机的跳过此步)
通过docker-machine使用VirtualBox驱动程序创建3个VM (已经有Linux主机或虚拟机的跳过此步):
docker-machine create --driver virtualbox myvm-1 docker-machine create --driver virtualbox myvm-2 docker-machine create --driver virtualbox myvm-3
列出虚拟机并获取其IP地址:
docker-machine ls
以下是此命令的示例输出:
$docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS myvm-1 - virtualbox Running tcp://10.10.185.111:2376 v19.03.8 myvm-2 - virtualbox Running tcp://10.10.192.12:2376 v19.03.8
myvm-3 - virtualbox Running tcp://10.10.192.13:2376 v19.03.8
已经有的虚拟机为了好区分,需要先将主机名进行修改
[root@localhost sbin]# hostname localhost [root@localhost sbin]# hostnamectl set-hostname kycx185manage [root@localhost sbin]# hostname kycx185manage
2. 初始化swarm
把第一台机器myvm-1充当管理节点,第二台myvm-2 、第三台myvm-3为工作节点。
使用 docker-machine ssh 连接 myvm-1,Linux主机直接ssh连接就行。
docker-machine ssh myvm-1
初始化swarm
docker swarm init --advertise-addr 10.10.185.111 Swarm initialized: current node (yvkx9sr1luzofxdtz1o0h34w9) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-3u15etardpg9k51afbfewj985t1vhf60p5g10pses0y9x46ghg-0orvff38nna4ggv2xzvz681vt 10.10.185.111:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
上面输出的这一段就是工作节点加入集群的命令:
docker swarm join --token SWMTKN-1-3u15etardpg9k51afbfewj985t1vhf60p5g10pses0y9x46ghg-0orvff38nna4ggv2xzvz681vt 10.10.185.111:2377
如果你的 Docker 主机有多个网卡,拥有多个 IP,必须使用 --advertise-addr 指定 IP。
执行 docker swarm init 命令的节点自动成为管理节点。
命令 docker info 可以查看 swarm 集群状态:
[root@localhost ~]# docker info Client: Debug Mode: false Server: Containers: 2 Running: 2 Paused: 0 Stopped: 0 Images: 3 Server Version: 19.03.8 Storage Driver: overlay2 Backing Filesystem: <unknown> 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: yvkx9sr1luzofxdtz1o0h34w9 Is Manager: true ClusterID: qhj62ncygxunm59hplhosuw9i 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: 10.10.185.111 Manager Addresses: 10.10.185.111:2377 Runtimes: runc Default Runtime: runc Init Binary: docker-init containerd version: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc version: dc9208a3303feef5b3839f4323d9beb36df0a9dd 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: 2 Total Memory: 15.51GiB Name: localhost ID: X6LV:54KJ:RIXA:64DG:M4GF:HXV3:UKRM:GTR7:GGBQ:RMGK:MPES:GNVD 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 Live Restore Enabled: false WARNING: bridge-nf-call-iptables is disabled WARNING: bridge-nf-call-ip6tables is disabled
命令 docker node ls 可以查看集群节点信息:
[root@localhost ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION yvkx9sr1luzofxdtz1o0h34w9 * localhost Ready Active Leader 19.03.8
工作节点加入 swarm 集群
[root@localhost ~]# docker swarm join --token SWMTKN-1-3u15etardpg9k51afbfewj985t1vhf60p5g10pses0y9x46ghg-0orvff38nna4ggv2xzvz681vt 10.10.185.111:2377 This node joined a swarm as a worker.
节点myvm-3,执行myvm-2相同的操作加入集群
集群的大部分命令需要在管理节点中才能运行
1、我们进入管理节点 myvm-1 ,查看集群的节点信息。
[root@localhost sbin]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION yvkx9sr1luzofxdtz1o0h34w9 * kycx185manage Ready Active Leader 19.03.8 ngwd7l3z3kzcz6jzfc9elbtbg kycxnode91 Ready Active 19.03.8 w545kl9t966y2gc3v60ettf3l kycxnode111 Ready Active 19.03.8 [root@localhost sbin]#
2、编辑主机上的docker 文件
vi /usr/lib/systemd/system/docker.service
docker.service 文件中将 ExecStart 修改为如下内容
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
3、初始化文件生效
systemctl daemon-reload
4. 重启docker服务
systemctl restart docker
5、安装portainer
说明一下portainer
docker针对于系统工程师或者开发人员来说操作比较简单。一般我们习惯了对着黑黑的屏幕敲命令,docker pull,docker push,docker run,docker logs,docker ps等等。或者我们将常用的docker原生api封装到我们的shell脚本工具或者python脚本工具中去使用管理docker。然而对于部分用户,或者说非技术用户去使用docker难度其实不小。因此一个明了的可视化管理界面显得非常重要了。万物诞生总有其诞生的理由。可能只是为了服务某部分人。
Docker 图形化管理提供了很多工具,有Portainer、Docker UI、Shipyard等等,下面主要介绍Portainer。
Portainer是一个开源、轻量级Docker管理用户界面,基于Docker API,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
官网:https://www.portainer.io/documentation/
docker查找portainer 镜像
docker search portainer
# docker拉取 最新镜像
docker pull portainer/portainer
6、启动portainer
portainer集群方式启动(这里我喜欢通过简单启动的方式,然后在界面上进行节点的添加):
docker volume create portainer_data #创建数据卷
#/var/lib/docker/volumes/portainer_data
docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer #启动 将数据卷挂载到portainer 数据上,这样重启后数据仍然是存在的
命令解释
-d:容器在后台运行; -p 9000:9000 :宿主机9000端口映射容器中的9000端口 -v /var/run/docker.sock:/var/run/docker.sock :把宿主机的Docker守护进程(Docker daemon)默认监听的Unix域套接字挂载到容器中; -v portainer_data:/data :把宿主机portainer_data数据卷挂载到容器/data目录;
访问 ip:9999 进入 portainer的管理界面
首先设置用户名密码
7、选择remote 输入名称和对应的主机的ip:2375 如果没有进行 上面的第二部会出现如下错误
这里出现这个错误解决办法:
1、查看 防火墙2375 端口是否打开
2、下图操作是否执行
docker 重启后再次访问应该就没问题了
8、
到此集群搭建完毕
将节点停用,该节点上的容器会迁移到其他节点
docker node update --availability drain node_t_1
当node_t_1的容器都迁移完后,停止docker服务
systemctl stop docker.service #停止docker服务(删除节点前,需先停该节点的docker服务)
登录到docker-manage 节点上上,将节点node_t_37降级成worker,然后删除。只能删除worker基本的节点。
docker node demote node_t_37 # 降级 docker node rm node_t_37 #删除