docker update_docker系列之swarm模式

前言

Docker Swarm可以看做是多个Docker Engines的集群方式,是docker的一种编排工具,当前版本的Docker包含swarm模式,用于本地管理称为Swarm的Docker引擎集群。 使用Docker CLI创建集群,将应用程序服务部署到集群以及管理集群行为。

Docker Engine中嵌入的集群管理和编排功能是使用swarmkit构建的。 Swarmkit是一个单独的项目,用于实现Docker的业务流程层,并直接在Docker中使用。

一个群集由多个Docker主机组成,这些Docker主机以群集模式运行,并充当管理员(用于管理成员资格和委派)和工作人员(运行群集服务)。 给定的Docker主机可以是管理员,工作人员或同时担任这两个角色。 创建服务时,您要定义其最佳状态(可用副本,网络和存储资源的数量,服务向外界公开的端口等)。 Docker致力于维持所需状态。 例如,如果一个工作节点不可用,则Docker会将该节点的任务安排在其他节点上。 任务是一个运行中的容器,它是群集服务的一部分,由群集管理器管理,而不是独立的容器。

5cb176ce88d66b1d34c2ee75be23a9ce.png

更多表示请参考官方文档https://docs.docker.com/engine/swarm/key-concepts/

部署方式

首先准备两台或者三台可以使用的主机,比如manager1、manager2、manage3

登录主机manager1用来创建swarm集群管理节点。

docker swarm init --advertise-addr 192.168.99.1

这里的-- advertise-addr表示集群对外暴露的ip,后续所有的节点要加入到要通过

此ip加入。如果不指定,则机器会自动选择合理的ip,如下所示:

docker swarm initSwarm initialized: current node (ulypq2b3eb176aka0rtzjmnnp) is now a manager.To add a worker to this swarm, run the following command:docker swarm join --token SWMTKN-1-4b0aux48r0yib3jt5kuhw12cbd73a8vxh4vo6zt3nlpcpz7o26-9xs3ss6s5odmvx9cxw7k1vxu4 172.21.0.10:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

到此一个swarm集群管理创建成功。

然后分别登录manager2、manager3执行如下命令将另外两个节点加入到此管理节点中。

docker swarm join --token SWMTKN-1-4b0aux48r0yib3jt5kuhw12cbd73a8vxh4vo6zt3nlpcpz7o26-9xs3ss6s5odmvx9cxw7k1vxu4 172.21.0.10:2377命令加入到此节点当中

如果以上命令找不到可以使用docker swarm join-token worker命令将其找回。

到此执行docker info查看swarm当前节点的状态

Swarm: active NodeID: ulypq2b3eb176aka0rtzjmnnp Is Manager: true ClusterID: gcrsq6qqaqhwiekecirdmldco Managers: 1 Nodes: 1 Default Address Pool: 10.0.0.0/8   SubnetSize: 24 Orchestration: Task History Retention Limit: 5

执行docker node ls查看连接到的节点

39afb6266cba8a412564eec21ce675c1.png

部署服务到swarm节点

docker service create --replicas 1 --name helloworld alpine ping docker.com

-- replaicas 1表示期望一个服务实例

-- name 表示运行的服务名称

alpine ping docker.com 表示运行的镜像是alpine 命令为ping,如下图,创建成功一个服务实例

20fd793020931e8a695c797bc4b41e0f.png

可以使用docekr service ls来查看运行的服务实例。

c3685a08c6b434dba3b6a9bc3b32982b.png

运行命令docker service inspect --pretty 服务id

来查看优化显示的服务详情 去掉以joson显示

docker service inspect --pretty b9cmmraop0tbID:b9cmmraop0tbrcc6z6ld47fnhName:helloworldService Mode:Replicated Replicas:1Placement:UpdateConfig: Parallelism:1 On failure:pause Monitoring Period: 5s Max failure ratio: 0 Update order:      stop-firstRollbackConfig: Parallelism:1 On failure:pause Monitoring Period: 5s Max failure ratio: 0 Rollback order:    stop-firstContainerSpec: Image:alpine:latest@sha256:185518070891758909c9f839cf4ca393ee977ac378609f700f60a771a2dfe321 Args:ping docker.com  Init:falseResources:Endpoint Mode:vip

运行docker service ps 服务id 将查看到哪些节点在运行该服务实例

docker service ps b9cmmraop0tbID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTSp5vnvit9gbp9        helloworld.1        alpine:latest       zhaoyd      

同时使用docekr ps也可以看到运行的容器

ec97479908037b8074893bff0931dd59.png

swarm集群删除应用

docker service rm helloworld

swarm的滚动更新

docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.7-alpine

这里使用redis镜像测试滚动更新任务--update-delay 表示更新服务对应的任务或一组任务之间的时间间隔。时间间隔用数字和时间单位表示,m 表示分,h 表示时,所以 10m30s 表示 10 分 30 秒的延时。

