docker-swarm集群模式

阅读本文前,请确保您至少有三台电物理机或者三台虚拟机,并且每个机器都部署了最新的Docker Engine。如若没有,请参考给物理机或者虚拟机部署Docker Engine

参考官方文档

节点的特性

每个容器化的机器(即安装了Docker Engine)可以变为一个swarm节点。

swarm节点分为两种,管理节点(manager node)和工作节点(worker node)。

管理节点的主要功能是:

  • 维护集群状态
  • 安排部署服务
  • 提供集群API服务

工作节点的主要功能是:

  • 运行容器

一个swarm可以是管理节点,也可以是工作节点,也可以两者都是。默认情况下,一个管理节点既有管理节点的职能,也有工作节点的职能,也就是两者都是。可以通过docker node update --availability drain NODE把节点置为Drain状态,这样管理节点就不会部署容器了。

在这里插入图片描述
一个swarm集群最少有一个管理节点,可以没有工作节点。(swarm单节点模式

一个swarm集群最好有大于1个的奇数个管理节点。为什么要大于一个呢?主要是为了容错,当其中一个管理节点挂掉之后,其他的管理节点能够正常运行提供服务(管理节点的职能,创建任务,维护状态等)。管理节点间通过Raft算法保证状态的一致性,工作节点的状态不参与Raft算法的计算过程。

三个管理节点可以容许一个管理节点挂掉,五个管理节点可以容许两个管理节点挂掉,n个管理节点可以容许(N-1)/2个管理节点挂掉。添加更多的管理节点不一定增加集群的可伸缩性和性能,但是减少管理节点却会降低可伸缩性和性能。

首先选择三个容器化机器的任何一个,把它变为管理节点:

//变为一个管理节点
docker swarm init --advertise-addr <MANAGER-IP>

获取以管理节点加入的token,因为需要三个管理节点,所以获取的是加入管理节点的token。

//获取以管理节点加入的token
docker swarm join-token manager
//也可以获取以工作节点加入的token,这里都是管理节点,暂时不用
docker swarm join-token worker

把其他两个机器以管理节点身份加入进来。

//加入swarm集群
docker swarm join --token *** --advertise-addr ***

至此,三个容器化机器都以管理节点身份加入到集群中,后续可以部署服务了。

swarm集群通过管理节点部署服务,只要配置好yml文件即可,语法可以参考docker-compose文件语法。定义服务时,可以指令下面的参数:

  • 服务的端口
  • 服务的网络
  • cpu和内存的限制和预留
  • 回滚策略
  • 同一服务的个数

服务、任务和容器的关系
在这里插入图片描述
一个服务可以有多个,分别由不同的任务去创建容器,每个容器运行相同服务的一个副本。

任务及其调度
在这里插入图片描述
首先客户端(一般指命令行)下发一个创建服务的指令给管理节点(通过Api),管理节点创建一个任务,并把这个任务分发给工作节点。工作节点确认任务后,执行任务并创建容器,之后工作节点不断给管理节点上报数据,告知管理节点服务的状态。

如果集群没有可用的节点部署服务,服务会一直处于pending状态直到有节点可用。可以给服务指定预留的内存,当预留的内存足够时,才执行部署任务。如果给服务预留太大的内存,那么服务会一直处于pending状态。某些情况下,不想yml文件的服务被部署,可以把服务的数量指定为0。

对于系统管理员来说,只需要指定服务最终的状态(比如数量,cpu和内存限制等)即可,无需直接操作任务本身。管理节点和工作节点配合会让服务达到最终给定的状态。

复制和全局服务
在这里插入图片描述
复制服务的个数由replicated参数决定,而全局服务是每个节点都会运行的服务,一般是日志或者杀毒服务。

假设现在已经在一台window10上安装了Docker Engine,并且使用docker-machine配合hyperv创建了三台虚拟机xxl、zzz、lll,并且都已管理节点加入集群中。

为了避免网速缓慢,选择一个管理节点安装Registry,把测试镜像放到里面
网速快可以直接上传到Docker Hub

//运行注册服务
docker service create --name registry --publish published=5000,target=5000 registry:2

编写测试服务
创建文件夹demo,并在其中加入文件:

  • app.py
from flask import Flask
from redis import Redis

app = Flask(__name__)
redis = Redis(host='redis', port=6379)

@app.route('/')
def hello():
    count = redis.incr('hits')
    return 'Hello World! I have been seen {} times.\n'.format(count)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8000, debug=True)
  • requirements.txt
flask
redis
  • Dockerfile
FROM python:alpine
ADD . /code
WORKDIR /code
RUN pip install -r requirements.txt
CMD ["python", "app.py"]
  • docker-compose.yml
version: '3'

services:
  web:
    image: 127.0.0.1:5000/demo	//试过用localhost和路由器ip地址都报错,只有127.0.0.1可以上传成功
    build: .
    ports:
      - "8000:8000"
  redis:
    image: redis:alpine

使用docker-compose构建服务并上传到本地的registry服务

//构建
docker-compose build --no-cache
//上传
docker-compose push
//查看上传的仓库
curl http://127.0.0.1:5000/v2/_catalog

部署集群的服务
集群的配置文件swarm.yml内容如下:

version: "3"
services:
  portainer:		//查看集群服务
    image: portainer/portainer
    ports:
      - "9000:9000"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      replicas: 1
      placement:
        constraints: [node.role == manager]
  web:
    image: 127.0.0.1:5000/demo
    ports:
      - "8000:8000"
    deploy:
      replicas: 3
  redis:
    image: redis:alpine
    deploy:
      replicas: 3

把swarm.yml文件复制到管理节点并部署:

//运行服务栈
docker stack deploy -c swarm.yml xxl

其他常用命令

//查看服务状态
docker service ps --no-trunc {serviceName}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值