初次接触docker 是在2016年初,当时是在一家初创公司


Docker从v1.12.0后开始集成swarm mode(swarmkit),关于swarm的所有操作可以直接使用docker swarm 命令来完成。Docker Swarm是docker原生的用于管理docker集群的工具,内置kv存储功能,不再需要外置的etcd,目前的功能主要有:

a. Docker节点集群的管理,包括集群的创建,master,worker节点的加入删除。

b. 服务的管理,包括service的创建删除,update,scale等。

c. 跨主机的网络管理(overlay)

d. 服务发现(内建DNS服务,服务可以通过dns发现)

e. 服务负载均衡LB(端口暴露routing meshing, VIP, DNS-round-robin)

Docker Swarm Mode和Swarm是有区别的,虽然都是集群管理服务编排工具。


本文将使用两个管理节点,一个工作节点

要求:

    系统 system: linux (此列使用centos 7)

    内核 kernel: 3.10+

    docker version: 1.12+

准备

    主机host: 三台,linux系统

        192.168.56.101    (manager1)

        192.168.56.102    (manager2)

        192.168.56.103    (worker1)


    修改主机名为: manager1 manager2 worker1

1. 编辑hostname 文件修改

#vim /etc/hostname


2. hostnamectl 命令设置

这里要修改的是静态名

#hostnamectl set-hostname "host1" --static

重启systemd-hostname 服务生效

#systemctl restart systemd-hostname


实施:

    docker 安装不在此做说明,请参考 http://morrowind.blog.51cto.com/1181631/1873723

    初始化swarm

#192.168.56.102

#docker swarm init --advertise-addr 192.168.56.102
Swarm initialized: current node (dcpp5zxdh35g2du00q1pvhtc2) is now a manager.
To add a worker to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-4sqil7es18zvthb0s7cjdtpwe1q1fkw0m6jeikh30e70sal0sb \
    -dj34fdb8w9v0k0u5cege14ty0 \
    192.168.56.102:2377
To add a manager to this swarm, run 'docker swarm join-token manager' \
and follow the instructions.

初始化后默认输出的信息为worker 工作节点加入方式,在工作节点执行,就可以将节点加入到集群


如下命令可以查看manager 管理节点加入方式,要在管理节点执行才有效

#docker swarm join-token manager
To add a manager to this swarm, run the following command:
    docker swarm join \
    --token SWMTKN-1-4sqil7es18zvthb0s7cjdtpwe1q1fkw0m6jeikh30e70sal0sb \
    -4gqw9f7fdylqcxwfz07jq8bfs \
    192.168.56.102:2377



#192.168.56.103

将103 做为管理节点加入集群

#docker swarm join \
--token SWMTKN-1-4sqil7es18zvthb0s7cjdtpwe1q1fkw0m6jeikh30e70sal0sb \
-dj34fdb8w9v0k0u5cege14ty0 \
192.168.56.102:2377
This node joined a swarm as a worker.


#192.168.56.104

将104 做为管理节点加入集群

#docker swarm join \
    --token SWMTKN-1-4sqil7es18zvthb0s7cjdtpwe1q1fkw0m6jeikh30e70sal0sb \
    -dj34fdb8w9v0k0u5cege14ty0 \
    192.168.56.102:2377
This node joined a swarm as a worker.


在管理节点执行节点查看命令,可看到个节点的状态

#docker node ls
ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
dcpp5zxdh35g2du00q1pvhtc2    manager1  Ready   Active        Leader
sxkcz3xhjyuks0gwtb22h6q0t    worker1   Ready   Active        
w8d2dbp7l3j6df6r0v3feuscq *  mangger2  Ready   Active        Reachable


三台主机的集群,到这就算创建完了,后续是网络和管理节点发出指令


