介绍
Docker Swarm 是 Docker 公司推出的官方容器集群平台,基于 Go 语言实现
作为容器集群管理器,Swarm 最大的优势之一就是 100% 支持标准的 Docker API。各种基于标准 API 的工具比如 Compose、docker-py、各种管理软件,甚至 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 集群
关闭防火墙
[root@master ~]# systemctl stop firewalld.service [root@master ~]# systemctl disable firewalld.service Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service. Removed symlink /etc/systemd/system/basic.target.wants/firewalld.service.
官网示例
[root@master ~]# docker swarm init --advertise-addr 192.168.132.148 Swarm initialized: current node (4c6iv7adv3ha0ejho0f9pu3na) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-2pf6s6myfdn9yx6lekinmvnqmen0vyce8s32bacxw2mdlem30r-d6ch6wkkisacoihs1byrjf0e1 192.168.132.148:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. [root@master ~]# netstat -ntlp |grep 2377 tcp6 0 0 :::2377 :::* LISTEN 2220/dockerd
#节点一 [root@slave1 ~]# docker swarm join --token SWMTKN-1-2pf6s6myfdn9yx6lekinmvnqmen0vyce8s32bacxw2mdlem30r-d6ch6wkkisacoihs1byrjf0e1 192.168.132.148:2377 This node joined a swarm as a worker. #节点二 [root@slave2 ~]# docker swarm join --token SWMTKN-1-2pf6s6myfdn9yx6lekinmvnqmen0vyce8s32bacxw2mdlem30r-d6ch6wkkisacoihs1byrjf0e1 192.168.132.148:2377 This node joined a swarm as a worker.
docker swarm 命令
命令 说明 docker swarm init 初始化集群 docker swarm join-token worker 查看工作节点的 token docker swarm join-token manager 查看管理节点的 token docker swarm join 加入集群中
查看集群
[root@master ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 4c6iv7adv3ha0ejho0f9pu3na * master Ready Active Leader ezr1hf1prwzuisbjquhtd8qsq slave1 Ready Active s9wxeakddde48z212r09j9zga slave2 Ready Active
docker node 命令
命令 说明 docker node ls 查看所有集群节点 docker node rm 删除某个节点(-f强制删除) docker node inspect 查看节点详情 docker node demote 节点降级,由管理节点降级为工作节点 docker node promote 节点升级,由工作节点升级为管理节点 docker node update 更新节点 docker node ps 查看节点中的 Task 任务
部署服务
$ docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine
现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。
查看service
[root@master ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS 71vkd0ywfphg nginx replicated 3/3 nginx:1.13.7-alpine *:80->80/tcp
查看服务详情
[root@master ~]# docker service ps nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS nikyvqah8k5n nginx.1 nginx:latest slave2 Running Preparing 3 minutes ago 7fjgztll22f7 nginx.2 nginx:latest master Running Preparing 35 seconds ago gyl1vb9nguzs nginx.3 nginx:latest slave1 Running Preparing less than a second ago
查看日志
[root@master ~]# docker service logs nginx
服务扩容与缩减
#扩容 $ docker service scale nginx=5 #缩减 $ docker service scale nginx=2
删除服务
[root@master ~]# docker service rm nginx nginx [root@master ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker service命令
命令 说明 docker service create 部署服务 docker service inspect 查看服务详情 docker service logs 产看某个服务日志 docker service ls 查看所有服务详情 docker service rm 删除某个服务(-f强制删除) docker service scale 设置某个服务个数 docker service update 更新某个服务
使用docker-compose
[root@master ~]# cat docker-compose.yml version: "3" services: wordpress: image: wordpress ports: - 80:80 networks: - overlay environment: WORDPRESS_DB_HOST: db:3306 WORDPRESS_DB_USER: wordpress WORDPRESS_DB_PASSWORD: wordpress deploy: mode: replicated replicas: 3 db: image: mysql networks: - overlay volumes: - db-data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD: somewordpress MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD: wordpress deploy: placement: constraints: [node.role == manager] visualizer: image: dockersamples/visualizer:stable ports: - "8080:8080" stop_grace_period: 1m30s volumes: - "/var/run/docker.sock:/var/run/docker.sock" deploy: placement: constraints: [node.role == manager] volumes: db-data: networks: overlay: #部署服务使用docker stack deploy
,其中-c
参数指定 compose 文件名。 [root@master ~]# docker stack deploy -c docker-compose.yml wordpress Creating network wordpress_default Creating network wordpress_overlay Creating service wordpress_visualizer Creating service wordpress_wordpress Creating service wordpress_db
docker stack 常用命令
命令 说明
docker stack deploy 部署新的堆栈或更新现有堆栈
docker stack ls 列出现有堆栈
docker stack ps 列出堆栈中的任务
docker stack rm 删除堆栈
docker stack services 列出堆栈中的服务
docker stack down 移除某个堆栈(不会删除数据)
现在我们打开浏览器输入 任一节点IP:8080
即可看到各节点运行状态。如下图所示:
滚动升级
使用上面创建的nginx服务作为基础
#升级
$ docker service update --image nginx:1.13.12-alpine nginx
#如果升级后发生问题,回退$ docker service rollback nginx
swarm过滤器
过滤器分为两类,节点过滤器和容器配置过滤器。节点过滤器根据Docker主机的特性或Docker守护程序的配置进行操作。容器配置过滤器根据容器的特征或主机上的image可用性进行操作。
每个过滤器都有一个标识它的名称。节点过滤器是:
-
constraint #用来选择进行调度的节点子集
health
containerslots
容器配置过滤器是:
affinity
dependency
port
使用过滤器时,通过传递--filter标志和名称来指定过滤的子集
$ swarm manage --filter=health --filter=dependency #包括已经停止的容器
示例将某镜像拉倒某个节点上
$ docker -H node-1:2375 pull redis $ docker -H node-2:2375 pull mysql $ docker -H node-3:2375 pull redis
constraint
以下示例说明了一些可能的表达式: constraint:node==node1 匹配节点node1。 constraint:node!=node1 匹配所有节点,除了node1。 constraint:region!=us* 使用带有region前缀的标记匹配外部的所有节点us。 constraint:node==/node[12]/ 匹配节点node1和node2。 constraint:node==/noded/ 匹配所有节点node+ 1位数。 constraint:node!=/node-[01]/ 匹配所有节点,除了node-0和node-1。 constraint:node!=/foo[bar]/ 匹配所有节点,除了foo[bar]。你可以在这里看到转义字符的使用。 constraint:node==/(?i)node1/ 匹配节点node1不区分大小写。所以NoDe1还是NODE1匹配。 affinity:image==~redis 尝试匹配运行容器的节点与redis图像。 constraint:region==~us* 搜索属于该us区域的群集中的节点。 affinity:container!=~redis* 将新redis5容器安排到没有满足容器的节点redis*。
根据节点daemon中设置的标签名来选择启用的节点
version: "2" services: mongodb: image: mongo:latest environment: - "constraint:com.example.storage==ssd" #指定标签为ssd的节点
#这里表示在docker的启动配置文件中设定如下标签
DOCKER_OPTS="$DOCKER_OPTS --label com.example.environment='production' --label com.example.storage="ssd" "
可以使用集群节点的名称来启动,省去了配置 label。
docker service create --name xxx --constraint node.hostname==swarm1 xxx