前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker swarm笔记

docker swarm笔记

作者头像
pollyduan
发布2019-11-04 13:39:46
7810
发布2019-11-04 13:39:46
举报

1 准备节点:

代码语言:javascript
复制
node-1 192.168.33.201
node-2 192.168.33.202
node-3 192.168.33.203
node-4 192.168.33.204

2 在每个节点分别安装docker服务。

代码语言:javascript
复制
sudo curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -

安装后需要修改dockerd启动参数,增加:

代码语言:javascript
复制
-H 0.0.0.0:2375

这个很重要,否则manager无法连接到节点。

docker 1.12以前,需要自己使用swarm镜像启动环境,这里整理一下。如果你已经是1.12+了,请直接跳到第4节。

3 Docker1.12以前的swarm-swarm container

3.1 在node-1启动swarm容器

代码语言:javascript
复制
docker pull warm

创建token

代码语言:javascript
复制
$ docker run --rm swarm create
3445719bd06a6a19950c8a034f276cab

加入集群

代码语言:javascript
复制
docker run -d swarm join --addr=192.168.33.201:2375 token://3445719bd06a6a19950c8a034f276cab

3.2 在node-2启动swarm容器

重复node-1操作。记得修改IP地址。

3.3 查看集群节点

在其中一个节点查看集群

代码语言:javascript
复制
$ docker run --rm swarm list token://3445719bd06a6a19950c8a034f276cab
192.168.33.202:2375
192.168.33.201:2375

3.4 集群管理

3.4.1 启动管理节点

在测试机上开启管理程序。如果在node-1或node-2上,建议使用非2375端口,如:-p 5000:2375

代码语言:javascript
复制
$ docker run -d -p 2375:2375 swarm manage token://3445719bd06a6a19950c8a034f276cab
3eb0aec4c9917725c098d102aa12767803db59f869052c611d3be160971df534
3.4.2 查看集群状态
代码语言:javascript
复制
$ docker -H 192.168.33.203:2375 info
Containers: 6
 Running: 6
 Paused: 0
 Stopped: 0