网络:

    swarm 已经内置网络解决方案,可实现不同主机间的容器互相通信。Docker Swarm 模式提供一套默认覆盖网络,其负责配合 libnetwork 与 libkv 实现一套基于 VxLAN 的解决方案。当然,大家也可以选择 Flannel、Calico 或者 Weave 等其它覆盖网络驱动方案


查看下目前都有哪些网络驱动

#docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
3bea9b80b33e        bridge              bridge              local
00c0561f8ad2        docker_gwbridge     bridge              local
efac93cdb8c2        host                host                local
ye6qsmmt2spd        ingress             overlay             swarm
f77b4c6271fc        none                null                local


bridge:

    容器使用独立网络Namespace,并连接到docker0虚拟网卡(默认模式)

    当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上


host:

    容器与主机共享网络Namespace,拥有与主机相同的网络设备


overlay:

    Overlay网络是指在不改变现有网络基础设施的前提下,通过某种约定通信协议,把二层报文封装在IP报文之上的新的数据格式。这样不但能够充分利用成熟的IP路由协议进程数据分发,而且在Overlay技术中采用扩展的隔离标识位数,能够突破VLAN的4000数量限制,支持高达16M的用户,并在必要时可将广播流量转化为组播流量,避免广播数据泛滥。因此,Overlay网络实际上是目前最主流的容器跨节点数据传输和路由方案。


    说到Overlay网络,许多人的第一反应便是:低效,这种认识其实是带有偏见的。Overlay网络的实现方式可以有许多种,其中IETF(国际互联网工程任务组)制定了三种Overlay的实现标准,分别是:虚拟可扩展LAN(VXLAN)、采用通用路由封装的网络虚拟化(NVGRE)和无状态传输协议(SST),其中以VXLAN的支持厂商最为雄厚,可以说是Overlay网络的事实标准。

    而在这三种标准以外还有许多不成标准的Overlay通信协议,例如Weave、Flannel、Calico等工具都包含了一套自定义的Overlay网络协议(Flannel也支持VXLAN模式),这些自定义的网络协议的通信效率远远低于IETF的标准协议[5],但由于他们使用起来十分方便,一直被广泛的采用而造成了大家普遍认为Overlay网络效率低下的印象。然而,根据网上的一些测试数据来看,采用VXLAN的网络的传输速率与二层VLAN网络是基本相当的。


null:

    此模式默认容器只有回环地址,容器没有任何网卡,适合不需要与外部通过网络通信的容器。


创建好swarm 集群后,overlay 驱动网络已经默认创建,但这个默认的overlay 网络是用于swarm 管理节点做为负载均衡路由用的,容器并不能使用此默认网络。

因此需要创建一个容器使用的overlay 网络

#docker network create -drvice=overlay over0


部署服务:

#docker service create --name nginx --network over0 --replicas 1 \
--mount type=bind,source=/tmp/html/,destination=/usr/share/nginx/html \
--mount type=bind,source=/tmp/test/,destination=/usr/share/nginx/html/test \
--publish 80:80 nginx:1.10-alpine

参数:

--name 容器名称

--network 使用的网络名称

--replicas  部署容器个数

--mount   挂载


Option Required Description
types

The type of mount, can be either volume, bind, or tmpfs. Defaults to volume if no type is specified.

  • volume: mounts a [managed volume](volume_create.md) into the container.

  • bind: bind-mounts a directory or file from the host into the container.

  • tmpfs: mount a tmpfs in the container

src or source for type=bind only>
  • type=volume: src is an optional way to specify the name of the volume (for example, src=my-volume).          If the named volume does not exist, it is automatically created. If no src is specified, the volume is          assigned a random name which is guaranteed to be unique on the host, but may not be unique cluster-wide.          A randomly-named volume has the same lifecycle as its container and is destroyed when the container          is destroyed (which is upon service update, or when scaling or re-balancing the service)

  • type=bind: src is required, and specifies an absolute path to the file or directory to bind-mount          (for example, src=/path/on/host/). An error is produced if the file or directory does not exist.

  • type=tmpfs: src is not supported.

