“这是一个非常棒的docker swarm学习历程。我把一个国外的docker精简实践教学进行了简略的翻译,比起国内博客学习的总结性文章,它更注重让小白在实战背景下容易理解与感悟,激发萌新自我疏理总结实战演练下的小细节。”
文章目录
- 1. docker swarm爱之初体验
- 20.1 初始化集群
- 20.2 加入新节点
- 20.3 创建overlay网络
- 20.4 部署服务service
- 20.5 状态监测
- 20.6 弹缩服务service
- 2. Overlay网络恋习
- 3. docker swam集群实现负载均衡与服务发现美
- 3.1 初始化集群
- 3.2 虚拟IP
- 3.3 服务发现
- 3.4 多主机LB和服务发现
- 4. 跨swarm集群应用滚床单更新
- 4.1 Update Limits
- 4.2 Update Replicas
- 4.3 Update Image
- 4.4 滚动更新
1. docker swarm爱之初体验
将单主机Docker主机转换为多主机Docker swarm集群模式。默认情况下,Docker作为一个隔离的单节点工作。所有容器仅部署在引擎上。群模式将它变成了一个多主机集群感知引擎。
初始化群模式的第一个节点成为管理器。当新的节点加入集群时,它们可以在管理者或工人之间调整角色。您应该在生产环境中运行3-5个管理器,以确保高可用性。
Docker CLI内置了Swarm Mode
$ docker swarm --help Usage: docker swarm COMMAND Manage Swarm Commands: ca Display and rotate the root CA init Initialize a swarm join Join a swarm as a node and/or manager join-token Manage join tokens leave Leave the swarm unlock Unlock swarm unlock-key Manage the unlock key update Update the swarm Run 'docker swarm COMMAND --help' for more information on a command.20.1 初始化集群
最重要的是如何初始化群模式。初始化是通过init完成的。
$ docker swarm init
Swarm initialized: current node (d5oub8tip41v0iedsotw02k1r) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-04j3xv6fsp4h2sp2al7ast6hjcntgrztcf24e13ozxazsbuvpx-cln0834q5dzecdkeiorf84tip 172.17.0.14:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow
运行该命令后,Docker引擎知道如何与集群一起工作,并成为集群的管理器。初始化的结果是一个令牌,用于以安全的方式添加额外的节点。在扩展集群时,请确保此token 令牌的安全性和安全性。
在下一步中,我们将添加更多节点并在这些主机上部署容器。
20.2 加入新节点启用集群模式后,可以添加额外的节点并在所有节点上发出命令。如果节点突然消失,例如,由于崩溃,在这些主机上运行的容器将自动重新调度到其他可用节点上。重新调度确保您不会损失容量,并提供高可用性。
在每个希望添加到集群的附加节点上,使用Docker CLI加入现有组。连接是通过将另一个主机指向集群的当前管理器来完成的。在本例中,是第一个主机。
Docker现在使用一个额外的端口2377来管理集群。应该阻止公共访问该端口,只允许受信任的用户和节点访问该端口。我们建议使用vpn或私有网络来确保访问安全。
第一个任务是获取向集群添加工作人员所需的令牌。出于演示的目的,我们将通过swarm join-token询问管理器这个令牌是什么。在生产中,此令牌应该安全地存储,并且只可由受信任的个人访问。
第二台机器执行:
$ token=$(ssh -o StrictHostKeyChecking=no 172.17.0.14 "docker swarm join-token -q worker") && echo $token Warning: Permanently added '172.17.0.14' (ECDSA) to the list of known hosts. SWMTKN-1-04j3xv6fsp4h2sp2al7ast6hjcntgrztcf24e13ozxazsbuvpx-cln0834q5dzecdkeiorf84tip
在第二个主机上,通过管理器请求访问加入集群。令牌作为附加参数提供。
$ docker swarm join 172.17.0.14:2377 --token $token This node joined a swarm as a worker.
默认情况下,管理器将自动接受添加到集群的新节点。可以通过以下命令查看集群中的所有节点
$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION d5oub8tip41v0iedsotw02k1r * host01 Ready Active Leader 19.03.1320.3 创建overlay网络
群模式还引入了一种改进的网络模型。在以前的版本中,Docker需要使用外部键值存储,如Consul,以确保整个网络的一致性。对协商一致意见和KV的需求现在已被纳入Docker内部,不再依赖外部服务.
改进的网络方法遵循与前面相同的语法。覆盖网络用于不同主机上的容器之间通信。在背后,这是一个虚拟可扩展LAN (VXLAN),设计用于大规模基于云的部署。
下面的命令将创建一个新的覆盖网络称为skynet。所有注册到这个网络的容器都可以彼此通信,而不管它们部署到哪个节点上。
$ docker network create -d overlay skynet 4a687dx7ym4qj8wddr0vn1k0r20.4 部署服务service
默认情况下,Docker使用扩散复制模型来决定哪些容器应该在哪些主机上运行。扩展方法确保容器均匀地部署在集群中。这意味着,如果从集群中删除其中一个节点,实例将已经在其他节点上运行。删除节点上的工作负载将在其余可用节点上重新调度。
服务service的新概念用于跨集群运行容器。这是一个比容器更高级的概念。服务允许您定义应用程序应该如何大规模部署。通过更新服务,Docker以托管的方式更新所需的容器。
在本例中,我们将部署镜像 katacoda/docker-http-server。我们正在为一个名为http的服务定义一个友好的名称,并且它应该被附加到新创建的skynet网络。
为了确保复制和可用性,我们在集群中运行容器的两个副本实例。
最后,我们把这两个容器一起在port 80。向集群中的任何节点发送HTTP请求将由集群中的一个容器处理请求。接受请求的节点可能不是容器响应的节点。相反,Docker在所有可用的容器中对请求进行负载平衡。
$ docker service create --name http --network skynet --replicas 2 -p 80:80 katacoda/docker-http-server rt3hun6j3rtuy33vn2vrn2zv7 overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
通过CLI命令可以查看集群中运行的服务
$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS rt3hun6j3rtu http replicated 2/2 katacoda/docker-http-server:latest *:80->80/tcp
当容器启动时,您将看到它们使用ps命令。您应该在每个主机上看到该容器的一个实例。
列出第一个主机上的容器
$ docker ps ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8f732975d0a5 katacoda/docker-http-server:latest "/app" 2 m
列出第二台主机上的容器
$ docker ps ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 7d5a1b2112cd katacoda/docker-http-server:latest "/app" 2 minutes ago Up 2 minutes 80/tcp http.2.vcxurhlb7j39mq4hmzz6nyagx
如果我们向公共端口发出HTTP请求,它将由两个容器处理
$ curl host0120.5 状态监测This request was processed by host: 7d5a1b2112cd
$ curl host01This request was processed by host: 8f732975d0a5
服务概念允许您检查集群和运行中的应用程序的运行状况和状态。
您可以在集群中查看与某个服务关联的所有任务的列表。在本例中,每个任务都是一个容器
$ docker service ps http ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ey77icv0scbo http.1 katacoda/docker-http-server:latest host01 Running Running 5 minutes ago vcxurhlb7j39 http.2 katacoda/docker-http-server:latest host02 Running Running 5 minutes ago
您可以通过以下方式查看服务的详细信息和配置
$ docker service inspect --pretty http ID: rt3hun6j3rtuy33vn2vrn2zv7 Name: http Service Mode: Replicated Replicas: 2 Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-first RollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-first ContainerSpec: Image: katacoda/docker-http-server:latest@sha256:76dc8a47fd019f80f2a3163aba789faf55b41b2fb06397653610c754cb12d3ee Init: false Resources: Networks: skynet Endpoint Mode: vip Ports: PublishedPort = 80 Protocol = tcp TargetPort = 80 PublishMode = ingress
在每个节点上,您可以询问它当前正在运行哪些任务。Self是指管理节点Leader
通过节点ID可以查询单个主机
$ docker node ls -q | head -n1 d5oub8tip41v0iedsotw02k1r $ docker node ps $(docker node ls -q | head -n1) ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ey77icv0scbo http.1 katacoda/docker-http-server:latest host01 Running Running 7 minutes ago
在下一步中,我们将扩展服务以运行容器的更多实例。
20.6 弹缩服务service服务允许我们扩展在集群中运行的任务实例的数量。由于它了解如何启动容器以及哪些容器正在运行,因此可以根据需要轻松地启动或删除容器。目前缩放是手动的。但是,API可以连接到external system,比如metrics dashboard。
目前,我们有两个运行的负载平衡容器,它们正在处理我们的请求
$ curl host01This request was processed by host: 8f732975d0a5
$ curl host01This request was processed by host: 7d5a1b2112cd
下面的命令将扩展我们的http服务,使其在五个容器中运行。
$ docker service scale http=5 http scaled to 5 overall progress: 5 out of 5 tasks 1/5: running [==================================================>] 2/5: running [==================================================>] 3/5: running [==================================================>] 4/5: running [==================================================>] 5/5: running [==================================================>] verify: Service converged
负载均衡器将自动更新。
2. Overlay网络恋习
默认情况下,Docker作为一个隔离的单节点工作。所有容器仅部署在引擎上。群模式将它变成了一个多主机集群感知引擎。
初始化集群
$ docker swarm init
Swarm initialized: current node (korrjr24x2drfvlu78xi77lno) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1hriikcsgzi577cl3xcu6s0x7kk3058by92vvbtdltjsz8mp9s-3j2cuvx64eqm0tmkmwru6tn9z 172.17.0.139:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
$
在第二台主机上执行下面的命令,将它作为一个worker添加到集群中。
$ token=$(ssh -o StrictHostKeyChecking=no 172.17.0.139 "docker swarm join-token -q worker") && docker swarm join 172.17.0.139:2377 --token $token Warning: Permanently added '172.17.0.139' (ECDSA) to the list of known hosts. This node joined a swarm as a worker.
Overlay Networks是通过Docker CLI创建的,类似于在主机之间创建桥接网络。当创建网络时,将使用一种覆盖驱动类型。当新的服务通过集群模式部署时,它们可以利用这个网络允许容器进行通信.
要创建Overlay Network,使用CLI并定义驱动程序。网络只能通过群管理器节点创建。网络名称为app1-network
$ docker network create -d overlay app1-network vuq3m5hi0t0jkvo1djuhpeqsp $ docker network ls NETWORK ID NAME DRIVER SCOPE vuq3m5hi0t0j app1-network overlay swarm f9000dd7435e bridge bridge local d17623c76ebf docker_gwbridge bridge local 8b89e3388c32 host host local kuugxuiaalh1 ingress overlay swarm
注意:你创建的overlay网络不会出现在工作节点上。manager节点处理网络创建和正在部署的服务。
$ docker network ls NETWORK ID NAME DRIVER SCOPE 1d52a41d7ffb bridge bridge local 398c1bd88b1d docker_gwbridge bridge local 8b89e3388c32 host host local kuugxuiaalh1 ingress overlay swarm b3dc159371bf none null local
一旦创建了网络,就可以部署服务,并能够与网络上的其他容器通信。
下面将使用网络部署Redis服务。该服务的名称将是redis,可用于通过DNS发现。
$ docker service create --name redis --network app1-network redis:alpine wdz1i71gu6c1ep54jjfja1ziu
下一步将在不同的节点上部署一个web应用程序,通过网络与Redis进行交互。
$ docker service create > --network app1-network -p 80:3000 > --replicas 1 --name app1-web > katacoda/redis-node-docker-example p8ktbxnju1cy9vopuaxwobe0q
对于双节点部署,每个容器将被部署到不同的主机上。
他们会利用覆盖网络和DNS发现进行通信。发送HTTP请求将在Redis中保持客户端的IP。
$ docker ps
ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cb586ee1000f redis:alpine "docker-entrypoint.s…" 55 seconds ago Up 52 seconds 6379/tcp redis.1.ajuo5o3z4snh0shbjur9qhnsg
$ curl host01
This page was generated after talking to redis.
Application Build: 1
Total requests: 1
IP count:
::ffff:10.0.0.2: 1
$ curl host01
This page was generated after talking to redis.
Application Build: 1
Total requests: 2
IP count:
3. docker swam集群实现负载均衡与服务发现美
3.1 初始化集群
第一个节点(manager):
$ docker swarm init
Swarm initialized: current node (9qksq9kb8tt9i5un3y2eqbhlj) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5b3w5w10px9ok0t39zs1nujng8x37rcapfkg885hmrokb5wvqi-9v45djurbjeajp3ln80zqcevu 172.17.0.6:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
第二个节点(worker):
$ docker swarm join 172.17.0.6:2377 --token $(ssh -o StrictHostKeyChecking=no 172.17.0.6 "docker swarm join-token -q worker") Warning: Permanently added '172.17.0.6' (ECDSA) to the list of known hosts. This node joined a swarm as a worker.
默认情况下,对服务的请求基于公共端口进行负载均衡。
3.2 虚拟IP下面的命令将创建一个名为lbapp1的新服务,其中运行两个容器。服务通过端口公开81
$ docker service create --name lbapp1 --replicas 2 -p 81:80 katacoda/docker-http-server 7w8k1esxuyx1gs17hwa4svop5
当向集群中端口81上的节点发出请求时,它会将负载分散到两个容器上。
$ curl host01:81This request was processed by host: cbc4fa365043
$ curl host01:81This request was processed by host: faecced3dc9f
HTTP响应指示哪个容器处理请求。在第二台主机上运行命令会得到相同的结果,它会跨这两台主机处理请求。
在下一步中,我们将探讨如何使用它来部署一个实际的应用程序。
3.3 服务发现Docker群模式包括一个路由网,它支持多主机网络。它允许两个不同主机上的容器通信,就像它们在同一主机上一样。它通过创建虚拟可扩展LAN (VXLAN)来实现这一点,VXLAN是为基于云的网络设计的。
路由以两种不同的方式工作。首先,基于公共端口暴露的服务。任何对端口的请求都将被分发。其次,该服务被赋予一个虚拟IP地址,该IP地址仅在Docker网络内部可路由。当向IP地址发出请求时,它们被分发到底层容器。这个虚拟IP是在Docker中的嵌入式DNS服务器上注册的。当基于服务名进行DNS解析时,返回Virtual IP。
在这个步骤中,你将创建一个负载均衡的http,它被附加到一个覆盖网络,并查找它是虚拟IP。
$ docker network create --attachable -d overlay eg1 cf4fx7p2a75irup0pjafylpd4
这个网络将是一个“群体范围网络”。这意味着只有作为服务启动的容器才能将自己附加到网络上。
$ docker service create --name http --network eg1 --replicas 2 katacoda/docker-http-server
通过调用服务http, Docker添加了一个条目到它是嵌入式DNS服务器。网络上的其他容器可以使用友好的名称来发现IP地址。与端口一起,这个IP地址可以在网络内部使用,以达到负载均衡。
使用Dig查找内部虚拟IP。通过使用--attable标志,Swarm服务之外的容器可以访问网络。
$ docker run --name=dig --network eg1 benhall/dig dig http Unable to find image 'benhall/dig:latest' locally latest: Pulling from benhall/dig 12b41071e6ce: Pull complete d23aaa6caac4: Pull complete a3ed95caeb02: Pull complete Digest: sha256:ed7d241f0faea3a015d13117824c04a433a79032619862e4e3741a31eb9e4272 Status: Downloaded newer image for benhall/dig:latest ; <<>> DiG 9.10.2 <<>> http ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59560 ;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;http. IN A ;; ANSWER SECTION: http. 600 IN A 10.0.1.2 ;; Query time: 1 msec ;; SERVER: 127.0.0.11#53(127.0.0.11) ;; WHEN: Thu Sep 30 07:59:23 UTC 2021 ;; MSG SIZE rcvd: 42
通过ping该名称还可以发现IP地址。
$ docker run --name=ping --network eg1 alpine ping -c5 http PING http (10.0.1.2): 56 data bytes 64 bytes from 10.0.1.2: seq=0 ttl=64 time=0.287 ms 64 bytes from 10.0.1.2: seq=1 ttl=64 time=0.108 ms 64 bytes from 10.0.1.2: seq=2 ttl=64 time=0.160 ms 64 bytes from 10.0.1.2: seq=3 ttl=64 time=0.157 ms 64 bytes from 10.0.1.2: seq=4 ttl=64 time=0.131 ms --- http ping statistics --- 5 packets transmitted, 5 packets received, 0% packet loss round-trip min/avg/max = 0.108/0.168/0.287 ms
这应该与给服务的虚拟IP相匹配。您可以通过检查服务来发现这一点。
$ docker service inspect http --format="{{.Endpoint.VirtualIPs}}"
[{cf4fx7p2a75irup0pjafylpd4 10.0.1.2/24}]
每个容器仍然会被赋予一个唯一的IP地址。
$ docker inspect --format="{{.NetworkSettings.Networks.eg1.IPAddress}}" $(docker'{print $1}')cker-http-server | head -n1 | awk
10.0.1.4
这个虚拟IP确保在集群中按照预期的方式进行负载平衡。而IP地址确保它在集群外工作。
3.4 多主机LB和服务发现虚拟IP和端口负载均衡和服务发现都可以用于多主机场景,应用程序可以在不同的主机上与不同的服务通信。
在这个步骤中,我们将部署一个复制的Node.js应用程序,它与Redis通信来存储数据。
首先,需要有一个覆盖网络,应用程序和数据存储可以连接。
$ docker network create -d overlay app1-network
部署Redis时,可以连接网络。应用程序希望能够连接到一个名为Redis的实例。为了使应用程序能够通过嵌入式DNS发现虚拟IP,我们调用服务Redis。
$ docker service create --name redis --network app1-network redis:alpine
每个主机都应该有一个Node.js容器实例,其中一个主机存储Redis。
$ docker ps ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 06f131fda216 redis:alpine "docker-entrypoint.s…" 27 seconds ago Up 25 seconds 6379/tcp redis.1.mq95cigfa7etgefqs1pye9crv 1890d08df8cc katacoda/docker-http-server:latest "/app" 7 minutes ago Up 7 minutes 80/tcp http.2.j5c4ari06egpy3zqw6b0n3iyl
调用HTTP服务器将在Redis中存储请求并返回结果。这是负载平衡,两个容器通过覆盖网络与Redis容器通信。
应用程序现在分布在多个主机上。
4. 跨swarm集群应用滚床单更新
服务可以动态更新,以控制各种设置和选项。在内部,Docker管理如何应用更新。对于某些命令,Docker将停止、删除和重新创建容器。对于管理连接和正常运行时间来说,让所有容器一次性停止是一个重要的考虑因素。
有各种各样的设置你可以控制,通过查看帮助
$ docker service update --help
要启动,需要部署HTTP服务。我们将使用它来更新/修改容器设置。
$ docker swarm init && docker service create --name http --replicas 2 -p 80:80 katacoda/docker-http-server:v1
Swarm initialized: current node (vemt8upto85rpq2c0iv26hfjb) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3ql2gc1k1clslqhyce6ww09fshgvslde4fpkt5wabgc6gewkid-96vytrgsrua2qrgfujq8bdo08 172.17.0.40:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2838c9f2d95l8qxzdin1zn7pa
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
4.1 Update Limits
一旦启动,就可以更新各种属性。例如,向容器添加一个新的环境变量。
$ docker service update --env-add KEY=VALUE http http overall progress: 0 out of 2 tasks overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
或者,更新CPU和内存限制。
$ docker service update --limit-cpu 2 --limit-memory 512mb http http overall progress: 2 out of 2 tasks 1/2: running [==================================================>] 2/2: running [==================================================>] verify: Service converged
一旦执行,当您检查服务时,结果将是可见的.
$ docker service inspect --pretty http ID: 2838c9f2d95l8qxzdin1zn7pa Name: http Service Mode: Replicated Replicas: 2 UpdateStatus: State: completed Started: 38 seconds ago Completed: 23 seconds ago Message: update completed Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Update order: stop-first RollbackConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 Rollback order: stop-first ContainerSpec: Image: katacoda/docker-http-server:v1@sha256:4d7bfcb1e38912d286c5cda63aeddc850a4be16127094ffacbb7abfc6298c5fa Env: KEY=VALUE Resources: Limits: CPU: 2 Memory: 512MiB Endpoint Mode: vip Ports: PublishedPort = 80 Protocol = tcp TargetPort = 80 PublishMode = ingress
但是,在列出所有容器时,您将看到它们在每次更新时都被重新创建.
$ docker ps -a ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 26e2064259ff katacoda/docker-http-server:v1 "/app" about a minute ago Up about a minute 80/tcp http.1.vsv080fuwlsgcqo16m0d3czz9 74c412f02426 katacoda/docker-http-server:v1 "/app" about a minute ago Up about a minute 80/tcp http.2.z6sp9scii6kj4ponoz0wrmv05 deda0102a7e2 katacoda/docker-http-server:v1 "/app" 2 minutes ago Exited (2) about a minute ago http.2.ugilx2q6zkkkw0pwo2f6ydrmi 9b9d3addcc2f katacoda/docker-http-server:v1 "/app" 2 minutes ago Exited (2) about a minute ago http.1.lvhnd9zywl7ioax9t5wi3y9c8 9806903d549f katacoda/docker-http-server:v1 "/app" 2 minutes ago Exited (2) 2 minutes ago http.1.9m8l4jz9cxicel0ff8w3sq8k7 cdcd87d9487d katacoda/docker-http-server:v1 "/app" 2 minutes ago Exited (2) 2 minutes ago http.2.ahrvwdkcd9kkkxp868ppx14v54.2 Update Replicas
并非所有更新都需要重新创建每个容器。例如,扩展副本的数量不会影响现有容器。docker service scale作为一种替代docker服务规模的方法,可以使用更新来定义应该运行多少个副本。下面将把副本从2更新为6。然后Docker将重新安排要部署的另外四个容器。
$ docker service update --replicas=6 http http overall progress: 6 out of 6 tasks 1/6: running [==================================================>] 2/6: running [==================================================>] 3/6: running [==================================================>] 4/6: running [==================================================>] 5/6: running [==================================================>] 6/6: running [==================================================>] verify: Service converged
副本的数量在检查服务时是可见的
$ docker service inspect --pretty http ID: 2838c9f2d95l8qxzdin1zn7pa Name: http Service Mode: Replicated Replicas: 64.3 Update Image
使用更新的最常见场景是通过更新的Docker Image发布应用程序的新版本。由于Docker Image是容器的属性,所以可以像前面的步骤一样对其进行更新。
下面的命令将使用Docker镜像的v2标记重新创建HTTP服务的实例。
$ docker service update --image katacoda/docker-http-server:v2 http http overall progress: 6 out of 6 tasks 1/6: running [==================================================>] 2/6: running [==================================================>] 3/6: running [==================================================>] 4/6: running [==================================================>] 5/6: running [==================================================>] 6/6: running [==================================================>] verify: Service converged
如果你打开一个新的终端窗口,你会注意到Swarm正在执行滚动更新。
$ docker ps ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 35d342b07967 katacoda/docker-http-server:v2 "/app" 49 seconds ago Up 44 seconds 80/tcp http.5.bjdoq1c85l2q2hdv1xkx0q8tb 18da1f1606ef katacoda/docker-http-server:v2 "/app" 54 seconds ago Up 49 seconds 80/tcp http.2.gx464snpuedj2dm0iq1rzgad6 725fdaafe45b katacoda/docker-http-server:v2 "/app" about a minute ago Up 54 seconds 80/tcp http.1.4n0ub4wo24zi8v7ptigbahtsz 5987cf3c84e8 katacoda/docker-http-server:v2 "/app" about a minute ago Up about a minute 80/tcp http.3.rm9ehbhf8gaay83dkb44frd3o 7c68ffd7eb76 katacoda/docker-http-server:v2 "/app" about a minute ago Up about a minute 80/tcp http.6.u9yzhw2reneuipj5na0vkwp8r 2c1b365d7601 katacoda/docker-http-server:v2 "/app" about a minute ago Up about a minute 80/tcp http.4.i8r9ulpxfcldjorqucfryjtgl
通过使用多个副本进行滚动更新,应用程序永远不会宕机,并且可以执行零停机部署。
$ curl http://dockerNew Release! Now v2! This request was processed by host: 35d342b07967
$ curl http://dockerNew Release! Now v2! This request was processed by host: 18da1f1606ef
$ curl http://dockerNew Release! Now v2! This request was processed by host: 725fdaafe45b
$ curl http://dockerNew Release! Now v2! This request was processed by host: 5987cf3c84e8
$ curl http://dockerNew Release! Now v2! This request was processed by host: 7c68ffd7eb76
$ curl http://dockerNew Release! Now v2! This request was processed by host: 2c1b365d7601
$ curl http://dockerNew Release! Now v2! This request was processed by host: 35d342b07967
$
下一步将讨论如何控制推出和零停机部署。
4.4 滚动更新其目的是部署一个新的Docker镜像而不引起任何停机时间。通过设置并行性和延迟,可以实现零停机时间。Docker可以批处理更新,并将其作为跨集群的rollout执行。
- update-parallelism:定义了Docker一次应该更新多少个容器。副本的数量取决于您将对请求进行批量处理的大小。
- update-delay:定义在每个更新批之间等待多长时间。如果应用程序有预热时间(例如启动JVM或CLR),那么延迟是有用的。通过指定延迟,可以确保在流程启动时仍然可以处理请求。
这两个参数在运行docker服务更新时应用。在这个例子中,它一次更新一个容器,在每次更新之间等待10秒。该更新将影响所使用的Docker映像,但参数可以应用于任何可能的更新值
$ docker service update --update-delay=10s --update-parallelism=1 --image katacoda/docker-http-server:v3 http
启动之后,您会慢慢地看到容器的新v3版本启动并替换现有的v2版本。
$ docker ps ConTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bf72245972b2 katacoda/docker-http-server:v3 "/app" 8 seconds ago Up 2 seconds 80/tcp http.5.nk6451tjyjof7bmhrbz8mwa8t db63c2989df4 katacoda/docker-http-server:v3 "/app" 24 seconds ago Up 18 seconds 80/tcp http.2.ymml1p2qcyndx7wdpzt4fgnmd b5e45490f79b katacoda/docker-http-server:v3 "/app" 39 seconds ago Up 34 seconds 80/tcp http.1.l6la8w8cqu87ndenxico2fx4q 5987cf3c84e8 katacoda/docker-http-server:v2 "/app" 7 minutes ago Up 6 minutes 80/tcp http.3.rm9ehbhf8gaay83dkb44frd3o 7c68ffd7eb76 katacoda/docker-http-server:v2 "/app" 7 minutes ago Up 7 minutes 80/tcp http.6.u9yzhw2reneuipj5na0vkwp8r 2c1b365d7601 katacoda/docker-http-server:v2 "/app" 7 minutes ago Up 7 minutes 80/tcp http.4.i8r9ulpxfcldjorqucfryjtgl
向负载均衡器发出HTTP请求将请求v2和v3容器处理它们,从而产生不同的输出。
$ curl http://dockerNew Release! Now v2! This request was processed by host: 5987cf3c84e8
$ curl http://dockerNew Another Release! Now v3! This request was processed by host: 8349dd465a7e
$ curl http://dockerNew Another Release! Now v3! This request was processed by host: 09860150d9b1
$ curl http://dockerNew Another Release! Now v3! This request was processed by host: bf72245972b2
$ curl http://dockerNew Another Release! Now v3! This request was processed by host: db63c2989df4
$ curl http://dockerNew Another Release! Now v3! This request was processed by host: b5e45490f79b
应用程序必须考虑到这一点,并同时处理两个不同的版本。
相关阅读:
- docker 快速学习手册
- docker 的冷门高效玩法
- docker 命令使用大全
- 公司要新招美女跟我学docker,你来吗?
参考资料:
- https://www.katacoda.com/courses/docker