Images: 4
Server Version: swarm/1.2.5
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint
Nodes: 2
 test1: 192.168.33.201:2375
  └ ID: 52BN:6F2E:GMCP:4JYC:H3IW:VEUM:3ART:TAUE:4CLW:GR3I:S4KI:LKSR
  └ Status: Healthy
  └ Containers: 3 (3 Running, 0 Paused, 0 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: kernelversion=4.4.0-51-generic, operatingsystem=Ubuntu 16.04.1 LTS, storagedriver=aufs
  └ UpdatedAt: 2017-01-09T06:12:52Z
  └ ServerVersion: 1.12.5
 test2: 192.168.33.202:2375
  └ ID: I6N6:WJZH:B3S3:DW6E:MIPP:FIKF:EGIX:RAVH:XNKU:LHGL:WAE7:SBZ2
  └ Status: Healthy
  └ Containers: 3 (3 Running, 0 Paused, 0 Stopped)
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.018 GiB
  └ Labels: kernelversion=4.4.0-51-generic, operatingsystem=Ubuntu 16.04.1 LTS, storagedriver=aufs
  └ UpdatedAt: 2017-01-09T06:13:40Z
  └ ServerVersion: 1.12.5
Plugins:
 Volume:
 Network:
Swarm:
 NodeID:
 Is Manager: false
 Node Address:
Security Options:
Kernel Version: 4.4.0-51-generic
Operating System: linux
Architecture: amd64
CPUs: 2
Total Memory: 2.035 GiB
Name: cfa479ee8a5e
Docker Root Dir:
Debug Mode (client): false
Debug Mode (server): false
WARNING: No kernel memory limit support

其中Status: Healthy表示节点正常,如果前面提及的dockerd启动项未设置,这里将会是:Pending,服务不可用。

3.5 测试集群

3.5.1 查看容器
代码语言:javascript
复制
$ docker -H 192.168.33.203:2375 ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3.5.2 设置命令别名

如果是2375,端口号可以省略。为了使用方便可以创建一个命令别名:

代码语言:javascript
复制
alias docker-swarm='docker -H 192.168.33.203'

再测试:

代码语言:javascript
复制
$ docker-swarm images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
3.5.3 启动容器
代码语言:javascript
复制
docker-swarm run -d --name web1 nginx
docker-swarm run -d --name web2 nginx
docker-swarm run -d --name web3 nginx
docker-swarm run -d --name web4 nginx
3.5.4 查看整个集群的容器
代码语言:javascript
复制
$ docker-swarm ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED                  STATUS                  PORTS               NAMES
478206c91145        nginx               "nginx -g 'daemon off"   Less than a second ago   Up Less than a second   80/tcp, 443/tcp     test1/web4
07a70b5ba0c2        nginx               "nginx -g 'daemon off"   4 seconds ago            Up 4 seconds            80/tcp, 443/tcp     test2/web3
dbd596f5464a        nginx               "nginx -g 'daemon off"   18 seconds ago           Up 18 seconds           80/tcp, 443/tcp     test2/web2
04c23c28bafb        nginx               "nginx -g 'daemon off"   54 seconds ago           Up 54 seconds           80/tcp, 443/tcp     test1/web1

查看NAMES数据,形如:test1/webx,其中test1表示节点名字

4 Docker1.12以后的swarmkit

Docker 1.12 在 2016 年 7 月 28 日正式 GA,除了大量的在使用上的改进和 bug 修复外,最引人瞩目的是Docker原生支持了 Swarm 模式,而不是将Swarm作为一个容器对集群进行管理。而docker1.12的操作命令并不向下兼容,于是过去所有创建swarm集群的文档都不能参考了。

4.1 几个概念

4.1.1 节点类型

docker-swarm 把节点分为manager和worker,顾名思义,manager是管理节点,worker是工作节点。

4.1.2 service

区别于旧的swarm管理容器,新的docker-swarm抽象了一个service的概念,有点类似于kubernates的pod,它是管理的最小单元。

一个service是一个以上的容器的集合。

4.2 搭建swarm环境

仍然使用前面的节点服务来测试,第1、2节的工作还是需要有效的。

4.2.1 在node-1节点创建swarm环境
代码语言:javascript
复制
$ docker swarm init --advertise-addr 192.168.33.201
Swarm initialized: current node (9vpgoqj65y3kqo52jj3y6gcnj) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-2at6h0j885ttz6zzxxdca7rerj0dkcnq5tbqv729u0ty2tvtzz-2g85bb2vug886wxit8rbpcisy \
    192.168.33.201:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

他是使用Raft来管理节点的。事实上,如果你只有一个外网地址(即除了lo和docker网络等虚拟网络之外没有其他网络接口),可以直接执行:docker swarm init

4.2.2 将node-2节点加入到创建的swarm cluster

在node-2 执行:

代码语言:javascript
复制
$ docker swarm join \
--token SWMTKN-1-2at6h0j885ttz6zzxxdca7rerj0dkcnq5tbqv729u0ty2tvtzz-2g85bb2vug886wxit8rbpcisy \
192.168.33.201:2377
This node joined a swarm as a worker.
4.2.3 在更多节点加入swarm cluster

token没有记录下来?没关系,在node-1执行如下命令查看完整的命令提示:

代码语言:javascript
复制
$ docker swarm join-token worker
To add a worker to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-2at6h0j885ttz6zzxxdca7rerj0dkcnq5tbqv729u0ty2tvtzz-2g85bb2vug886wxit8rbpcisy \
    192.168.33.201:2377

如果要加入的是manager节点,则如下查看:

代码语言:javascript
复制
$ docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-2at6h0j885ttz6zzxxdca7rerj0dkcnq5tbqv729u0ty2tvtzz-37rg2khjxgk1iis6dfds48b0s \
    192.168.33.201:2377

4.3 集群管理

4.3.1 查看集群节点

在manager节点:

代码语言:javascript
复制
$ docker node list
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
9vpgoqj65y3kqo52jj3y6gcnj *  test1     Ready   Active        Leader
dc5t7rc04a69rzuahky6qh53x    test2     Ready   Active
e4k1fjd93ukncipzy9cer0lcg    test3     Ready   Active

可以看到,一共有三个节点,node-1自身已经是一个worker了,他的MANAGER是Leader。

该命令只有在manager节点才有权限使用,如果你想在node-3上使用,则需要让node-3成为manager。。

一种方法是让node-3先从cluster重新以manager身份加入cluster。

代码语言:javascript
复制
$ docker swarm leave
Node left the swarm.

注意:有时自己退出重新加入,反复操作,会让manager混乱,导致一些问题。如,test3已经leave,但manager看到它还是Reading状态,无法删除掉。docker node rm test3只能删除down状态的节点, 加上--force不是那么好使。

4.3.2 节点角色转换

接上,将node-3转换为manager最简单的方法是,角色提权:是在manager中把node-3的角色提升为manager:

代码语言:javascript
复制
vagrant@test1:~$ docker node promote test3
Node test3 promoted to a manager in the swarm.
vagrant@test1:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
5awz4cd6auchp0knq0iljfudh    test2     Ready   Active
a02rv4zuex14p03erer1h6zkz *  test1     Ready   Active        Leader
cq9q1su8ipkp9w80sabv16mmz    test3     Ready   Active        Reachable

与之相反的就是降权:

一种方法是在manager中把node-3的角色提升为manager:

代码语言:javascript
复制
vagrant@test1:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
5awz4cd6auchp0knq0iljfudh    test2     Ready   Active
a02rv4zuex14p03erer1h6zkz *  test1     Ready   Active        Leader
cq9q1su8ipkp9w80sabv16mmz    test3     Ready   Active

从安全性考虑,一个集群应该指定多个manager。但需要注意的是,如果一个manager宕机,那么另一个manager需要接管服务,需要至少有三个以上存活的节点。

4.3.3 删除节点
代码语言:javascript
复制
docker node rm [node_id]

如果节点状态是Down,可以直接删除,否则可以增加--force开关强制删除。

4.3.4 manager容灾测试

再增加一个node-4,并将node-3提权为manager。

代码语言:javascript
复制
vagrant@test1:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
2n3x7y0oaez6pdoxq91r5lng9    test4     Ready   Active
77pnoup6clbxgwfd58dp9reu4    test2     Ready   Active
84n1fg849v49i2ezobmps5vwg *  test1     Ready   Active        Leader
8v5r3wb9sujlluqda6jv981ut    test3     Ready   Active        Reachable

关闭node-1,在node-3检查节点:

代码语言:javascript
复制
vagrant@test3:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
2n3x7y0oaez6pdoxq91r5lng9    test4     Ready   Active
77pnoup6clbxgwfd58dp9reu4    test2     Ready   Active
84n1fg849v49i2ezobmps5vwg    test1     Ready   Active        Unreachable
8v5r3wb9sujlluqda6jv981ut *  test3     Ready   Active        Leader

此时test3接管Leader了。

启动node-1,检查节点:

代码语言:javascript
复制
vagrant@test1:~$ docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
2n3x7y0oaez6pdoxq91r5lng9    test4     Ready   Active
77pnoup6clbxgwfd58dp9reu4    test2     Ready   Active
84n1fg849v49i2ezobmps5vwg *  test1     Ready   Active        Reachable
8v5r3wb9sujlluqda6jv981ut    test3     Ready   Active        Leader

node-1已经变成了Reachable。

4.4 使用入门

4.4.1 创建service

折腾了半天,办点正事吧。

代码语言:javascript
复制
vagrant@test1:~$ docker service create --name web1 nginx
bojkn65bzwpv2az82y3p7qssv
vagrant@test1:~$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
vagrant@test1:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  0/1       nginx
#稍等片刻
vagrant@test1:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  1/1       nginx

REPLICAS 表示一共指定了1个副本,开始启动了0个,启动完成后,变成1/1。

4.4.2 查看服务中的容器
代码语言:javascript
复制
vagrant@test1:~$ docker service ps web1
ID                         NAME    IMAGE  NODE   DESIRED STATE  CURRENT STATE          ERROR
3tu8qr42a74tzudu8xta46u9h  web1.1  nginx  test2  Running        Running 3 minutes ago
4.4.3 调整容器副本

我们可以把web1服务中的容器多启动几个副本,如6个:

代码语言:javascript
复制
vagrant@test1:~$ docker service scale web1=6
web1 scaled to 6
vagrant@test1:~$ docker service ps web1
ID                         NAME    IMAGE  NODE   DESIRED STATE  CURRENT STATE             ERROR
3tu8qr42a74tzudu8xta46u9h  web1.1  nginx  test2  Running        Running 4 minutes ago
chy2qbqz3pbboyxxz90gb9vxb  web1.2  nginx  test3  Running        Preparing 12 seconds ago
2ae4vz4lx8zcpacjepdzcxx5y  web1.3  nginx  test1  Running        Preparing 13 seconds ago
dfg1pul4brwa8xqutls2dddm1  web1.4  nginx  test4  Running        Preparing 13 seconds ago
2o39qlezex2ddk8ie0bzs9drv  web1.5  nginx  test4  Running        Preparing 13 seconds ago
bsduc9qvegikjs8fj94k4ogi8  web1.6  nginx  test2  Running        Running 6 seconds ago
vagrant@test1:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  2/6       nginx

其中的2/6以及前面看到的列表信息状态可以看出,我们指定了6个副本,目前web1.1web1.6已经启动完成,其他还在Preparing。

6个副本中分别在test1启动了1个、test2启动了2个、test3启动了1个、test4启动了2个。

过一会再刷新:

代码语言:javascript
复制
vagrant@test1:~$ docker service ps web1
ID                         NAME    IMAGE  NODE   DESIRED STATE  CURRENT STATE            ERROR
3tu8qr42a74tzudu8xta46u9h  web1.1  nginx  test2  Running        Running 7 minutes ago
chy2qbqz3pbboyxxz90gb9vxb  web1.2  nginx  test3  Running        Preparing 3 minutes ago
2ae4vz4lx8zcpacjepdzcxx5y  web1.3  nginx  test1  Running        Preparing 3 minutes ago
dfg1pul4brwa8xqutls2dddm1  web1.4  nginx  test4  Running        Running 9 seconds ago
2o39qlezex2ddk8ie0bzs9drv  web1.5  nginx  test4  Running        Running 9 seconds ago
bsduc9qvegikjs8fj94k4ogi8  web1.6  nginx  test2  Running        Running 3 minutes ago
vagrant@test1:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  4/6       nginx

最终会完全启动。

代码语言:javascript
复制
vagrant@test1:~$ docker service ls
ID            NAME  REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  6/6       nginx

处理scale子命令,还可以使用update子命令完成同样的工作:

代码语言:javascript
复制
vagrant@test1:~$ docker service update web1 --replicas=3
web1
vagrant@test1:~$ docker service ls
ID            NAME    REPLICAS  IMAGE  COMMAND
bojkn65bzwpv  web1  2/3       nginx

4.5 负载均衡

多个副本容器启动后, swarm集群的service:

公共的端口会暴露在每一个swarm集群中的节点服务器上.

请求公共端口时,会负载均衡到所有的sevice实例上.

负载均衡模式有两种,vip和dnsrr,可以在出啊构建服务时指定:

代码语言:javascript
复制
vagrant@test1:~$ docker service create --name web1 --replicas=6 --endpoint-mode=dnsrr nginx
4dx616zii0vgrz4s5oi2rwgsp

如果使用vip模式,应该有VirtualIP:

代码语言:javascript
复制
$ docker service inspect --format='{{.Endpoint.VirtualIPs}}' web1
[]

怎么木有?你可能忘记在创建服务时发布端口了。

代码语言:javascript
复制
vagrant@test1:~$ docker service create --name web1 --replicas=6 -p 8888:80 nginx
8qlkxx7v643z7aenfrmfnksxk
vagrant@test1:~$ docker service inspect --format='{{.Endpoint.VirtualIPs}}' web1
[{9h4hrcm7bv1ijdpzpyezy4pld 10.255.0.6/16}]

可以直接访问"http://10.255.0.6:8080"吗?no,它只是为容器间通信的,你可以访问任一台节点的IP:http://192.168.33.201:8888

4.6 启动时指定副本数

代码语言:javascript
复制
vagrant@test1:~$ docker service create --name nginx1 --replicas 2 nginx
c79881b02bd7zrfg74a9qp8ji
vagrant@test1:~$ docker service ps nginx1
ID                         NAME      IMAGE  NODE   DESIRED STATE  CURRENT STATE          ERROR
1ghmia00xkxucrisadlwyitv9  nginx1.1  nginx  test3  Running        Running 5 seconds ago
193mdx2xcja4qv8s9ssakt8w1  nginx1.2  nginx  test4  Running        Running 6 seconds ago

4.7 swarm网络

由于容器在不同的docker主机上,swarm是如何保证网络层的互通呢?swarm是使用overlay网络来解决这个问题的。

代码语言:javascript
复制
vagrant@test1:~$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
180d624cf798        bridge              bridge              local
4d225a25b2b4        docker_gwbridge     bridge              local
6c1889cd666a        host                host                local
9h4hrcm7bv1i        ingress             overlay             swarm
839e8db03b09        none                null                local

其中的swarm是缺省创建的overlay网络。

你可以自己创建网络来管理一组服务的互通。

代码语言:javascript
复制
vagrant@test1:~$ docker network create --driver overlay test
17wzxz29pxdf6are8an6u0ep2
vagrant@test1:~$ docker network ls |grep test
17wzxz29pxdf        test                overlay             swarm

在指定子网启动服务

代码语言:javascript
复制
vagrant@test1:~$ docker service create --network test --name myservice hello-world
5kz0imiep9fztvsev0c101568
vagrant@test1:~$ docker service ps myservice
ID                         NAME         IMAGE        NODE   DESIRED STATE  CURRENT STATE            ERROR
6zww5ci2jhnvy05aj68ohb3do  myservice.1  hello-world  test2  Running        Preparing 5 seconds ago

通过docker service inspect myservice返回的json中Networks元素可以看到网络信息,Target正是前面创建的test接口的id:

代码语言:javascript
复制
"Networks": [
      {
          "Target": "17wzxz29pxdf6are8an6u0ep2"
      }
]

你只要保证你启动的多个服务在同一个网络接口,就可以保证他们之间互相通信。

4.8 小结

swarmkit的引入,在docker中引入了三个子命令:

代码语言:javascript
复制
docker swarm——swarm集群搭建
docker service——服务管理
docker node——集群节点管理
4.8.1 docker swarm 子命令

查看子命令 vagrant@test1:~$ docker swarm --help

代码语言:javascript
复制
  init        初始化swarm集群
  join        将当前节点加入到集群中
  join-token  管理加入token
  update      动态更新swarm配置
  leave       当前节点主动退出集群(仅限worker节点)
4.8.2 docker service 子命令

查看子命令 vagrant@test1:~$ docker service --help

代码语言:javascript
复制
create      创建服务
inspect     显示服务详情
ps          列出服务中的容器
ls          列出所有服务及简介
rm          删除服务
scale       调整服务的副本数
update      动态更新服务配置
4.8.3 docker node 子命令

查看子命令 vagrant@test1:~$ docker node --help

代码语言:javascript
复制
demote      管理节点为指定子节点降权
inspect     显示节点详情
ls          列出集群中的节点
promote     管理节点为指定子节点提权
rm          删除一个节点
ps          列出指定子节点中running的容器
update      动态更新节点配置
4.8 使用帮助

本节实际上只是给出了查看帮助的方法。想了解某个命令的使用,只需要在子命令后面加上--help即可,逐级深入。如想了解docker node的子命令rm,则是:

代码语言:javascript
复制
vagrant@test1:~$ docker node rm --help

Usage:	docker node rm [OPTIONS] NODE [NODE...]

Remove one or more nodes from the swarm

Aliases:
  rm, remove

Options:
      --force   Force remove an active node
      --help    Print usage
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 准备节点:
  • 2 在每个节点分别安装docker服务。
  • 3 Docker1.12以前的swarm-swarm container
    • 3.1 在node-1启动swarm容器
      • 3.2 在node-2启动swarm容器
        • 3.3 查看集群节点
          • 3.4 集群管理
            • 3.4.1 启动管理节点
            • 3.4.2 查看集群状态
          • 3.5 测试集群
            • 3.5.1 查看容器
            • 3.5.2 设置命令别名
            • 3.5.3 启动容器
            • 3.5.4 查看整个集群的容器
        • 4 Docker1.12以后的swarmkit
          • 4.1 几个概念
            • 4.1.1 节点类型
            • 4.1.2 service
          • 4.2 搭建swarm环境
            • 4.2.1 在node-1节点创建swarm环境
            • 4.2.2 将node-2节点加入到创建的swarm cluster
            • 4.2.3 在更多节点加入swarm cluster
          • 4.3 集群管理
            • 4.3.1 查看集群节点
            • 4.3.2 节点角色转换
            • 4.3.3 删除节点
            • 4.3.4 manager容灾测试
          • 4.4 使用入门
            • 4.4.1 创建service
            • 4.4.2 查看服务中的容器
            • 4.4.3 调整容器副本
          • 4.5 负载均衡
            • 4.6 启动时指定副本数
              • 4.7 swarm网络
                • 4.8 小结
                  • 4.8.1 docker swarm 子命令
                  • 4.8.2 docker service 子命令
                  • 4.8.3 docker node 子命令
                  • 4.8 使用帮助
              相关产品与服务
              容器服务
              腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档