一:原理:
1:docker集群亮点:
功能亮点
与Docker Engine集成的集群管理:使用Docker Engine CLI创建一大群Docker引擎,您可以在其中部署应用程序服务。您不需要额外的编排软件来创建或管理群。即自带swarm不需要那么多负载均衡高可用源件

分散式设计: Docker Engine在部署时不是处理节点角色之间的差异,而是在运行时处理任何专业化。您可以使用Docker Engine部署这两种节点,管理员和工作人员。这意味着您可以从单个磁盘映像构建整个群集。

声明式服务模型: Docker Engine使用声明式方法来定义应用程序堆栈中各种服务的所需状态。例如,您可能会描述一个由带有消息队列服务和数据库后端的Web前端服务组成的应用程序。

缩放:对于每个服务,您可以声明要运行的任务数量。当您向上或向下缩放时,swarm管理器会通过添加或删除任务来自动调整以保持所需的状态。

期望的状态协调:群管理器节点不断监视群集状态,并协调实际状态与表达的期望状态之间的任何差异。例如,如果您设置了一个服务来运行一个容器的10个副本以及一个承载其中两个副本崩溃的工作器,那么管理器将创建两个新的副本来替换崩溃的副本。swarm manager将新副本分配给正在运行且可用的工作人员。

多主机联网:您可以为您的服务指定一个重叠网络。swarm管理器在初始化或更新应用程序时会自动将地址分配给覆盖网络上的容器。

服务发现: Swarm管理器节点为swarm中的每个服务分配唯一的DNS名称,并负载平衡正在运行的容器。您可以通过群集中嵌入的DNS服务器来查询在群集中运行的每个容器。

负载平衡:您可以将服务的端口暴露给外部负载平衡器。在群集内部,您可以指定如何在节点之间分发服务容器。

默认情况下是安全的:群中的每个节点都强制实施TLS相互认证和加密,以保护自身与所有其他节点之间的通信。您可以选择使用自定义根证书或来自自定义根CA的证书。

滚动更新:在推出时,您可以逐渐将服务更新应用于节点。swarm管理器允许您控制服务部署到不同节点集之间的延迟。如果出现任何问题,您

当Docker以群集模式运行时,您仍然可以在参与群集的任何Docker主机以及群集服务上运行独立容器。独立容器和群集服务之间的一个主要区别是,只有群集管理员可以管理群集,而独立容器可以在任何守护进程上启动。Docker守护进程可以作为管理者,工作者,或两者兼而有之。

负载均衡
swarm管理器使用入口负载均衡来暴露你想在群集外部提供的服务。swarm管理器可以自动将服务分配给一个PublishedPort,或者您可以为该服务配置一个PublishedPort。您可以指定任何未使用的端口。如果您不指定端口,那么swarm管理器将为该服务分配一个30000-32767范围内的端口。

外部组件(如云负载平衡器)可以访问群集中任何节点的已发布端口上的服务,而不管该节点当前是否正在运行该服务的任务。群路由中的所有节点都将入口连接到正在运行的任务实例。

Swarm模式有一个内部的DNS组件,可以自动为群集中的每个服务分配一个DNS条目。群管理器使用内部负载平衡根据服务的DNS名称在群集内的服务之间分配请求。

按照官网的文档直接走,别翻来覆去找没用的资料了
1. manager:172.25.67.250
2. server1:172.25.67.1
3. server2:172.25.67.2
前提:
本教程需要在每台主机上安装Docker Engine 1.12或更高版本。安装Docker Engine并验证Docker Engine守护进程在每台机器上运行。如果低于1.12 不会自带swarm ,需要pull

三台:

yum update -y docker-engine-1.12.6-1.el7.centos.x86_64.rpm docker-engine-selinux-1.12.6-1.el7.centos.noarch.rpm
systemctl restart docker
[root@foundation67 Desktop]# docker swarm init
Error response from daemon: could not choose an IP address to advertise since this system has multiple addresses on interface br0 (172.25.254.67 and 172.25.67.250) - specify one with --advertise-addr

错误原因:在manager上我有俩快网卡,没有指定哪个ip上创建swarm

