1、 Swarm介绍
Swarm是Docker公司自研发的容器集群管理系统,Swarm在早期是作为一个独立服务存在,在Docker Engine v1.12中集成了Swarm的集群管理 和编排功能。可以通过初始化Swarm或加入现有Swarm来启用Docker引擎的Swarm模式。
Docker Engine CLI和API包括了管理Swarm节点命令,比如添加、删除节点,以及在Swarm中部署和编排服务。 也增加了服务栈(Stack)、服务(Service)、任务(Task)概念。
swarm架构.png
处理逻辑流程:
docker客户端发送服务请求---->API接收请求并创建对象--->创建对象服务任务--->给任务分配IP地址--->将任务分配到某个节点--->将任务下发到某个工作节点----> 创建容器
Swarm两个角色:
Manager:接收客户端服务定义,将任务发送到worker节点;维护集群期望状态和集群管理功能及Leader选举。默认情况下manager节点也会运行任务,也可以配置只做管理任务。利用RAFT协议保持Manager状态一致性。
Worker:接收并执行从管理节点分配的任务,并报告任务当前状态,以便管理节点维护每个服务期望状态。
创建一个3个副本nginx 的服务发送到manager节点,然后manager节点将三个副本分配到可用到节点上,nginx.1就是第一个任务。
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⃣️. 滚动更新
升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先前版本。
Manager | Worker |
---|---|
Manager | 10.40.6.167 |
Worker01 | 10.40.6.166 |
Worker02 | 10.40.6.165 |
在三个节点防火墙对网段开放:iptables -I INPUT -s 10.40.6.0/23 -j ACCEPT
初始化swarm:docker swarm init --help
2、集群部署
使用Swarm前提:
1⃣️.Docker版本1.12+
2⃣️.集群节点之间保证TCP 2377(集群管理)、TCP/UDP 7946(容器网络发现)和UDP 4789(Overlay网络)端口通信 节点规划:
操作系统:CentOS7.4_x64
管理节点初始化Swarm:
# docker swarm init --advertise-addr 10.40.6.167
Swarm initialized: current node (y7kvs1pl3ydu990k0lv2j846m) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-2ya3gjj6z8hdz8kraebib9v194t4fqjqyu3imjtcnax9awk7dk-7gmmejuor1vodojqwdb5y8r13 10.40.6.167:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
工作节点加入Swarm:docker swarm join --token SWMTKN-1-XXX 10.40.6.167:2377
# docker swarm join --token SWMTKN-1-2ya3gjj6z8hdz8kraebib9v194t4fqjqyu3imjtcnax9awk7dk-7gmmejuor1vodojqwdb5y8r13 10.40.6.167:2377
This node joined a swarm as a worker.
###注意主机时间保持一致,免得出现证书过期问题:
Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid
在管理节点上查看节点:
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
y7kvs1pl3ydu990k0lv2j846m * docker-manager01 Ready Active Leader 18.09.6
gv4r5k331flafgeedre6btwkh docker-work01 Ready Active 18.09.6
lci41ilcev8jyjit4pbtslufv docker-work02 Ready Active 18.09.6
3、 节点管理
docker node COMMAND 管理Swarm节点:
# docker node --help
Usage: docker node COMMAND
Manage Swarm nodes
Commands:
demote Demote one or more nodes from manager in the swarm
inspect Display detailed information on one or more nodes
ls List nodes in the swarm
promote Promote one or more nodes to manager in the swarm
ps List tasks running on one or more nodes, defaults to current node
rm Remove one or more nodes from the swarm
update Update a node
Run 'docker node COMMAND --help' for more information on a command.
4、 服务管理
docker service --help
配置docker镜像源文件:/etc/docker/daemon.json
### 创建服务
# docker service create --replicas 1 --name hello busybox ping www.baidu.com
### 显示服务详细信息
# docker service inspect --pretty hello
### 易于阅读显示
# docker service inspect hello # json格式返回
### 扩展服务实例数
# docker service scale hello=3
### 查看服务任务
# docker service ls
# docker service ps hello
# docker service ps -f 'desired-state=running' hello
### 滚动更新服务
# docker service create --replicas 3 --name redis --update-delay 10s redis:3.0.6
# docker service update --image redis:3.0.7 redis
### 创建服务时设定更新策略
# docker service create \
--name my_web \
--replicas 10 \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action continue \
nginx:1.12
### 创建服务时设定回滚策略
# docker service create \
--name my_web \
--replicas 10 \
--rollback-parallelism 2 \
--rollback-monitor 20s \
--rollback-max-failure-ratio .2 \
nginx:1.12
### 服务更新
# docker service update --image nginx:1.13 my_web
### 手动回滚
# docker service update --rollback my_web
5、管理应用程序数据
(1) Volume
创建数据卷:
# docker service create \
--mount type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH> \
--name myservice \
<IMAGE>
查看数据卷详细信息:
# docker volume inspect <VOLUME-NAME>
(2) Bind Mounts
读写挂载:
# docker service create \
--mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH> \
--name myservice \
<IMAGE>
只读挂载:
# docker service create \
--mount type=bind,src=<HOST-PATH>,dst=<CONTAINER-PATH>,ro \
--name myservice \
<IMAGE>
NFS数据持久存储:
###安装一个NFS服务:
# yum install nfs-utils -y
# cat # cat /etc/exports
/nfs_data/ 10.40.6.0/23(rw,sync,no_root_squash,no_all_squash)
# mkdir /nfs_data
###每个结果都安装一下客户端:
# yum install nfs-utils -y
### 格式:
# docker service create --mount \
'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,\
volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,\
"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"' \
--name myservice <IMAGE>
### 实例:
# # docker service create --mount 'type=volume,src=nfs-vol,dst=/usr/share/nginx/html,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/nfs_data,"volume-opt=o=addr=10.4.4.151,vers=4,soft,timeo=180,bg,tcp,rw"' --name nfs-nginx 10.40.6.165/library/nginx:v1
# docker service ps nfs-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
j81r9oh3xgrs nfs-nginx.1 10.40.6.165/library/nginx:v1 docker-work01 Running Running 30 seconds ago
# df -h ### nfs共享目录挂载到节点上
.....
:/nfs_data 76G 8.7G 67G 12% /var/lib/docker/volumes/nfs-vol/_data
# docker volume ls
DRIVER VOLUME NAME
local nfs-vol
# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8774783e0cac 10.40.6.165/library/nginx:v1 "nginx -g 'daemon of…" About a minute ago Up About a minute 80/tcp nfs-nginx.1.j81r9oh3xgrsyudujxzfss0kw
# docker exec -it 8774783e0cac bash
[root@8774783e0cac nginx]# ls /usr/share/nginx/html/
aaa
### 增加到三个实例
# docker service scale nfs-nginx=3
nfs-nginx scaled to 3
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
# docker service ps nfs-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
j81r9oh3xgrs nfs-nginx.1 10.40.6.165/library/nginx:v1 docker-work01 Running Running 4 minutes ago
matq9qdwx12r nfs-nginx.2 10.40.6.165/library/nginx:v1 docker-work02 Running Running 26 seconds ago
tklrm734ukkm nfs-nginx.3 10.40.6.165/library/nginx:v1 docker-manager01 Running Running 26 seconds ago
###缩容到2个实例
# docker service scale nfs-nginx=2
nfs-nginx scaled to 2
overall progress: 2 out of 2 tasks
1/2: running [==================================================>]
2/2: running [==================================================>]
verify: Service converged
# docker service ps nfs-nginx
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
j81r9oh3xgrs nfs-nginx.1 10.40.6.165/library/nginx:v1 docker-work01 Running Running 7 minutes ago
matq9qdwx12r nfs-nginx.2 10.40.6.165/library/nginx:v1 docker-work02 Running Running 3 minutes ago
注意缩容后,去掉实例的节点的系统数据挂载随之卸载,节点的docker数据卷volume不会除掉,但节点数据卷volume的数据会移除掉
6、集群服务发布
Docker Swarm,主要包含以下概念:
- Swarm
- Node
- Stack
- Service
- Task
- Load balancing
Swarm本身就是“群”的意思,人群、蜂群。 这里就是指计算机集群(cluster)在用Docker连接后的状态。 docker swarm
命令可以创建、加入、离开一个集群。
Node就是计算机节点,也可以认为是一个Docker节点。 Node分为两类:Manager和Worker。 一个Swarm至少要有一个Manager,部分管理命令只有在Manager上才能使用。 两类Node都可以运行Service,但只有Manager上才能执行运行命令。 比如,在Manager才能使用docker node
命令可以查看、配置、删除Node。
Stack是一组Service,和docker-compose类似。 默认情况下,一个Stack共用一个Network,相互可访问,与其它Stack网络隔绝。 这个概念只是为了编排的方便。 docker stack
命令可以方便地操作一个Stack,而不用一个一个地操作Service。
Service是一类容器。 对用户来说,Service就是与Swarm交互的最核心内容。 Service有两种运行模式,一是replicated
,指定一个Service运行容器的数量; 二是global
,在所有符合运行条件的Node上,都运行一个这类容器。docker service
命令可以操作Swarm中的Service。
Task就是指运行一个容器的任务,是Swarm执行命令的最小单元。 要成功运行一个Service,需要执行一个或多个Task(取决于一个Service的容器数量),确保每一个容器都顺利启动。 通常用户操作的是Service,而非Task。
Load balancing即负载均衡,也包含反向代理。 Swarm使用的是Ingress形式的负载均衡,即访问每个节点的某个Published端口,都可自动代理到真正的服务。 大致原理如下图所示。
Load balancing.pngdocker_task_service.png
docker service create --name my_web -p 88:80 --replicas 3 nginx
# docker service ps my_web
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
kva9nlhj1xbz my_web.1 nginx:latest docker-manager01 Running Running 45 minutes ago
eni1a9jquvgh my_web.2 nginx:latest docker-work01 Running Running about an hour ago
xonfhfxxizfx my_web.3 nginx:latest docker-work02 Running Running 45 minutes ago
# docker service logs my_web -f ## 查看访问日志
# docker service inspect my_web ## 查看服务的详细信息
...
"Ports": [
{
"Protocol": "tcp", ##默认启动的是TCP协议,如果要指定UDP,则 -p 88:80/udp
"TargetPort": 80,
"PublishedPort": 88,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "m4c12supk4prtsb46osiep2rz",
"Addr": "10.255.0.13/16" ### VIP地址
}
]
}
...
# docker network ls
NETWORK ID NAME DRIVER SCOPE
....
m4c12supk4pr ingress overlay swarm
...
# docker network inspect ingress ##查看详细的网络服务的网络
# iptables-save |grep 88 ##其实是通过iptables 做目标地址转发实现
-A DOCKER-INGRESS -p tcp -m tcp --dport 88 -j DNAT --to-destination 172.19.0.2:88
-A DOCKER-INGRESS -p tcp -m tcp --dport 88 -j ACCEPT
-A DOCKER-INGRESS -p tcp -m state --state RELATED,ESTABLISHED -m tcp --sport 88 -j ACCEPT
在三个节点前面加一个haproxy或nginx对暴露的端口做负载均衡:
ingress_network.png
7、服务发现与负载均衡
服务发现与负载均衡.pngswarm集群内置类似分布式存储,记录一下集群的状态信息和创建服务信息,比如创建的副本IP、对外暴露的访问端口,访问到具体哪些节点。
服务发现:Swarm模式内置DNS组件,自动为每个服务分配DNS记录,然后服务的DNS名称在集群内的服务直接分发请求。
负载均衡:在Swarm集群中创建服务时,Ingress网络会自动为其分配一个虚拟IP(VIP),在DNS解析时返回VIP,流入该VIP的流量将自动发送(IPVS)该服务的所以健康任务(容器)。
# docker network create --driver overlay my-web
s9blzb8nvymwpqxfk4c4sp7qw
# docker network ls
NETWORK ID NAME DRIVER SCOPE
76158eb5c5a9 bridge bridge local
12c813b82062 docker_gwbridge bridge local
35e935d201b0 host host local
m4c12supk4pr ingress overlay swarm
s9blzb8nvymw my-web overlay swarm
5c110c0bd687 none null local
将多个服务加入同一个自定义网络,服务之间通信可以通过服务名通信
# docker service create --replicas 3 --network my-web --name web01 nginx
# docker service create --replicas 3 --network my-web --name redis01 redis
# docker service create --replicas 3 --network my-web --name bs2 busybox ping www.baidu.com
# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ab73f288a741 busybox:latest "ping www.baidu.com" 2 minutes ago Up 2 minutes bs2.2.r4bv8tf8sgl6z3fzwek3e2rrn
# docker exec -it ab73f288a741 sh
/ # ping web01 ###web01服务的VIP为 10.0.0.2
PING web01 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.220 ms
/ # ping redis01 ###redis01服务的VIP为 10.0.0.2
PING redis01 (10.0.0.9): 56 data bytes
64 bytes from 10.0.0.9: seq=0 ttl=64 time=0.197 ms
负责均衡的模式:VIP和DNS
### 默认通过VIP模式,得经过负载均衡VIP再转发:
# docker service inspect web01
...
"EndpointSpec": {
"Mode": "vip" ##默认通过VIP模式,得经过负载均衡VIP再转发
}
...
### 默认通过内部DNS模式将请求转发:
# docker service create --replicas 3 --network my-web --endpoint-mode dnsrr --name web02 nginx
# docker service inspect web02
...
"EndpointSpec": {
"Mode": "dnsrr"
}
...
/ # nslookup web02
Server: 127.0.0.11
Address: 127.0.0.11:53
Non-authoritative answer:
Name: web02
Address: 10.0.0.17 ###容器的IP
Name: web02
Address: 10.0.0.18 ###容器的IP
Name: web02
Address: 10.0.0.19 ###容器的IP
# docker inspect rwji4rwdejy4(容器ID) 可以看到对应容器的IP
常用命令:
# 进容器查看DNS记录
nslookup hello
# 获取虚拟IP
docker service inspect -f '{{json .Endpoint.VirtualIPs}}' hello
# 设置DNS轮询模式
docker service create \
--replicas 3 \
--name my-web \
--network my-network \
--endpoint-mode dnsrr \
nginx
8、高可用架构
swarm集群即使managers节点挂了也不影响集群其他节点的容器的业务访问(去中心化设计),Internal distributed state store 为swarm manager 内置分布式存储,利用RAFT协助保持manager节点的数据一致性,manager主要是维护集群的状态;创建请求调度服务;提供swarm API。
高可用架构.pngmanager_nodes.png
#将work节点升级为manager节点:
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
y7kvs1pl3ydu990k0lv2j846m * docker-manager01 Ready Active Leader 18.09.6
gv4r5k331flafgeedre6btwkh docker-work01 Ready Active 18.09.6
lci41ilcev8jyjit4pbtslufv docker-work02 Ready Active 18.09.6
# docker node promote docker-work01
# docker node promote docker-work02
# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
y7kvs1pl3ydu990k0lv2j846m * docker-manager01 Ready Active Leader 18.09.6
gv4r5k331flafgeedre6btwkh docker-work01 Ready Active Reachable 18.09.6
lci41ilcev8jyjit4pbtslufv docker-work02 Ready Active Reachable 18.09.6
9、配置文件管理
docker config --help
(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配置中,data是做加密存储的
# docker config create nginx-v1.conf site.conf
# docker config ls
ID NAME CREATED UPDATED
p9572lxwcb0hffh6pz5rlulrs nginx-v1.conf 22 seconds ago 22 seconds ago
# docker config inspect ID或者NAME
# docker config inspect nginx-v1.conf
[
{
"ID": "p9572lxwcb0hffh6pz5rlulrs",
"Version": {
"Index": 1278
},
"CreatedAt": "2019-05-20T12:08:51.54970674Z",
"UpdatedAt": "2019-05-20T12:08:51.54970674Z",
"Spec": {
"Name": "nginx-v1.conf",
"Labels": {},
"Data": "c2VydmVyIHsKICAgIGxpc3RlbiA4MDsKICAgIHNlcnZlcl9uYW1lIGxvY2FsaG9zdDsKICAgIGxvY2F0aW9uIC8gewogICAgICAgIHJvb3QgL3Vzci9zaGFyZS9uZ2lueC9odG1sOwogICAgICAgIGluZGV4IGluZGV4Lmh0bWwgaW5kZXguaHRtOwogICAgfQp9Cg=="
}
}
]
(3)、创建一个Nginx并应用这个配置
# docker service create \
--name nginx_test \
--config source=nginx-v1.conf,target=/etc/nginx/conf.d/nginx-v1.conf \
--publish 8080:80 \
nginx
网友评论