Contents
为什么需要使用容器的编排?
- 怎么去管理多个容器?
- 怎么能方便的横向扩展?
- 如果容器down了,怎么能够自动的恢复业务?
- 如何去更新容器而不影响业务?
- 如何去监控追踪这些个容器?
- 怎么去调度容器的创建?
- 怎么包保护数据的隐私?
Swarm的历史
- 自从2017的docker,v1.12开始,集群管理和编排功能就已经集成进Docker Engine中。
- 在这个版本之前的Swarm是一个单独提供的集群软件,而且依赖外部数据。
- 对比Kubernetes,使用Swarm创建集群非常的简单,不需要安装额外的任何软件原生态,也不需要任何的配置。
什么是Swarm?
Docker Swarm管理的是docker Host集群(Clustering)
服务器集群是由于网络上相互连接的服务器组成,它们一起协作工作。
一堆的服务和服务器的集群有什么区别?
- 集群可以像单台系统那样工作,同时也可以提供高可用、负载均衡和并行处理。而Swarm就是一个集群。
Swarm Mode
- docker运行在一台宿主机器上运用Swarm和单独的容器,两者互相不影响。
Swarm就是运行Docker Enginer的多个主机组合成为的集群,
当没有启动Swarm的时候我们使用执行的是docker容器的命令,
当我们启动Swarm创建一个新的mode或加入一个新存在Swarm。
docker就具有了编排服务的能力。
- 当Swarm遇见Swarm Mode
老的Docker Swarm:使用独立的外部KV存储(比如Consul、etcd、zookeeper),搭建独立运行的Docker主机集群,用户像操作单台Docker 机器一样操作整个集群,Docker Swarm把多台Docker主机当做一台Docker主机来管理。在docker 1.12版之前,只有搭建Docker Swarm集群,没有Swarm mode之说,结合machine和compose来操作所有Docker机器。这样的集群也是可以正常运行的,没有任何问题。
新的Swarm mode:是在docker 1.12版本中集成到 Docker 引擎中的,引入服务的概念,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得Docker 原生的Swarm mode集群具备与Mesos、Kubernetes叫板的实力。
Swarm Node
在Swarm集群中每一个Docker Enginer都是一个Node节点
- node类型为:manager(控制节点)、worker(工作节点)
-
为了方便Swarm中部署应用,我们会在Manager的node节点上编写部署的命令,由于控制节点分发给work
Swarm Service
- Service的存在就是定义了work_node上需要执行的任务。
- Swarm最为主要的目的就是保证我们Service一直处于我们期望的状态。
Swarm的特点
-
1.Docker Engine集成集群管理
使用Docker Engine CLI创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务
- 2.去中心化设计
Swarm角色分配为Manager和Worker借点,Manager节点故障不影响应用的使用
- 3.扩容缩容
可以声明每个服务器运行的容器数量,通过添加或者删除容器自动调整期望的状态
- 4.期望状态协调
Swarm Manager节点不断监控集群的状态,并且调整当前的状态与期望状态之间的差异,例如,设置一个服务运行10个副本容器,如果两个服务器的节点崩溃了,Manager将会创建两个新的副本代替崩溃的副本,并且将新的副本分配到可用的work节点上。
- 5.多主机网络
可以为服务指定Overlay网络,当初始化或者更新应用程序的时候,SWarm manager会自动的为Overlay网络上的容器分配IP地址
- 6.服务发现
Swarm manager节点为集群中的每一个服务分配唯一的DNS记录和负载均衡VIP,可以通过Swarm内置的DNS服务器查询集群中每一个运行的容器
- 7.负载均衡
实现服务副本负载均衡,提供入口访问,也可以将服务入口暴露给外部负载均衡机器再一次的负载均衡
- 8.安全传输
Swarm中的每一个节点使用TLS相互验证和加密,确保安全的其他节点通信
- 9.滚动更新
升级时,逐步的将应用服务更新到节点,如果出现问题,可以将任务回滚到先前的版本。
Swarm的架构
DNS服务发现
Routing Mesh的两种体现
- Internal-Container和Container之间的访问通过overlay网络(VIP虚拟IP)
- 以负载均衡的模式把请求推送到各个节点容器
1.不同的工作组在同一个overlay中如何通信
2.客户端的请求是如何一步步到达容器处理的
- Ingress-如果服务有绑定接口,则此服务可以用过任意swarm节点的相应接口访问
- 外部访问的负载均衡
-
服务端口被暴露到各个节点swarm节点
-
内部通过IPVS进行负载均衡
部署Swarm
使用swarm的前提
- Docker版本大于1.12
- 集群节点之间保证TCP:2377、TCP/UDP 7946、UDP 4789端口通信
节点的规划
节点名称 | 操作系统 | IP地址 | 服务器 | 规格 |
---|---|---|---|---|
Swarm_manager | Centos7 | 10.104.253.33 | 腾讯云 | 2G2G |
Swarm_node1 | Centos7 | 10.186.33.161 | 腾讯云 | 2G2G |
Swarm_node2 | Centos7 | 10.104.54.87 | 腾讯云 | 2G2G |
开始部署
swarm相关命令 | 相关解释 |
---|---|
docker swarm init | 初始化集群 |
docker swarm join-token worker | 查看工作节点的 token |
docker swarm join-token manager | 查看管理节点的 token |
docker swarm join | 加入集群中 |
创建控制主机
[root@VM_253_33_centos ~]# docker swarm init --advertise-addr 10.104.253.33 #指定要创建的Swarm manager控制节点
Swarm initialized: current node (qishvxpcc7iibe2q04t1w9jms) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-310j2qc2gwbp84n7kuaxu3mpdy9p1xp38xbq5nil2br9rk3i5l-cv40bmktgys4mtqif51fbg06m \
10.104.253.33:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
加入节点
docker swarm join \
--token SWMTKN-1-310j2qc2gwbp84n7kuaxu3mpdy9p1xp38xbq5nil2br9rk3i5l-cv40bmktgys4mtqif51fbg06m \ #执行语句加入集群
This node joined a swarm as a worker.
查看集群
docker node ls
查看一个节点的详细信息
docker node inspect --pretty VM_253_33_centos
容器服务的基础操作
swarm server相关命令 | 相关解释 |
---|---|
docker service create | 部署服务 |
docker service inspect | 查看服务详情 |
docker service logs | 产看某个服务日志 |
docker service ls | 查看所有服务详情 |
docker service rm | 删除某个服务(-f强制删除) |
docker service scale | 设置某个服务个数 |
docker service update | 更新某个服务 |
1.创建一个服务
[root@VM_253_33_centos ~]# docker service create --replicas 1 --name hellow busybox --relicas创建一个副本数指定数量
2.查看当前运行中的服务
[root@VM_253_33_centos ~]# docker service ls
ID NAME MODE REPLICAS IMAGE
rjqr9qpt3ajv hellow replicated 0/1 busybox:latest
3.查看服务下运行的容器
[root@VM_253_33_centos ~]# docker service ps hellow #启动镜像处于失败的状态中,manager会自动查看你启动的状态,如果不是期望的会自动再次启动
4.让容器真正的运行起来
1.让容器执行任务
[root@VM_253_33_centos ~]# docker service update --args "ping www.baidu.com" hellow #指定容器的任务
2.过滤查看我们运行的容器
docker service ps -f "desired-state=Ready" hellow #-f指定查看的容器状态
5.对容器进行扩容
docker service scale hellow=3 #scale指定扩容的数量
docker service ps -f "desired-state=Ready" hellow #过滤正在运行中的全部容器,三个容器在不同的节点启动了
6.滚动更新redis
解释:对我们的容器进行平滑的升级,例如的Redis2—>redis3,这样的一个过程。
docker service create \
--replicas 3 \
--name redis \
--update-delay 10s \ #更的间隔10S
redis:3.0.6
7.开始平滑更新
docker service update --image redis:3.0.7 redis #更新并且指定镜像的版本
docker service ps -f "desired-state=Running" redis #等待30~40秒左右
更新的方式为:停止当前的第一个副本更新当第一个副本State为running时候继续更新,下一个副本。否则停止更新
容器服务的管理
1.创建一个服务并且设置更新策略
[root@VM_253_33_centos ~]# docker service create \
> --name my_web \
> --replicas 10 \
> --update-delay 10s \
> --update-parallelism 2 \ #默认最大的并行数量,就是可以同时执行的任务
> --update-failure-action continue \ #如果更新失败,则继续更新
> nginx:1.12
成功的运行
2.创建服务的时候设定回滚的策略
[root@VM_253_33_centos ~]# docker service create \
> --name my_web \
> --replicas 10 \
> --rollback-parallelism 2 \
> --rollback-monitor 20s \
> --rollback-max-failure-ratio .2 \ #故障率小于20%就容忍不回滚
nginx:1.12
3.服务更新
docker service update --image nginx1.13 my_web
4.如果执行不成功则可以手动回滚
docker service update --rollback --update-delay 0s my_web
容器服务的水平扩展
创建一个简单的容器
docker service create --name demo busybox sh -c "while true;do sleep 3600;done" #创建并让他保持后台执行
使用scale水平扩容
创建demo
docker service scale demo=3 在一个副本中创建三个容器
swarm为我们提供一个高可用,当我们在一个副本中的某些容器宕机后,会自动的在其他的节点上生成新的容器。
例如
[root@swarm-node1 ~]# docker stop c3230b47eb69 #在主节点1停止一个容器
Swarm使用原生的Overlay Network
1.创建自己的Overlay网络
docker network create --driver overlay my-network
2.创建新的服务并且运行到Overlay网络
[root@swarm-manager ~]# docker service create \
> --replicas 3 \ #容器数量3个
> --network my_network \
> --name my-web \
> nginx
每一个节点上都平均分配一个
3.将现有的网络连接到overlay网络
docker service update --network-add my-network my-web
4.将现有的网络连接删除overlay网络
docker service update --network-rm my-network my-web
Swarm的数据持久化
1.创建数据卷
Swarm部署wordprss
创建一个桥接网卡
docker network create -d overlay demo
创建一个Mysql
[root@swarm-manager ~]# docker service create \
> --name mysql \
> --env MYSQL_ROOT_PASSWORD=root \
> --env MYSQL_ROOT_DATABASE=wordpress \
> --network demo \
> --mount type=volume,source=mysql-data,destination=/var/lib/mysql \
> mysql:5.7
创建一个wordpress
docker service create \
> --name wordpress \
> -p 80:80 \
> --env WORDPRESS_DB_PASSWORD=root \
> --env WORDPRESS_DB_HOST=mysql \
> --network demo wordpress