参考
https://docs.docker.com/engine/reference/commandline/stack/
https://blog.csdn.net/footless_bird/article/details/129121931
10.0.0.11 node1
10.0.0.12 node2
10.0.0.13 node3
[root@node1 ~]# docker swarm init --advertise-addr 10.0.0.11 --default-addr-pool 192.168.0.0/16
Swarm initialized: current node (nud5xyarpgl448232hhb9g1op) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-49eyeavnqvftnwfqw6tfenupqfhfkaixmymcyyx89yudg0mu5h-e8wo8cgagkowsd66wvx92ne4u 10.0.0.11:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker swarm join --token SWMTKN-1-49eyeavnqvftnwfqw6tfenupqfhfkaixmymcyyx89yudg0mu5h-e8wo8cgagkowsd66wvx92ne4u 10.0.0.11:2377
在10.0.0.12这台主机上执行上述命令,将其加入到集群中
#获取一个manager加入集群的token ,这个命令要在之前的那个manager 10.0.0.11 上执行
docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-49eyeavnqvftnwfqw6tfenupqfhfkaixmymcyyx89yudg0mu5h-0rt069u4a46a06ml3i6qmrgyq 10.0.0.11:2377
Leader:该节点是集群管理和编排决策的主要管理器节点
Reachable:该节点是管理者节点正在参与Raft选举。如果Leader节点不可用,则该节点有资格被选为新领导者
Unavailable:该节点属于不能与其他manager通信的manager。如果manager节点不可用,可以将它加入群集,或者将工作器节点升级为管理器
Active:调度程序可以将任务分配给当前节点
Pause:调度程序不会将新任务分配给当前节点,但现有任务仍在运行
Drain:调度程序不会向当前节点分配新任务。调度程序关闭所有现有任务并在可用节点上重新调度这些任务
#将worker节点提升为manager节点,在manager节点执行如下命令:
docker node promote 节点名称|节点ID
docker node promote 0pn3zwwa0rchs805y18rimtru
#将manager节点降低为worker节点,在manager节点执行如下命令:
docker node demote 节点名称|节点ID
docker node demote qgrkswhlsv0run1ukcxmn9oj1
#在要脱离集群的节点上使用以下命令, 主动离开集群,让节点处于down状态,才能删除
docker swarm leave
#指向完后,等一会在manager节点使用命令:docker node ls 就会发现该节点已经脱离集群管理
删除脱离集群的节点
#节点脱离集群后,才能删除节点,删除节点使用如下命令
docker node rm 节点名称|节点ID
docker node rm qgrkswhlsv0run1ukcxmn9oj1
docker swarm init 初始化一个 swarm 群集
docker swarm join 加入群集作为节点或管理器
docker swarm join-token 管理用于加入群集的令牌
docker swarm leave 离开 swarm 群集
docker swarm unlock 解锁 swarm 群集
docker swarm unlock-key 管理解锁钥匙
docker swarm update 更新 swarm 群集
管理节点,解散集群
docker swarm leave --force
docker node demote 从 swarm 群集管理器中降级一个或多个节点
docker node promote 将一个或多个节点推入到群集管理器中(也就是升级节点)
docker node inspect 显示一个或多个节点的详细信息
docker node ls 列出 swarm 群集中的节点
docker node ps 列出在一个或多个节点上运行的任务,默认为当前节点
docker node rm 从 swarm 群集删除一个或多个节点
docker node update 更新一个节点
docker-swarm的图形界面需要安装在manager节点上,不然无法操作节点
docker pull dockersamples/visualizer:latest
docker run -itd --name visualizer -p 8099:8080 -e HOST=10.0.0.11 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer:latest
访问图形界面
http://10.0.0.11:8099/
在node节点执行,离开集群
docker swarm leave
在master节点删除状态为down的节点
docker node rm 节点id [节点id] ...
管理节点,解散集群
docker swarm leave --force
在manager节点中创建overlay网络
docker network create -d overlay nginx-net
在集群中创建3个Nginx服务,在manager节点中执行,使用docker service create命令
# --network nginx-net 使用刚刚创建的网络
# replicas 3 代表 3个副本服务
docker service create --name nginx --network nginx-net -p 80:80 --replicas 3 nginx:1.18.0-alpine
查看服务
docker service ls
docker node update --availability drain 节点Id|名称
docker node update --availability drain nud5xyarpgl448232hhb9g1op
docker service scale nginx=5
docker service update --image nginx:1.19.3-alpine nginx
#将8090 也映射到容器的80端口
docker service update --publish-add 8090:80 nginx
删除service
docker service rm nginx
删除之前创建的nginx-net
docker network rm nginx-net
docker service create 创建服务
docker service inspect 显示一个或多个服务的详细信息
docker service logs 获取服务的日志
docker service ls 列出服务
docker service ps service名称 查看服务中的容器
docker service rm 删除一个或多个服务
docker service scale 设置服务的实例数量
docker service update 更新服务
docker service rollback 恢复服务至update之前的配置
Stack是一组Service,和docker-compose类似,它也可以通过yml的将一组service放在一起操作,docker stack命令可以方便地操作一个Stack,而不用一个个地操作Service
默认情况下,一个Stack共用一个Network,相互可访问,与其它Stack网络隔绝
docker-stack.yml
version: '3'
services:
edwin-nginx:
image: nginx:1.18.0-alpine
container_name: edwin-nginx
networks:
- edwin-net
restart: always
ports:
- 80:80
deploy:
mode: replicated
replicas: 6 # replicas模式, 副本数目为1
endpoint_mode: vip
labels:
description: "This redis service label"
resources:
limits:
cpus: '0.50'
memory: 50M
reservations:
cpus: '0.25'
memory: 20M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
placement:
constraints:
- "node.role==worker" # 部署位置,只在工作节点部署
- "engine.labels.operatingsystem==ubuntu 18.04"
preferences:
- spread: node.labels.zone
update_config:
parallelism: 2
delay: 10s
order: stop-first
networks:
edwin-net:
driver: overlay
cat docker-stack.yml |docker stack config --compose-file -
version: "3.10"
services:
edwin-nginx:
container_name: edwin-nginx
deploy:
replicas: 3
image: nginx:1.18.0-alpine
networks:
edwin-net: null
ports:
- mode: ingress
target: 80
published: 80
protocol: tcp
restart: always
networks:
edwin-net:
driver: overlay
在manager节点中创建docker-stack.yml文件
#nginx-stack 是stack的名字
docker stack deploy nginx-stack --compose-file=docker-stack.yml
#或者是
docker stack deploy nginx-stack -c docker-stack.yml
查看stack服务
docker stack services nginx-stack
查看运行的节点
# 查看service的服务名为:nginx-stack_edwin-nginx
docker service ls
#查看3个nginx-stack容器分别运行在哪个节点中
docker service ps nginx-stack_edwin-nginx
删除stack服务
docker stack rm nginx-stack
docker stack deploy -c yaml文件 stack名称 部署新的stack或更新现有stack
docker stack ls 列出现有stack
docker stack ps stack名称 列出stack中的任务
docker stack rm stack名称 删除一个或多个stack
docker stack services 列出stack中的服务
docker config配置文件
vim nginx.conf
user nginx;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/nginx/error.log error;
pid /var/run/nginx.pid;
events {
use epoll;
worker_connections 65535;
accept_mutex off;
multi_accept off;
}
http {
include mime.types;
default_type application/octet-stream;
log_format json '{ "@timestamp": "$time_iso8601",'
'"hostname": "$hostname",'
'"http_host": "$http_host",'
'"remote_user": "$remote_user",'
'"request": "$request",'
'"request_uri": "$request_uri",'
'"request_method": "$request_method",'
'"request_body": "$request_body",'
'"size": "$body_bytes_sent",'
'"http_user_agent": "$http_user_agent",'
'"referer": "$http_referer",'
'"cookie": "$cookie_name",'
'"requesttime": "$request_time",'
'"upstreamtime": "$upstream_response_time",'
'"upstreamhost": "$upstream_addr",'
'"clientip": "$http_x_forwarded_for",'
'"scheme":"$scheme",'
'"server_protocol":"$server_protocol",'
'"status": "$status"}';
open_file_cache max=65535 inactive=20s;
server_tokens off;
sendfile on;
keepalive_timeout 65;
gzip on;
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80;
server_name frontend;
client_max_body_size 30720m;
charset utf-8;
access_log /var/log/nginx/access_json.log json;
proxy_connect_timeout 1800;
proxy_read_timeout 1800;
proxy_send_timeout 1800;
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS';
add_header Access-Control-Allow-Headers 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Authorization';
location / {
root /data/frontend/;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
location /apis {
rewrite ^.+apis/?(.*)$ /$1 break;
include uwsgi_params;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_pass http://nginx-api;
}
}
}
创建config
docker config create nginx-conf nginx.conf
查看config
docker config ls
nginx部署文件
vim nginx.yaml
version: '3.8'
services:
nginx:
image: nginx
configs:
- source: nginx-conf
target: /etc/nginx/nginx.conf
healthcheck:
test: netstat -lnpt | grep '80'
interval: 30s
timeout: 10s
retries: 3
networks:
- pro-net
ports:
- target: 80
published: 80
protocol: tcp
mode: host
deploy:
mode: replicated
replicas: 2
placement:
constraints: [node.role == manager]
resources:
limits:
cpus: '1'
memory: 2G
reservations:
cpus: '0.25'
memory: 512M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
update_config:
parallelism: 1
delay: 10s
configs:
nginx-conf:
external: true
networks:
pro-net:
external: true
部署
docker stack deploy -c yaml文件 stack名称
docker stack deploy -c nginx.yaml nginx
查看stack
#查看stack
docker stack ls
#查看stack中的任务
docker stack ps stack名称
#查看stack中的service
docker stack services stack名称
查看service
#查看service列表
docker service ls
#查看一个service的容器在哪个节点
docker service ps service名称
Docker stack没有构建指令,无法使用stack命令构建新镜像,需要镜像是预先准备镜像。 docker-compose可以直接构建镜像,所以docker-compose更适合于开发场景;
Docker Compose是Python写的,需要安装,Docker Stack是swarm mode的一部分,包含在Docker引擎中
Docker stack 不支持version版本为3以下的yml
Docker stack 的功能基本上包含了docker compose
Task是 Swarm 集群中的最小的调度单位,任务包含一个Docker容器和在容器内运行的命令,如果某一个任务奔溃,那么协调器将创建一个新的副本任务,该任务将生成一个新的容器。
Task调度主要分为Manager节点的任务分配和Worker节点的任务执行两部分
通过 Docker Engine Client 在manage节点使用命令 docker service create 提交 Service 定义
Manager节点根据定义创建相应的 Task,并分配IP地址
将Task分发到对应的节点上
节点进行相应的初始化使得它可以执行Task
连接Manager节点的分配器检查该Task相关定义的信息
验证通过以后在 Worker 节点上执行Task
Task 的执行是一种单向机制,它会按顺序的依次经历 assigned, prepared 和 running 等执行状态,如果Task执行失败了,Manager的编排器会直接将该 Task 以及它的 Container 给删除掉,然后在其它节点上另外创建并执行该 Task