默认情况下,调度器一次更新一个任务。你可以使用 --update-parallelism 标志配置调度器每次同时更新的最大任务数量。

默认情况下,如果更新某个任务返回了RUNNING状态,调度器会转去更新另一个任务,直到所有任务都更新完成。如果在更新某个任务的任意时刻返回了FAILED,调度器暂停更新。我们可以在执行 docker service create 命令和 docker service update 命令时使用 --update-failure-action 标志来覆盖这种默认行为

更新redis镜像

swarm管理节点会根据UpdateConfig策略来更新节点

docker service update --image redis:3.2.5-alpine redis

调度器根据下面默认的策略来应用滚动更新:

  • 停止第一个任务。
  • 未停止的任务应用更新。
  • 为更新的任务启动容器。
  • 如果更新任务时返回RUNNING,等待一个指定的延时后停止下一个任务。
  • 如果,在更新的任意时刻,某个任务返回FAILED,暂停更新

docker service inspect --pretty redis 查看状态可以看到已经更新到期望版本。

下线某个swarm节点

从前面的示例中可以看出swarm的状态为avtive,表示所有节点可以接受任务有时候,比如到了计划的维护时间,你需要将节点的可用性设为DRAIN。可用性为DRAIN的节点不会从 swarm 接收任何新任务。同时,管理器将停止运行在该节点上的任务,并在另外可用性为 ACTIVE 的节点上启动相应的任务副本。

通过docker node ls命令查看可用节点使用docker node update --availability drain manager2下线

此时查看被下线的服务,则可以看到状态已经变更为drain

$ docker node lsID                           HOSTNAME   STATUS  AVAILABILITY  MANAGER STATUS4rkvaeauhftolat98u5ty01iz    worker02   Ready   Drain         7ik7wqhe5wcag8k5tp816c7ck *  manager01  Ready   Active        Leadercashcvy4qzcq3lvtnix4trqu7    worker01   Ready   Activ

那么如何修改为活动状态呢。使用如下命令即可恢复

docker node update --availability active manager2

swarm模式下的覆盖网络

当Docker在swarm模式下运行时,您可以在管理节点上创建覆盖网络,而无需外部key-value存储。swarm使覆盖网络仅可用于需要服务的swarm节点。 当您创建使用覆盖网络的服务时,管理节点会自动将覆盖网络扩展到运行服务任务的节点。

下面的示例显示了如何创建网络并将其用于来自swarm管理节点的服务:

$ docker network create   --driver overlay   --subnet 10.0.9.0/24   my-multi-host-network400g6bwzd68jizzdx5pgyoe95$ docker service create --replicas 2 --network my-multi-host-network --name my-web nginx716thylsndqma81j6kkkb5aus

上述代码创建的服务就是使用的my-multi-host-network自定义的覆盖网络。

只有swarm服务可以连接到覆盖网络,而不是独立的容器

非swarm模式下的覆盖网络

如果您不是在swarm模式下使用Docker Engine,那么overlay网络需要有效的key-value存储。 支持的key-value存储包括Consul,Etcd和ZooKeeper(分布式存储)。 在以这种方式创建网络之前,您必须安装并配置您所选择的key-value存储服务。 网络中的Docker宿主机、服务必须能够进行通信。

注意 :以swarm模式运行的Docker Engine与使用外部key-value存储的网络不兼容。

自定义网络插件

如果任何上述网络机制无法满足您的需求,您可以使用Docker的插件基础架构编写自己的网络驱动插件。 该插件将在运行Docker deamon的主机上作为单独的进程运行。 使用网络插件是一个高级主题。

网络插件遵循与其他插件相同的限制和安装规则。 所有插件都使用插件API,并具有包含了安装,启动,停止和激活的生命周期。

创建并安装自定义网络驱动后,您可以使用--driver 标志创建一个使用该驱动的网络。

 docker network create --driver weave mynet

内嵌DNS服务器

Docker daemon运行一个嵌入式的DNS服务器,从而为连接到同一用户自定义网络的容器之间提供DNS解析——这样,这些容器即可将容器名称解析为IP地址。 如果内嵌DNS服务器无法解析请求,它将被转发到为容器配置的任意外部DNS服务器。 为了方便,当容器创建时,只有127.0.0.11 可访问的内嵌DNS服务器会列在容器的resolv.conf文件中。

暴露和发布端口

在Docker网络中,有两种不同的机制可以直接涉及网络端口:暴露端口和发布端口。 这适用于默认网桥和用户定义的网桥。

  • 您使用Dockerfile 中的EXPOSE 关键字或 docker run 命令中的--expose 标志来暴露端口。 暴露端口是记录使用哪些端口,但实际上并不映射或打开任何端口的一种方式。 暴露端口是可选的。
  • 您可以使用Dockerfile 中的PUBLISH 关键字或 docker run 命令中的--publish标志来发布端口。 这告诉Docker在容器的网络接口上打开哪些端口。当端口发布时,它将映射到宿主机上可用的高阶端口(高于30000 ),除非您在运行时指定要映射到宿主机的哪个端口。 您不能在Dockerfile中指定要映射的端口,因为无法保证端口在运行image的宿主机上可用。此示例将容器中的端口80发布到宿主机上的随机高阶端口(在这种情况下为32768 )。 -d 标志使容器在后台运行,因此您可以发出docker ps 命令。