[root@foundation67 Desktop]# docker swarm init --advertise-addr 172.25.67.250
Swarm initialized: current node (3fj7bam3qavua00ksimls79n2) is now a manager.

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

    docker swarm join \
    --token SWMTKN-1-4ea7kwwqtwaddags5ypb44ql7qea4rjktysa9lvqkfculf4ywi-ev61dcr7g15xjb0fw8o3s1sjl \
    172.25.67.250:2377

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

该–advertise-addr标志配置管理器节点将其地址发布为192.168.99.100。群中的其他节点必须能够访问IP地址的管理者。

输出包括将新节点加入到群中的命令。根据–token 标志的价值,节点将作为经理或工人加入。根据上面输出在节点上执行,token是唯一标

[root@server1 ~]# docker swarm join     --token SWMTKN-1-4ea7kwwqtwaddags5ypb44ql7qea4rjktysa9lvqkfculf4ywi-ev61dcr7g15xjb0fw8o3s1sjl     172.25.67.250:2377
This node joined a swarm as a worker.
[root@server2 ~]# docker swarm join     --token SWMTKN-1-4ea7kwwqtwaddags5ypb44ql7qea4rjktysa9lvqkfculf4ywi-ev61dcr7g15xjb0fw8o3s1sjl     172.25.67.250:2377
This node joined a swarm as a worker.

运行docker info查看群体的当前状态:

[root@foundation67 Desktop]# docker info
Containers: 20
 Running: 0
 Paused: 0
 Stopped: 20
Images: 8
Server Version: 1.12.6
Storage Driver: devicemapper
 Pool Name: docker-8:10-273268971-pool
 Pool Blocksize: 65.54 kB
 Base Device Size: 10.74 GB
 Backing Filesystem: xfs
 Data file: /dev/loop4
 Metadata file: /dev/loop5
 Data Space Used: 21.82 GB
 Data Space Total: 107.4 GB
 Data Space Available: 142 MB
 Metadata Space Used: 4.133 MB
 Metadata Space Total: 2.147 GB
 Metadata Space Available: 142 MB
 Thin Pool Minimum Free Space: 10.74 GB
 Udev Sync Supported: true
 Deferred Removal Enabled: false
 Deferred Deletion Enabled: false
 Deferred Deleted Device Count: 0
 Data loop file: /var/lib/docker/devicemapper/devicemapper/data
 WARNING: Usage of loopback devices is strongly discouraged for production use. Use `--storage-opt dm.thinpooldev` to specify a custom block storage device.
 Metadata loop file: /var/lib/docker/devicemapper/devicemapper/metadata
 Library Version: 1.02.107-RHEL7 (2015-10-14)
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host null bridge overlay
Swarm: active
 NodeID: 3fj7bam3qavua00ksimls79n2
 Is Manager: true
 ClusterID: azzjtrdp4xx6u0xkrdlby4l0d
 Managers: 1
 Nodes: 3
 Orchestration:
  Task History Retention Limit: 5
 Raft:
  Snapshot Interval: 10000
  Heartbeat Tick: 1
  Election Tick: 3
 Dispatcher:
  Heartbeat Period: 5 seconds
 CA Configuration:
  Expiry Duration: 3 months
 Node Address: 172.25.67.250
Runtimes: runc
Default Runtime: runc
Security Options: seccomp
Kernel Version: 3.10.0-327.el7.x86_64
Operating System: Red Hat Enterprise Linux Server 7.2 (Maipo)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 3.624 GiB
Name: foundation67.ilt.example.com
ID: ESBG:ZZAB:KUZ6:4KP4:WHZ7:PSVD:KR3K:E3CY:UGX2:H4AC:BFK2:3YWY
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: bridge-nf-call-ip6tables is disabled
Insecure Registries:
 127.0.0.0/8

运行该docker node ls命令查看有关节点的信息:

[root@foundation67 Desktop]# docker node ls
ID                           HOSTNAME                      STATUS  AVAILABILITY  MANAGER STATUS
3fj7bam3qavua00ksimls79n2 *  foundation67.ilt.example.com  Ready   Active        Leader
arlf5530b1mkchbbgcxdm3ikk    server2                       Ready   Active        
d58wnlal0wlt9scqu25rlnc0i    server1                       Ready   Active

在*旁边的节点ID表明当前连接此节点上。

  • 部属服务

下一步是什么?
现在你的群由一个管理者和两个工人节点组成。在本教程的下一个步骤中,您将部署一个服务到群集。

