ops-21 Linux添加静态路由-Swarm入门
添加到主机的路由
route add -host 39.156.66.10 gw 10.1.1.2
添加到网络的路由
route add –net 39.156.66.0 netmask 255.255.255.0 gw 10.1.1.2
route add -net 39.156.66.0/24 gw 10.1.1.2 eth0
添加默认网关
route add default gw 10.1.1.2 eth0
删除路由
route del -net 10.1.1.0/24 dev eth0
#永久生效(添加 route-eth2 静态路由配置文件)
10.219.1.128/25 via 10.219.1.129 dev eth2
| # 一、Swarm介绍 |
|---|
| Swarm是Docker公司自研发的容器集群管理系统, Swarm在早期是作为一个独立服务存在, 在Docker Engine v1.12中集成了Swarm的集群管理和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。 |
| Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务。也增加了服务栈(Stack)、服务(Service)、任务(Task)概念。 |
| # 二、Swarm的亮点 |
| 参考链接( https://docs.docker.com/engine/swarm/ ) |
| \1. Docker Engine集成集群管理 |
| 使用Docker Engine CLI 创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务。 |
| \2. 去中心化设计 |
| Swarm角色分为Manager和Worker节点, Manager节点故障不影响应用使用。 |
| \3. 扩容缩容 |
| 可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态。 |
| \4. 期望状态协调 |
| Swarm Manager节点不断监视集群状态,并调整当前状态与期望状态之间的差异。 |
| \5. 多主机网络 |
| 可以为服务指定overlay网络。当初始化或更新应用程序时, Swarm manager会自动为overlay网络上的容器分配IP地址。 |
| \6. 服务发现 |
| Swarm manager节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过Swarm内置的DNS服务器查询集群中每个运行的容器。 |
| \7. 负载均衡 |
| 实现服务副本负载均衡,提供入口访问。 |
| \8. 安全传输 |
| Swarm中的每个节点使用TLS相互验证和加密, 确保安全的其他节点通信。 |
| \9. 滚动更新 |
| 升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先前版本。 |
| # 三、swarm关键概念 |
| 参考链接:https://docs.docker.com/engine/swarm/key-concepts/ |
| ## 1、什么是swarm? |
| 集群管理和任务编排功能已经集成到了Docker引擎中,通过使用swarmkit。swarmkit是一个独立的,专门用于Docker容器编排的项目,可以直接在Docker上使用。 |
| Swarm集群是由多个运行swarm模式的Docker主机组成,关键的是,Docker默认集成了swarm mode。swarm集群中有manager(管理成员关系和选举)、worker(运行swarm service)。 |
| 一个Docker主机可以是manager,也可以是worker角色,当然,也可以既是manager,同时也是worker。 |
| 当你创建一个service时,你定义了它的理想状态(副本数、网络、存储资源、对外暴露的端口等)。Docker会维持它的状态,例如,如果一个worker node不可用了,Docker会调度不可用node的task到其他nodes上。 |
| 运行在容器中的一个task,是swarm service的一部分,且通过swarm manager进行管理和调度,和独立的容器是截然不同的。 |
| swarm service相比单容器的一个最大优势就是,你能够修改一个服务的配置:包括网络、数据卷,不需要手工重启服务。Docker将会更新配置,把过期配置的task停掉,重新创建一个新配置的容器。 |
| 当然,也许你会觉得docker compose也能做swarm类似的事情,某些场景下是可以。但是,swarm相比docker compose,功能更加丰富,比如说自动扩容、缩容,分配至task到不同的nodes等。 |
| ## 2、nodes |
| 一个node是Swarm集群中的一个Docker引擎实例。你也可以认为这就是一个docker节点。你可以运行一个或多个节点在单台物理机或云服务器上,但是生产环境上,典型的部署方式是:Docker节点交叉分布式部署在多台物理机或云主机上。 |
| 通过swarm部署一个应用,你向manager节点提交一个service,然后manager节点分发工作(task)给worker node。 |
| manager节点同时也会容器编排和集群管理功能,它会选举出一个leader来指挥编排任务。worker nodes接受和执行从manager分发过来的task。一般地,manager节点同时也是worker节点,但是,你也可以将manager节点配置成只进行管理的功能。 |
| Agent则运行在每个worker节点上,时刻等待着接受任务。worker node会上报manager node,分配给他的任务当前状态,这样manager node才能维持每个worker的工作状态。 |
| ## 3、services和tasks |
| service就是在manager或woker节点上定义的tasks。service是swarm系统最核心的架构,同时也是和swarm最主要的交互者。当你创建一个service,你指定容器镜像以及在容器内部运行的命令。 |
| 在副本集模式下,swarm manager将会基于你需要扩容的需求,把task分发到各个节点。对于全局service,swarm会在每个可用节点上运行一个task。 |
| task携带Docker引擎和一组命令让其运行在容器中。它是swarm的原子调度单元。manager节点在扩容的时候回交叉分配task到各个节点上,一旦一个task分配到一个node,它就不能移动到其他node。 |
| ## 4、负载均衡 |
| swarm manager使用 ingress负载均衡来暴露你需要让外部访问的服务。swarm manager能够自动的分配一个外部端口到service,当然,你也能够配置一个外部端口,你可以指定任意没有使用的port,如果你不指定端口,那么swarm manager会给service指定30000-32767之间任意一个端口。 |
| swarn模式有一个内部的DNS组件,它能够自动分发每个服务在swarm里面。swarm manager使用内部负载均衡机制来接受集群中节点的请求,基于DNS名字解析来实现。 |
| # 四、Swarm架构图 |
![]() |
| Swarm manager: |
| 1、API:接受命令,创建一个service(API输入) |
| 2、orchestrator:service对象创建的task进行编排工作(编排) |
| 3、allocater:为各个task分配IP地址(分配IP) |
| 4、dispatcher:将task分发到nodes(分发任务) |
| 5、scheduler:安排一个worker运行task(运行任务) |
| worker node |
| 1、连接到分发器接受指定的task |
| 2、将task指派到对应的worker节点 |
| 例子: |
![]() |
| swarm manager创建一个3个nginx副本集的service,他会将task分配到对应的node。 |
| # 五、swarm集群部署 |
| ## 安装需求 |
| 1、主机安装了docker,Docker Engine 1.12+ |
| 2、关闭selinux、关闭防火墙(或者按照下面需要打开的端口开放防火墙) |
| 3、协议端口开放 |
| - TCP port 2377 集群管理通讯 |
| - TCP and UDP port 7946 节点之间通讯 |
| - UDP port 4789 overlay网络流量 |
| ## 机器分布 |
| ## 部署swarm |
| manager节点: |
| ``` |
| docker swarm init --advertise-addr 10.11.97.71 |
| ``` |
| 日志查看: |
| ``` |
[root@localhost ~]# docker swarm init --advertise-addr 10.11.97.71``Swarm initialized: current node (nnkbd7e2emx24ymnzyvxv7h2b) ``is now a manager. To add a worker to ``this swarm, run the following command: ``docker swarm ``join --token SWMTKN-1-4y22cau9ejhrppdlf2g5y7dn6ibltq67ccvoiw2xf3yoj5i5ii-69yg43tece4d5sbwl1a1ftmu9 10.11.97.71:2377 To add a manager to ``this swarm, run ``'docker swarm join-token manager' and follow the instructions. [root@localhost ~]# |
| ``` |
| worker01节点加入集群: |
| ``` |
[root@worker01 compose_nginx_tomcat]# docker swarm join` `--token SWMTKN-1-4y22cau9ejhrppdlf2g5y7dn6ibltq67ccvoiw2xf3yoj5i5ii-69yg43tece4d5sbwl1a1ftmu9 10.11.97.71:2377This node joined a swarm as` `a worker.[root@localhost compose_nginx_tomcat]# |
| ``` |
| worker02节点加入集群: |
| ``` |
[root@worker02 ~]# docker swarm join` `--token SWMTKN-1-4y22cau9ejhrppdlf2g5y7dn6ibltq67ccvoiw2xf3yoj5i5ii-69yg43tece4d5sbwl1a1ftmu9 10.11.97.71:2377This node joined a swarm as` `a worker.[root@localhost ~]# |
| ``` |
| 查看node状态: |
![]() |
| ## 部署一个服务 |
| ``` |
| docker service create --replicas 1 --name helloworld alpine ping docker.com |
| ``` |
![]() |
| --replicas 副本集数 |
| --name 服务名称 |
| ## 查看服务 |
![]() |
| 当前服务运行在manager上。 |
| ``` |
| ``` |
![]() |
| # 六、swarm集群服务管理 |
| ## 1、创建服务 |
| docker service create --replicas 1 --name web01 nginx |
![]() |
| ## 2、显示服务详细信息 |
| docker service inspect --pretty web01# 易于阅读显示 |
![]() |
| docker service inspect web01# json格式返回 |
![]() |
| ## 3、扩容和缩容 |
| docker service scale web01=3 |
![]() |
| ## 4、查看服务任务 |
| docker service ls(查看所有service) |
![]() |
| docker service ps web01(查看web01) |
![]() |
| 每个node上分布了1个容器。 |
| docker service ps -f 'desired-state=running' web01(查看运行状态的service) |
![]() |
| ## 5、滚动更新服务 |
| docker service create \ |
| --replicas 3 \ |
| --name redis \ |
| --update-delay 10s \ |
| redis:3.0.6 |
| docker service update --image redis:3.0.7 redis |
| ## 6、创建服务时设定更新策略 |
| docker service create \ |
| --name my_web |
| --replicas 10 \ |
| --update-delay 10s \ |
| --update-parallelism 2 \ |
| --update-failure-action continue \ |
| nginx:1.12 |
| ## 7、创建服务时设定回滚策略 |
| docker service create \ |
| --name my_web \ |
| --replicas 10 \ |
| --rollback-parallelism 2 \ |
| --rollback-monitor 20s \ |
| --rollback-max-failure-ratio .2 \ |
| nginx:1.12 |
| ## 8、服务更新 |
| docker service update --image nginx:1.13 my_web |
| ## 9、手动回滚 |
| docker service update --rollback my_web |
| ## 10、角色切换 |
| 升级前: |
![]() |
| 升级: |
| 停掉manager |
| systemctl stop docker |
| 将worker02升级 |
| docker node promote worker02 |
![]() |
| 升级后: |
![]() |
| # 七、swarm集群数据管理 |
| ## 1、volume方式管理数据 |
| volume模式:在宿主机上创建一个volume,默认目录为(/var/lib/docker/volume/your_custom_volume/_data),然后把容器的某个目录映射到宿主机的volume上,即使容器挂了,数据还会依然保留在宿主机的volume上。 |
| ``` |
| docker service create --replicas 1--mount type=volume,src=nginx^Cata,dst=/usr/share/nginx/html --name www_web01 nginx:1.12 |
| ``` |
![]() |
| 查看服务 |
| docker service inspect www_web01 |
| 服务ID |
| 服务版本 |
| 服务创建时间 |
| 服务更新时间 |
| 服务详细配置 |
| 服务名称 |
| 服务标签 |
| 服务的容器配置 |
| 镜像名称 |
| 挂载点 |
| 资源限制 |
| 重启策略 |
| 更新配置 |
| 回滚配置 |
| 挂载点配置 |
| ``` |
| [`` ``{`` ``"ID"``: ``"7ge7vfprynybyvz9otwomzumv"``,`` ``"Version"``: {`` ``"Index"``: 313`` ``},`` ``"CreatedAt"``: ``"2019-07-20T04:16:41.677166218Z"``,`` ``"UpdatedAt"``: ``"2019-07-20T04:16:41.677166218Z"``,`` ``"Spec"``: {`` ``"Name"``: ``"www_web01"``,`` ``"Labels"``: {},`` ``"TaskTemplate"``: {`` ``"ContainerSpec"``: {`` ``"Image"``: ``"nginx:1.12@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728"``,`` ``"Init"``: ``false``,`` ``"Mounts"``: [`` ``{`` ``"Type"``: ``"volume"``,`` ``"Source"``: ``"nginx_data"``,`` ``"Target"``: ``"/usr/share/nginx/html"`` ``}`` ``],`` ``"StopGracePeriod"``: 10000000000,`` ``"DNSConfig"``: {},`` ``"Isolation"``: ``"default"`` ``},`` ``"Resources"``: {`` ``"Limits"``: {},`` ``"Reservations"``: {}`` ``},`` ``"RestartPolicy"``: {`` ``"Condition"``: ``"any"``,`` ``"Delay"``: 5000000000,`` ``"MaxAttempts"``: 0`` ``},`` ``"Placement"``: {`` ``"Platforms"``: [`` ``{`` ``"Architecture"``: ``"amd64"``,`` ``"OS"``: ``"linux"`` ``},`` ``{`` ``"OS"``: ``"linux"`` ``},`` ``{`` ``"Architecture"``: ``"arm64"``,`` ``"OS"``: ``"linux"`` ``},`` ``{`` ``"Architecture"``: ``"386"``,`` ``"OS"``: ``"linux"`` ``},`` ``{`` ``"Architecture"``: ``"ppc64le"``,`` ``"OS"``: ``"linux"`` ``},`` ``{`` ``"Architecture"``: ``"s390x"``,`` ``"OS"``: ``"linux"`` ``}`` ``]`` ``},`` ``"ForceUpdate"``: 0,`` ``"Runtime"``: ``"container"`` ``},`` ``"Mode"``: {`` ``"Replicated"``: {`` ``"Replicas"``: 1`` ``}`` ``},`` ``"UpdateConfig"``: {`` ``"Parallelism"``: 1,`` ``"FailureAction"``: ``"pause"``,`` ``"Monitor"``: 5000000000,`` ``"MaxFailureRatio"``: 0,`` ``"Order"``: ``"stop-first"`` ``},`` ``"RollbackConfig"``: {`` ``"Parallelism"``: 1,`` ``"FailureAction"``: ``"pause"``,`` ``"Monitor"``: 5000000000,`` ``"MaxFailureRatio"``: 0,`` ``"Order"``: ``"stop-first"`` ``},`` ``"EndpointSpec"``: {`` ``"Mode"``: ``"vip"`` ``}`` ``},`` ``"Endpoint"``: {`` ``"Spec"``: {}`` ``}`` ``}``] |
| ``` |
| 查看数据卷 |
![]() |
![]() |
| 因为我硬盘的数据盘在/data,所以我这里已经把docker的Root Dir设置成/data/docker/,可以看到容器里面的nginx数据目录已经挂在到宿主机的nginx_data了。 |
| ## 2、bind mount方式管理数据 |
| bind mount模式:将宿主机某个目录映射到docker容器,很适合于网站,同时把宿主机的这个目录作为git版本目录,每次update代码的时候,容器就会更新。 |
| 创建数据目录 |
| 在mananger、worker01、worker02上创建web网站目录: |
| mkdir -p /data/wwwroot |
| 创建服务 |
| ``` |
| docker service create --replicas 1--mount type=bind,src=/data/wwwroot,dst=/usr/share/nginx/html --name www_web02 nginx:1.12 |
| ``` |
![]() |
| 查看服务 |
| 运行在worker02 |
![]() |
| 测试宿主机的数据盘和容器是映射关系: |
![]() |
| 进入容器查看内容: |
![]() |
| 可以看到我们在宿主机上创建的index.html已经挂在到容器上了! |
| ## 3、NFS方式管理数据 |
| 前面两种方式都是单机docker上数据共享方式,要是在集群中,这个就不适用了,我们必须使用共享存储或网络存储了。这里我们使用NFS来测试。 |
| 安装NFS服务 |
| 我们使用第三台(worker02作为NFS服务提供者) |
| yum install nfs-utils -y |
| 并且在nfs目录放入网站数据内容: |
| [root@worker02 container_data]# echo 'hello nfs' >index.html |
| 其他两个节点(worker01和manager均需要安装nfs客户端) |
| 创建服务 |
| ``` |
docker service create ``--mount 'type=volume,src=nfs-vol,dst=/usr/share/nginx/html, ``volume-driver=local,volume-opt=type=nfs,``volume-opt=device=:/data/container_data,"volume-opt=o=addr=10.11.97.187,vers=4,soft,timeo=180,bg,tcp,rw"' ``--name www_web03_nfs nginx:1.12 |
| ``` |
| swarm支持挂在NFS卷。 |
![]() |
| 可以查看到nfs已经挂在到manager节点了,且nfs里面的内容也在。 |
![]() |
| 进入容器查看: |
![]() |
| # 八、swarm集群发布 |
| ## 架构图 |
![]() |
| 服务发现: Swarm模式内置DNS组件,自动为每个服务分配DNS记录,然后服务的DNS名称在集群内的服务直接分发请求。 |
| 负载均衡:在Swarm集群中创建服务时, Ingress网络会自动为其分配一个虚拟IP(VIP),在DNS解析时返回VIP,流入该VIP的流量将自动发送(IPVS)该服务的所以健康任 |
| 务(容器)。 |
| 在每个节点上创建服务,使用ingress暴露publish port: |
| docker service create --replicas=3 --name web01 -p 88:80 nginx:1.12 |
![]() |
| 可以看到每个node上各分部了一个容器: |
![]() |
| 这时你直接访问:http://10.11.97.71:88就可以访问网站了。 |
| 注意: |
| 如果你关掉某个节点上web01的服务,swarm会再次启动一个服务,以达到原来task的个数。 |
| 在真实环境中,我们可以在swarm集群中的每个节点启动指定个数的tasks,然后在前端使用负载均衡设备,比如HA或Nginx都行,直接通过负载均衡的方式做到高可用。 |
| 查看service |
| docker service inspect web01 |
| ``` |
[ { "ID": "ii7ggbrqfsl417oqs9xgr877q", #ID "Version": { #版本 "Index": 753 }, "CreatedAt": "2019-07-20T15:12:36.035445496Z", #创建时间 "UpdatedAt": "2019-07-20T15:12:36.037336323Z", #更新时间 "Spec": { #详细配置 "Name": "web01", #服务名称 "Labels": {}, "TaskTemplate": { "ContainerSpec": { #容器配置 "Image": "nginx:1.12@sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728", "Init": false, "StopGracePeriod": 10000000000, "DNSConfig": {}, "Isolation": "default" }, "Resources": { #资源限制 "Limits": {}, "Reservations": {} }, "RestartPolicy": { #重启策略 "Condition": "any", "Delay": 5000000000, "MaxAttempts": 0 }, "Placement": { #平台相关 "Platforms": [ { "Architecture": "amd64", "OS": "linux" }, { "OS": "linux" }, { "Architecture": "arm64", "OS": "linux" }, { "Architecture": "386", "OS": "linux" }, { "Architecture": "ppc64le", "OS": "linux" }, { "Architecture": "s390x", "OS": "linux" } ] }, "ForceUpdate": 0, "Runtime": "container" }, "Mode": { #模式 "Replicated": { "Replicas": 3 } }, "UpdateConfig": { #更新配置 "Parallelism": 1, "FailureAction": "pause", "Monitor": 5000000000, "MaxFailureRatio": 0, "Order": "stop-first" }, "RollbackConfig": { #回滚配置 "Parallelism": 1, "FailureAction": "pause", "Monitor": 5000000000, "MaxFailureRatio": 0, "Order": "stop-first" }, "EndpointSpec": { #终端配置 "Mode": "vip", "Ports": [ { "Protocol": "tcp", "TargetPort": 80, "PublishedPort": 88, "PublishMode": "ingress" } ] } }, "Endpoint": { #终端,VIP模式,对外暴露88端口,ingress模式 "Spec": { "Mode": "vip", "Ports": [ { "Protocol": "tcp", "TargetPort": 80, "PublishedPort": 88, "PublishMode": "ingress" } ] }, "Ports": [ { "Protocol": "tcp", "TargetPort": 80, "PublishedPort": 88, "PublishMode": "ingress" } ], "VirtualIPs": [ #虚拟出了一个网段 { "NetworkID": "gd7sc5a8ke68zxzf9s7kz5mey", "Addr": "10.255.0.7/16" } ] } }] |
| ``` |
| 查看network |
| ``` |
[root@manager ~]# docker network ls``NETWORK ID NAME DRIVER SCOPE``13e5011b8fa7 bridge bridge local``1330304716df docker_gwbridge bridge local``95f6edd3f2ec host host local``gd7sc5a8ke68 ingress overlay swarm``57781759f937 none ``null local |
| ``` |
| 查看ingress网络 |
| ``` |
[root@manager ~]# docker network inspect gd7[ { "Name": "ingress", "Id": "gd7sc5a8ke68zxzf9s7kz5mey", "Created": "2019-07-18T17:17:43.808865817+08:00", "Scope": "swarm", "Driver": "overlay", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": null, "Config": [ { "Subnet": "10.255.0.0/16", "Gateway": "10.255.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": true, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "b4f5c5977de9248e4834f91f6a0bd54c438ad4c051cc9fef3537a726f2f64b49": { "Name": "web01.1.p9mhq9xrb35bwscrv23pgmimy", "EndpointID": "28b1e5fc0bef0e2b6ec812870c03962cf534e3f9f65646f507b6462da0a7eb58", "MacAddress": "02:42:0a:ff:00:0b", "IPv4Address": "10.255.0.11/16", "IPv6Address": "" }, "e4d6ace7511ac6ee24c6a3c3170749c8f08cbced6e86c2e4e1524e573db31418": { "Name": "web01.3.j1ev4hq7mjwyyy59e0l0g2qjy", "EndpointID": "6f9f9d2a61a3bb2424f7354dfd5a8e3e421734529fe626b4e263d2093078b285", "MacAddress": "02:42:0a:ff:00:0a", "IPv4Address": "10.255.0.10/16", "IPv6Address": "" }, "ingress-sbox": { "Name": "ingress-endpoint", "EndpointID": "2433360215c02637627f3f2cb8bada006b1837fa4aa551d1dffa6f2efe93987b", "MacAddress": "02:42:0a:ff:00:02", "IPv4Address": "10.255.0.2/16", "IPv6Address": "" } }, "Options": { "com.docker.network.driver.overlay.vxlanid_list": "4096" }, "Labels": {}, "Peers": [ { "Name": "5751b4f046eb", "IP": "10.11.97.71" }, { "Name": "e3f5cc62948d", "IP": "10.11.97.187" }, { "Name": "e9531b469fd9", "IP": "10.11.97.181" } ] }] |
| ``` |
| 可以看出ingress,模拟出了一个vxlan,驱动类型为overlay,网段为:10.255.0.0/16,网关为10.255.0.1,vxlan有4096个接口。 |
| # 九、swarm集群高可用架构实现 |
| ## HAPorxy实现高可用 |
![]() |
| ## Nginx反向代理实现高可用 |
![]() |
| # 十、Swarm配置文件管理 |
| 1、 生成一个基本的Nginx配置文件 |
| # cat site.conf |
| server { |
| listen 80; |
| server_name localhost; |
| location / { |
| root /usr/share/nginx/html; |
| index index.html index.htm; |
| } |
| } |
| 2、 将site.conf保存到docker配置中 |
| # docker config create site.conf site.conf |
| # docker config ls |
| ** |
| **3、 创建一个Nginx并应用这个配置 |
| # docker service create \ |
| --name nginx \ |
| --config source=site.conf,target=/etc/nginx/conf.d/site.conf \ |
| --publish 8080:80 \ |
| nginx |
珊瑚海
































浙公网安备 33010602011771号