docker run -it -d -p 80 nginx$ docker ps64879472feea        nginx               "nginx -g 'daemon ..."   43 hours ago        Up About a minute   443/tcp, 0.0.0.0:32768->80/tcp   blissful_mclean

下一个示例指定80端口应映射到宿主机上的8080端口。 如果端口8080不可用,将失败。

$ docker run -it -d -p 8080:80 nginx$ docker psb9788c7adca3        nginx               "nginx -g 'daemon ..."   43 hours ago        Up 3 seconds        80/tcp, 443/tcp, 0.0.0.0:8080->80/tcp   goofy_brahmagupta

容器与代理服务器

如果您的容器需要使用HTTP、HTTPS或者FTP代理,你可以使用如下两种方式进行配置:

  • 对于Docker 17.07或更高版本,你可以配置Docker客户端从而将代理信息自动传递给容器。
  • 对于Docker 17.06或更低版本,你必须在容器内设置环境变量。你可以在构建镜像(这样不太好移植)或启动容器时执行此操作。

在Docker客户端上,在启动容器所使用的用户的主目录中创建或编辑~/.config.json 文件。在其中添加如类似下所示的JSON,如果需要,使用httpsproxy 或ftpproxy 替换代理类型,然后替换代理服务器的地址和端口。 您可以同时配置多个代理服务器。

您可以通过将noProxy 键设置为一个或多个逗号分隔的IP地址或主机名来选择将指定主机或指定范围排除使用代理服务器。 支持使用*字符作为通配符,如此示例所示。

{  "proxies":  {    "httpProxy": "http://127.0.0.1:3001",    "noProxy": "*.test.example.com,.example2.com"  }}

保存文件

2、当您创建或启动新容器时,环境变量将在容器内自动设置。

手动设置环境变量

在构建映像时,或在创建或运行容器时使用--env 标志,可将下表中的一个或多个变量设置为适当的值。 这种方法使镜像不太可移植,因此如果您使用Docker 17.07或更高版本,则应该配置Docker客户端。

                   变量                               Dockerfile示例                              docker   run示例HTTP_PROXYENV HTTP_PROXY        "http://127.0.0.1:3001"     --env HTTP_PROXY "http://127.0.0.1:3001"HTTPS_PROXYENV HTTPS_PROXY     "https://127.0.0.1:3001"    --env HTTPS_PROXY "https://127.0.0.1:3001"FTP_PROXYENV FTP_PROXY              "ftp://127.0.0.1:3001"        --env FTP_PROXY "ftp://127.0.0.1:3001"NO_PROXY     `ENV NO_PROXY “*.test.example.com,.example2.com”    -env NO_PROXY“* .test.example.com,.example2.com”

在Docker包含“用户自定义网络”功能之前,您可以使用Docker --link 功能来允许容器将另一个容器的名称解析为IP地址,还可以访问你所链接的容器的环境变量。 如果可以,您应该避免使用 --link 标志。

当您创建连接时,当您使用默认bridge 或用户自定义网桥时,它们的行为会有所不同

Docker和iptables

Linux主机使用内核模块iptables 来管理对网络设备的访问,包括路由,端口转发,网络地址转换(NAT)等问题。 Docker会在启动或停止发布端口的容器、创建或修改网络、attach到容器或其他与网络相关的操作时修改iptables 规则。

对iptables 全面讨论超出了本主题的范围。 要查看哪个iptables 规则在任何时间生效,可以使用iptables -L 。 如存在多个表,例如nat , prerouting 或postrouting ,您可以使用诸如iptables -t nat -L 类的命令列出特定的表。 有关iptables 的完整文档,请参阅netfilter / iptables 。

通常, iptables规则由初始化脚本或守护进程创建,例如firewalld 。 规则在系统重新启动时不会持久存在,因此脚本或程序必须在系统引导时执行,通常在运行级别3或直接在网络初始化之后运行。请参阅您的Linux发行版的网络相关的文档,了解如何使iptables 规则持续存在。

Docker动态管理Docker daemon、容器,服务和网络的iptables 规则。 在Docker 17.06及更高版本中,您可以向名为DOCKER-USER的新表添加规则,这些规则会在Docker自动创建任何规则之前加载。 如果您需要在Docker运行之前预先设置需要使用的iptables 规则,这将非常有用

到此本篇文章就说完了,可能有点长,不过建议收藏,后续还可以拿来参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值