运行以下命令:

[root@foundation67 Desktop]# docker service create --replicas 1 --name hellowalld alpine ping 172.25.67.1
bed1vdf0lv2p0o29k2ttfg7rv

该docker service create命令创建该服务。
该–name标志命名该服务helloworld。
该–replicas标志指定了正在运行的实例的所需状态。
参数alpine ping xxx将服务定义为执行命令的Alpine Linux容器ping xxx。
运行docker service ls以查看正在运行的服务的列表:

[root@foundation67 Desktop]# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
bed1vdf0lv2p  hellowalld  1/1       alpine  ping 172.25.67.1
  • 下一步是什么?检查群上的服务
    现在你已经为这个群体部署了一个服务,你已经准备好检查这个服务了。

运行docker service inspect –pretty 以便于阅读的格式显示有关服务的详细信息。

[root@foundation67 Desktop]# docker service inspect --pretty hellowalld 
ID:     bed1vdf0lv2p0o29k2ttfg7rv
Name:       hellowalld
Mode:       Replicated
 Replicas:  1
Placement:
UpdateConfig:
 Parallelism:   1
 On failure:    pause
ContainerSpec:
 Image:     alpine
 Args:      ping 172.25.67.1

提示:要以json格式返回服务详细信息,请运行没有–pretty标志的相同命令。

[root@foundation67 Desktop]# docker service inspect --pretty hellowalld 
ID:     bed1vdf0lv2p0o29k2ttfg7rv
Name:       hellowalld
Mode:       Replicated
 Replicas:  1
Placement:
UpdateConfig:
 Parallelism:   1
 On failure:    pause
ContainerSpec:
 Image:     alpine
 Args:      ping 172.25.67.1
Resources:
[root@foundation67 Desktop]# docker service inspect hellowalld 
[
    {
        "ID": "bed1vdf0lv2p0o29k2ttfg7rv",
        "Version": {
            "Index": 22
        },
        "CreatedAt": "2017-11-16T01:57:14.00441158Z",
        "UpdatedAt": "2017-11-16T01:57:14.00441158Z",
        "Spec": {
            "Name": "hellowalld",
            "TaskTemplate": {
                "ContainerSpec": {
                    "Image": "alpine",
                    "Args": [
                        "ping",
                        "172.25.67.1"
                    ]
                },
                "Resources": {
                    "Limits": {},
                    "Reservations": {}
                },
                "RestartPolicy": {
                    "Condition": "any",
                    "MaxAttempts": 0
                },
                "Placement": {}
            },
            "Mode": {
                "Replicated": {
                    "Replicas": 1
                }
            },
            "UpdateConfig": {
                "Parallelism": 1,
                "FailureAction": "pause"
            },
            "EndpointSpec": {
                "Mode": "vip"
            }
        },
        "Endpoint": {
            "Spec": {}
        },
        "UpdateStatus": {
            "StartedAt": "0001-01-01T00:00:00Z",
            "CompletedAt": "0001-01-01T00:00:00Z"
        }
    }
]
[root@foundation67 Desktop]#

运行docker service ps 以查看哪些节点正在运行该服务:

[root@foundation67 Desktop]# docker service ps hellowalld 
ID                         NAME          IMAGE   NODE                          DESIRED STATE  CURRENT STATE          ERROR
863qwi0qzn98iqjhyavhqer8m  hellowalld.1  alpine  foundation67.ilt.example.com  Running        Running 4 minutes ago

在这种情况下,服务的一个实例helloworld正在worker2节点上运行 。您可能会看到服务在您的管理器节点上运行。默认情况下,群中的管理节点可以像工作节点一样执行任务。

群也表明你DESIRED STATE和LAST STATE服务任务的,所以你可以看到,如果任务是根据服务定义运行。
在运行docker ps任务的节点上运行,查看有关任务容器的详细信息。

[root@foundation67 Desktop]# docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
10ad9beff72e        alpine:latest       "ping 172.25.67.1"   5 minutes ago       Up 5 minutes                            hellowalld.1.863qwi0qzn98iqjhyavhqer8m
  • 扩展群中的服务

一旦您将服务部署到群集中,就可以使用Docker CLI来扩展服务中的容器数量。运行在服务中的容器被称为“任务”。

运行以下命令以更改在群集中运行的服务的所需状态:

ocker service scale =