dst or destination or target

yes

Mount path inside the container, for example /some/path/in/container/.      If the path does not exist in the container's filesystem, the Engine creates      a directory at the specified location before mounting the volume or bind-mount.

readonly or ro


The Engine mounts binds and volumes read-write unless readonly option      is given when mounting the bind or volume.

  • true or 1 or no value: Mounts the bind or volume read-only.

  • false or 0: Mounts the bind or volume read-write.


--publish  端口发布,发布端口由管理节点路由到可用容器,任意主机ip:port都可以访问,而不用管容器具体在哪台机器上

缩放集群中服务

通过docker service scale 命令来扩展

#docker service scale nginx=3
nginx scaled to 3


#docker service ls
ID            NAME    MODE        REPLICAS  IMAGE
hyaxe83wj1s7  nginx   replicated  3/3       nginx:1.10-alpine


删除服务:

#docker service rm nginx
nginx


滚动更新

更新容器镜像

docker service update --p_w_picpath nginx:1.11-alpine nginx

查看容器服务

docker service inspect --pretty nginx
ID:        hyaxe83wj1s7qh3b4ywnw0pfi
Name:        nginx
Service Mode:    Replicated
 Replicas:    3
UpdateStatus:
 State:        updating
 Started:    15 seconds
 Message:    update in progress
Placement:
UpdateConfig:
 Parallelism:    1
 On failure:    pause
 Max failure ratio: 0
ContainerSpec:
 Image:        nginx:1.11-alpine@sha256:5aadb68304a38a8e2719605e4e180413f390cd6647602bee9bdedd59753c3590
Mounts:
  Target = /usr/share/nginx/html
   Source = /tmp/html/
   ReadOnly = false
   Type = bind
Resources:
Networks: over0 
Endpoint Mode:    vip
Ports:
 PublishedPort 80
  Protocol = tcp
  TargetPort = 80


state状态为updating


更新延迟,可在更新时指定时间,亦可在启动容器时加入延迟参数--update-delay

启动时指定的时间可被更新时指定的时间覆盖

docker service update --update-delay 10s --p_w_picpath nginx:1.11-alpine nginx
docker service create --replicas 3 --name nginx --update-delay 10s nginx:1.10-alpine



swarm 常用命令

docker swarm init

docker node ls

docker node rm

docker swarm leave

docker swarm join


docker service create

docker serivce ls

docker service ps

docker service update

docker service rm

docker service inspect

docker service scale


docker network ls

docker network create

docker network rm

docker ps

docker p_w_picpaths

docker rmi

docker rm



参考

mount详情参考官方资料

https://docs.docker.com/engine/reference/commandline/service_create/#add-bind-mounts-or-volumes


遇到的问题

部署时查看部署状态有error

No such p_w_picpath: nginx@sha256:0…

其中有两台机器是我有意将外网网络关闭了,因为在多节点部署的时候,我发现部署时间有点长,各节点已经先通过docker load < nginx.tar 导入到了主机,本不应该部署时间长的,于是想到是不是又从网络去下载镜像了,而没有使用我导入的镜像,为了验证此猜想,隧关闭了几个节点的网络访问,然后就出现了此类报错。

通过查资料发现,导入的p_w_picpath缺少sha信息,需要重新将sha信息pull下来

docker p_w_picpaths  --digests
REPOSITORY   TAG          DIGEST                         IMAGE ID       
nginx        1.10-alpine  sha256:4aacdcf186934dcb02f642579314075910f1
                          855590fd3039d8fa4c9f96e48315   f94d6dd9b576     
CREATED             SIZE
3 months ago        54 MB

因此,只要在各个节点pull一遍p_w_picpath就可以解决了


初始化报错

Error response from daemon: --live-restore daemon configuration is incompatible with swarm mode


修改/etc/docker/daemon.json文件,true改为false

{
    "live-restore": false
}