一、Swarm
Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源。Swarm和Kubernetes比较类似,但是更加轻,具有的功能也较kubernetes更少一些。
Swarm 在 Docker 1.12 版本之前属于一个独立的项目,在 Docker 1.12 版本发布之后,该项目合并到了 Docker 中,成为 Docker 的一个子命令。目前,Swarm 是 Docker 社区提供的唯一一个原生支持 Docker 集群管理的工具。它可以把多个 Docker 主机组成的系统转换为单一的虚拟 Docker 主机,使得容器可以组成跨主机的子网网络。
2016年核心团队发现中央服务的扩展被限制之后,Swarm 在内部被再次重新设计为Swarm2,使用了去中心化的集群设计,允许构造数千个节点的集群;随后又发布了SwarmKit(可以作为任规模的分布式服务的编排工具包),将其合并到了Docker Engine,Docker Swarm在设计上遵从了可插拔的设计思想,安装集群只需要启动几个docker就可以完成。
文档地址:https://docs.docker.com/swarm/
swarm:是一组docker引擎的集群
node:是单个docker引擎的实例,可以在一个物理机上也可以在多个
application:是应用
manager node:部署应用的时候会有一个manager node节点
Worker nodes:对应的就是Worker nodes
service:然后service是一堆被workder执行的任务
replicated services:是负载均衡节点
global services:则是全局的,在所有节点上都会执行的一个服务
task:一个task就是一个docker的容器,是Swarm的工作单元
二、Swarm安装搭建
- 前置条件:
3台网络互通的宿主机
节点 | IP地址 | 主机名 |
---|---|---|
管理节点 | 192.168.77.129 | manager |
工作节点 | 192.168.77.132 | node1 |
工作节点 | 192.168.77.128 | node2 |
安装1.12或更高版本的docker
开启宿主机之间的端口(TCP端口2377集群管理端口)
使用三台机器创建一个Docker集群,其中192.168.77.129 同时充当swarm manager管理集群。
- Swarm安装
最简单的安装Swarm的方式就是用Docker官方提供的Swarm镜像:
[root@localhost ~]# 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
编辑三台机器的/etc/hosts文件,内容修改为:
192.168.77.129 manager
192.168.77.132 node1
192.168.77.128 node2
在manager节点初始化集群:
[root@manager ~]# docker swarm init --advertise-addr 192.168.77.129
Swarm initialized: current node (1ju7orjjswgyq9zki2a51mcdh) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-0dks8scy6jujjgfa6vp5xk4po5nq1s97iruz57882f4icqndlh-aj5ku11jcrwyk370m31rl3j2h \
192.168.77.129:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
通过以上命令获取Token。
在另外两个工作节点执行:
docker swarm join \
--token SWMTKN-1-0dks8scy6jujjgfa6vp5xk4po5nq1s97iruz57882f4icqndlh-aj5ku11jcrwyk370m31rl3j2h \
192.168.77.129:2377
执行docker node ls查看集群信息:(必须在管理节点执行)
[root@manager ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
1ju7orjjswgyq9zki2a51mcdh * manager Ready Active Leader
nvqgwl728dx24s1y0zl3dahxj node2 Ready Active
x0jz14lvk4cqq0eoao97wt0ae node1 Ready Active
- 部署测试
在管理节点执行:
创建一个apache服务:
# 拉取镜像
[root@manager ~]# docker pull httpd
[root@manager ~]# docker service create -p 80:80 --name webserver --replicas 5 httpd:latest
frawkw0wszlxqq7w96l6x9054
1. manifest unknown: manifest unknown
原因:镜像没有拉取下来,请使用docker pull httpd在每个机子里拉取镜像。
查看集群中的service:
docker service ls
查看集群中的指定服务:
# docker service ps 服务名称
[root@manager ~]# docker service ps webserver
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ej91lh0fgb68 webserver.1 httpd manager Running Preparing 3 minutes ago
vp6tbyxoav11 webserver.2 httpd node2 Running Preparing 3 minutes ago
bs8mos3x8bd6 webserver.3 httpd node1 Running Preparing 3 minutes ago
25ohgjsjxtqx webserver.4 httpd node2 Running Preparing 3 minutes ago
iluycd4z114t webserver.5 httpd node1 Running Preparing 3 minutes ago
访问:
http://192.168.77.129
http://192.168.77.132
http://192.168.77.128
三、Docker Hub内置的服务发现功能
- 创建集群标志
在任何一个节点上面执行swarm create
命令来创建一个集群标志。这条命令执行完毕之后,swarm会前往Docker Hub
上内建的发现服务中获取一个全球唯一的token,用以唯一的标识swarm管理的Docker集群。
docker run --rm swarm create
返回的token
是d947b55aa8fb9198b5d13ad81f61ac4d,这个token一定要记住,因为接下来的操作都会用到这一个token。
- 加入集群(节点)
在所有的要加入集群的机器上面执行swarm join
命令,把机器加入集群。
本次试验就是要在所有的三台机器上执行命令。
docker run –-rm swarm join –addr=ip_address:2375 token://d947b55aa8fb9198b5d13ad81f61ac4d
执行这条命令后不会立即返回 ,我们手动通过Ctrl+C返回。
- 启动swarm manager
因为我们要让192.168.77.129
充当Swarm管理节点,所以我们要在这台机器
上面执行swarm manage命令:
docker run –d –p 2376:2375 swarm manage token:// d947b55aa8fb9198b5d13ad81f61ac4d
重点内容需要注意的是:
第一:要以daemon的形式运行swarm;
第二:端口映射:2376可以更换成任何一个本机没有占用的端口
,一定不能是2375,否则就会出问题。
执行完这个命令之后,整个集群已经启动起来了。
现在可以在任何一个节点上查看集群上的所有节点了。
之后可以在任何一台安装了docker的机器上面通过命令(命令中要指明swarm maneger 机器的IP地址和端口
)在这个集群上面运行Dcoker容器操作。
现在在192.168.77.129这台机器上面查看集群的节点的信息。
info命令可以换成任何一个Swarm支持的docker命令。
# 远程连接,查看节点镜像信息
[root@manager ~]# docker -H tcp://192.168.77.132:2375 images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 66a97eeec7b8 28 hours ago 154 MB
- 获取Token与常用命令
Join tokens是允许一个节点加入集群的密钥。有两种可用的不同的join tokens,一个是用作worker角色,另一个是用作manager角色。在执行swarm join时使用–token来传递token。节点只在它们加入集群时才使用这个token。
swarm join-token :可以查看或更换join token。
docker swarm join-token worker:查看加入woker的命令。
docker swarm join-token manager:查看加入manager的命令
docker swarm join-token --rotate worker:重置woker的Token。
docker swarm join-token -q worker:仅打印Token。
四、文件配置服务发现功能
- 添加文件
在192.168.77.129这台机器上新建一个文件,把要加入集群的机器的IP地址写进去:
在192.168.77.129这台机器上面执行swarm manage命令:
$ sudo docker run –d –p 2376:2375 –v $(pwd)/cluster:/tmp/cluster swarm manage file:///tmp/cluster
注意:这里一定要使用-v命令,因为cluster文件是在本机上面,启动的容器默认是访问不到的,所以要通过-v命令共享。还有,file:///千万不能忘记了。
可以看到,swarm已经运行起来了。现在可以查看下集群节点信息了,使用命令:
$ sudo docker run –rm –v $(pwd)/cluster:/tmp/cluster swarm list file:///tmp/cluster
(在使用文件作为服务发现的时候,貌似manage list命令只能在swarm manage节点上使用,在其他节点上用不了)
现在集群也已经运行起来了,可以跟第一种方法一样在其他机器上使用集群了。同样在其它机器上做测试。
五、Swarm调度策略
Swarm在schedule节点运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, random.
Random
顾名思义,就是随机选择一个Node来运行容器,一般用作调试用,spread和binpack
策略会根据各个节点的可用的CPU, RAM以及正在运行的容器的数量来计算应该运行容器的节点。
在同等条件下,Spread策略会选择运行容器最少的那台节点来运行新的容器,binpack策略会选择运行容器最集中的那台机器来运行新的节点(The binpack strategy causes Swarm to optimize for the container which is most packed.)。
使用Spread策略会使得容器会均衡的分布在集群中的各个节点上运行,一旦一个节点挂掉了只会损失少部分的容器。
Binpack策略最大化的避免容器碎片化,就是说binpack策略尽可能的把还未使用的节点留给需要更大空间的容器运行,尽可能的把容器运行在一个节点上面。
三、Web管理
Portainer简介
Portainer是Docker的图形化管理工具,提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作(包括上传下载镜像,创建容器等操作)、事件日志显示、容器控制台操作、Swarm集群和服务等集中管理和操作、登录用户管理和控制等功能。功能十分全面,基本能满足中小型单位对容器管理的全部需求。
地址:https://www.portainer.io/installation/安装Portainer
拉取镜像:
[root@manager ~]# docker pull docker.io/portainer/portainer
布署portainer:
[root@manager ~]# sudo 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
访问:
http://192.168.77.129:9000
密码设置为:
admin1234
单机版这里选择local即可,选择完毕,点击Connect即可连接到本地docker。
如果是集群选择【Remote】选项,在Environment内容中输入自定义名称Name以及这个IP地址URL信息Endpoint URL,例如192.168.77.129:2375。注意该机器要开放2375端口防火墙访问权限。
-
节点操作
-
容器列表
点击容器列表中的容器名Name,即可查看容器详情:
-
镜像列表
在镜像列表可以直接pull一个镜像,可以从远程pull,也可以从私有库中pull。从私有库中pull,需要将私有库的地址提前进行配置:
点击镜像ID,即可查看镜像详情信息,在详情信息页面,除了镜像的一些信息外,还可以对该镜像进行打标签tag操作,然后将镜像push到远程仓库或者私有仓库中。
-
仓库管理
该界面可以查看配置的镜像仓库列表,同时可以添加仓库,添加成功之后,即可在image镜像页面进行pull、push操作。
集群运行
更多的情况下,我们会有一个docker集群,可能有几台机器,也可能有几十台机器,因此,进行集群管理就十分重要了,Portainer也支持集群管理,Portainer可以和Swarm一起来进行集群管理操作。
前置条件:搭建了一个Swarm。
如果是集群方式启动,建议portainer安装启动在Swarm管理节点,并且首次设置Endpoint URL时设置管理节点的URL。
四、Docker Swarm 常用命令
- 管理配置文件
# 管理配置文件
docker config
# 查看已创建配置文件
docker config ls
# 将已有配置文件添加到docker配置文件中
docker config create docker 配置文件名 本地配置文件
- 管理swarm节点
# 管理swarm节点
docker node
# 查看集群中的节点
docker node ls
# 将manager角色降级为worker
docker node demote 主机名
# 将worker角色升级为manager
docker node promote 主机名
# 查看节点的详细信息,默认json格式
docker node inspect 主机名
# 查看节点信息平铺格式
docker node inspect --pretty 主机名
# 查看运行的一个或多个及节点任务数,默认当前节点
docker node ps
# 从swarm中删除一个节点
docker node rm 主机名
# 更新一个节点
docker node update
# 对节点设置状态(“active”正常|“pause”暂停|“drain”排除自身work任务)
docker node update --availability
- 管理敏感数据存储
# 管理敏感数据存储
docker secret
# 服务栈,栈的形式,一般作为编排使用,格式与docker compose相同。
docker stack
# 通过.yml文件指令部署
docker stack deploy -c 文件名.yml 编排服务名
# 查看编排服务
docker stack ls
- 集群管理
# 作为集群的管理
docker swarm
# 初始化一个swarm
docker swarm init
# 指定初始化ip地址节点
docker swarm init --advertise-addr 管理端IP地址
# 去除本地之外的所有管理器身份
docker swarm init --force-new-cluster
# 将节点加入swarm集群,两种加入模式manager与worker
docker swarm join
# 工作节点加入管理节点需要通过join-token认证
docker swarm join-token
# 重新获取docker获取初始化命令
docker swarm join-token worker
# 离开swarm
docker swarm leave
# 对swarm集群更新配置
docker swarm update
- 服务管理
# 服务管理
docker service
# 创建一个服务
docker service create
# 创建的副本数
docker service create --replicas 副本数
# 指定容器名称
docker service create --name 名字
# 每次容器与容器之间的更新时间间隔。
docker service create --update-delay s秒
# 更新时同时并行更新数量,默认1
docker service create --update-parallelism 个数
# 任务容器更新失败时的模式,(“pause”停止|”continue“继续),默认pause。
docker service create --update-failure-action 类型
# 每次容器与容器之间的回滚时间间隔。
docker service create --rollback-monitor 20s
# 回滚故障率如果小于百分比允许运行
docker service create --rollback-max-failure-ratio .数值(列“.2”为%20)
# 添加网络
docker service create --network 网络名
# 创建volume类型数据卷
docker service create --mount type=volume,src=volume名称,dst=容器目录
# 创建bind读写目录挂载
docker service create --mount type=bind,src=宿主目录,dst=容器目录
# 创建bind只读目录挂载
docker service create --mount type=bind,src=宿主目录,dst=容器目录,readonly
# 创建dnsrr负载均衡模式
docker service create --endpoint-mode dnsrr 服务名
# 创建docker配置文件到容器本地目录
docker service create --config source=docker配置文件,target=配置文件路径
# 创建添加端口
docker service create --publish 暴露端口:容器端口 服务名
# 查看服务详细信息,默认json格式
docker service inspect
# 查看服务信息平铺形式
docker service inspect --pretty 服务名
# 查看服务内输出
docker service logs
# 列出服务
docker service ls
# 列出服务任务信息
docker service ps
# 查看服务启动信息
docker service ps 服务名
# 过滤只运行的任务信息
docker service ps -f "desired-state=running" 服务名
# 删除服务
docker service rm 服务名
# 缩容扩容服务
docker service scale
# 扩展服务容器副本数量
docker service scale 服务名=副本数
# 更新服务相关配置
docker service update
# 容器加入指令
docker service update --args “指令” 服务名
# 更新服务容器版本
docker service update --image 更新版本 服务名
# 回滚服务容器版本
docker service update --rollback 回滚服务名
# 添加容器网络
docker service update --network-add 网络名 服务名
# 删除容器网络
docker service update --network-rm 网络名 服务名
# 服务添加暴露端口
docker service update --publish-add 暴露端口:容器端口 服务名
# 移除暴露端口
docker service update --publish-rm 暴露端口:容器端口 服务名
# 修改负载均衡模式为dnsrr
docker service update --endpoint-mode dnsrr 服务名
# 添加新的配置文件到容器内
docker service update --config-add 配置文件名称,target=/../容器内配置文件名 服务名
# 删除配置文件
docker service update --config-rm 配置文件名称 服务名
# 强制重启服务
docker service update --force 服务名
- 免sudo使用docker命令
因为使用的是sudo安装docker,所以会导致一个问题。以普通用户登录的状况下,在使用docker images时必须添加sudo。
# 创建docker组
[root@manager ~]# sudo groupadd docker
# 将用户加入该 group 内。然后退出并重新登录就生效啦。
[root@manager ~]# sudo gpasswd -a ${USER} docker
正在将用户“root”加入到“docker”组中
# 重启 docker 服务
[root@manager ~]# sudo service docker restart
# 切换当前会话到新 group 或者重启 X 会话
root@manager ~]# newgrp - docker