[root@foundation67 Desktop]# docker service scale hellowalld=5
hellowalld scaled to 5

运行docker service ps 以查看更新的任务列表:

[root@foundation67 Desktop]# docker service ps hellowalld
ID                         NAME              IMAGE   NODE                          DESIRED STATE  CURRENT STATE               ERROR
863qwi0qzn98iqjhyavhqer8m  hellowalld.1      alpine  foundation67.ilt.example.com  Running        Running 8 minutes ago       
6yryer0ydxt2x6lpin12tlgi7  hellowalld.2      alpine  server2                       Running        Preparing 11 seconds ago    
adi26259g1fgvv65mc23ttyx6   \_ hellowalld.2  alpine  server2                       Shutdown       Rejected 12 seconds ago     "No such image: alpine:latest"
ee53jlqgpllcakio43uzgr3eq   \_ hellowalld.2  alpine  server2                       Shutdown       Rejected 33 seconds ago     "No such image: alpine:latest"
cag3ghtb7b1zyhuqyt7sjo5br   \_ hellowalld.2  alpine  server2                       Shutdown       Rejected 54 seconds ago     "No such image: alpine:latest"
aureyduzqcxzabujc9kl5v1km  hellowalld.3      alpine  server1                       Running        Preparing 11 seconds ago    
1mlrloz8sr18t4dtdps3akfzm   \_ hellowalld.3  alpine  server1                       Shutdown       Rejected 12 seconds ago     "No such image: alpine:latest"
ayqmug4k8fngrudzp99hrvcu3   \_ hellowalld.3  alpine  server1                       Shutdown       Rejected 33 seconds ago     "No such image: alpine:latest"
65swd6vs3zvaq8r4bp3sz33xk   \_ hellowalld.3  alpine  server1                       Shutdown       Rejected 54 seconds ago     "No such image: alpine:latest"
63kwbuhvpip1inkd4otgau5wf  hellowalld.4      alpine  server1                       Running        Preparing 11 seconds ago    
b3cr57x8qa9zhctudzeijhxa5   \_ hellowalld.4  alpine  server2                       Shutdown       Rejected 12 seconds ago     "No such image: alpine:latest"
5w4sq6hbt3z20rdnxhi1b3ax1   \_ hellowalld.4  alpine  server2                       Shutdown       Rejected 33 seconds ago     "No such image: alpine:latest"
1z3e5gclyp4tyq4ci35y6kdxc   \_ hellowalld.4  alpine  server1                       Shutdown       Rejected 54 seconds ago     "No such image: alpine:latest"
a9rdkip0mozxlb4haqe41ey95  hellowalld.5      alpine  foundation67.ilt.example.com  Running        Running about a minute ago  
[root@foundation67 Desktop]#

您可以看到,swarm创建了4个新任务,可以扩展到总共5个运行的Alpine Linux实例。任务分布在群体的三个节点之间。一个正在运行manager1。

  • 删除服务节点
[root@foundation67 Desktop]# docker service rm hellowalld \
> 
hellowalld
[root@foundation67 Desktop]# docker service inspect helloworld
[]
Error: no such service: helloworld
  • 将滚动更新应用于服务
[root@foundation67 11.12 docker]# docker service create \
>   --replicas 3 \
>   --name redis \
>   --update-delay 10s \
>   redis:3.0.6
9dmtv0i662sg415rv43v41o51

您可以在服务部署时配置滚动更新策略。

该–update-delay标志配置更新服务任务或任务组之间的时间延迟。您可以将时间描述T为秒数Ts,分钟数Tm或小时数的组合Th。所以 10m30s表示10分30秒的延迟。

默认情况下,调度程序一次更新1个任务。您可以通过此 –update-parallelism标志来配置调度程序同时更新的最大服务任务数。

默认情况下,当对单个任务的更新返回状态时 RUNNING,调度程序调度另一个任务以更新,直到所有任务都更新。如果在任务更新期间的任何时间FAILED,调度程序会暂停更新.
检查redis服务:

[root@foundation67 11.12 docker]#  docker service inspect --pretty redis
ID:     9dmtv0i662sg415rv43v41o51
Name:       redis
Mode:       Replicated
 Replicas:  3
Placement:
UpdateConfig:
 Parallelism:   1
 Delay:     10s
 On failure:    pause
ContainerSpec:
 Image:     redis:3.0.6

更新节点版本:

[root@foundation67 11.12 docker]# docker service update --image redis:3.0.7 redis
redis
```更新过程:
停止第一个任务。
为已停止的任务计划更新。
启动更新的任务的容器。
如果更新任务返回RUNNING,请等待指定的延迟时间,然后开始下一个任务。
如果在更新期间的任何时候任务返回FAILED,请暂停更新。


查看更新后的状态:变成了新的版本




<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker service inspect –pretty redis
ID: 9dmtv0i662sg415rv43v41o51
Name: redis
Mode: Replicated
Replicas: 3
Update status:
State: paused
Started: 2 minutes ago
Message: update paused due to failure or early termination of task 8j4ub39p2sgdi7gl060v0xhc3
Placement:
UpdateConfig:
Parallelism: 1
Delay: 10s
On failure: pause
ContainerSpec:
Image: redis:3.0.7
Resources:

删掉节点:


所有节点都已经运行并且ACTIVE 可用。swarm manager可以将任务分配给任何ACTIVE节点,所以到现在为止所有节点都可以接收任务。

有时,例如计划的维护时间,您需要将节点设置为DRAIN 可用性。DRAIN可用性阻止节点从群管理器接收新任务。这也意味着管理器停止在节点上运行的任务,并在具有ACTIVE可用性的节点上启动副本任务。





<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
3fj7bam3qavua00ksimls79n2 * foundation67.ilt.example.com Ready Active Leader
arlf5530b1mkchbbgcxdm3ikk server2 Ready Active
d58wnlal0wlt9scqu25rlnc0i server1 Ready Active

如上所有节点都是active

查看redis状态;





<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker service ps redis |grep Running
6968c0eb1obxil5hev8gfnq8b redis.1 redis:3.0.7 server2 Running Preparing 19 seconds ago
9v4finugxexzxchvnqqyoblds redis.2 redis:3.0.7 server1 Running Preparing 14 seconds ago
975qber3zecltkv8shi75ssji redis.3 redis:3.0.6 foundation67.ilt.example.com Running Preparing 12 minutes ago
[root@foundation67 11.12 docker]#

<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker node update –availability drain server1
server1
[root@foundation67 11.12 docker]# docker service ps redis |grep Running
1ngiolv8iqhb5zkld3u7g1zpy redis.1 redis:3.0.7 server2 Running Preparing 13 seconds ago
6h9me5vp6brlbdat2foibb6su redis.2 redis:3.0.7 server2 Running Preparing 2 seconds ago
975qber3zecltkv8shi75ssji redis.3 redis:3.0.6 foundation67.ilt.example.com Running Preparing 13 minutes ago
[root@foundation67 11.12 docker]#

如上,可看出节点已经下线了,任务也重新分配了;





<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker node inspect –pretty server1
ID: d58wnlal0wlt9scqu25rlnc0i
Hostname: server1
Joined at: 2017-11-16 01:51:09.159022759 +0000 utc
Status:
State: Ready
Availability: Drain
Platform:
Operating System: linux
Architecture: x86_64
Resources:
CPUs: 1
Memory: 993.1 MiB
Plugins:
Network: bridge, host, null, overlay
Volume: local
Engine Version: 1.12.6

如上,server1处于Drain状态

 - 运行 docker node update --availability active <NODE-ID>以将耗尽的节点返回到活动状态:






<div class="se-preview-section-delimiter"></div>

[root@foundation67 11.12 docker]# docker node update –availability active server1
server1
[root@foundation67 11.12 docker]# docker node inspect –pretty server1
ID: d58wnlal0wlt9scqu25rlnc0i
Hostname: server1
Joined at: 2017-11-16 01:51:09.159022759 +0000 utc
Status:
State: Ready
Availability: Active
Platform:
Operating System: linux
Architecture: x86_64
Resources:
CPUs: 1
Memory: 993.1 MiB
Plugins:
Network: bridge, host, null, overlay
Volume: local
Engine Version: 1.12.6

“`
将节点设置回Active可用性时,可以接收新的任务:
在服务更新期间要扩大规模
在滚动更新
当你设置另一个节点的Drain可用性
当一个任务在另一个活动节点上失败时
即后备,等下一个滚动更新,加入集群或者替代死的;