浅谈Docker swarm+HAProxy/Nginx

就不废话了,直接画出系统逻辑架构图:docker-arch

这里有些问题简单交待一下:

  1. HAProxy/Nginx作为External network的入口
  2. Docker swarm是Internal network,不对外公开
  3. HAProxy/Nginx在配置Load Balance时,每个Server的定义仍然使用的是各Docker work nodes的IP地址(最大的提高性能),在Nginx中类似于下面的配置片断:
    upstream apache2{
    server 192.168.0.2:8080;
    server 192.168.0.3:8080;
    }
    
    server{
    listen 80;
    server_name apache.zhuoyue.me;
    location /{
    proxy_pass http://apache2;
    }
    }
  4. Docker swarm也有自己的Load Balance和Health check功能和规则,在上一项的描述中,我们也可以在Nginx中不去指定upstream,而让swarm去进行load balancing,那么在nginx就可以这样配置:
    server{
    listen 80;
    server_name apache.zhuoyue.me;
    location /{
    proxy_pass http://192.168.0.2:8080;
    }
    }

    但这种配置有一个缺点:那就是192.168.0.2这台host上的docker process不能halt。

  5. 那么整个docker swarm创建过程可能是这样的:
    1. 在docker manager node上创建了一个task:
      docker service create --name apache2 --publish 8080:80 --replicas 3 apache2

      我们创建了一个名为apache2的task,通过定义replicas=3创建了总计3个image name为apache2的containers, 并且它们暴露8080 port,用以映射container内部的apache httpd 的80端口

    2. 该service task被分配在2个work nodes上运行(IP地址分别为192.168.0.2, 192.168.0.3,其中192.168.0.2上会运行着2个container)
    3. 因为某不知名原因192.168.0.2中的2个apache2 container 都被halt,比如执行了命令
      docker stop containername

      然而在halt之前你是可以使用192.168.0.2:8080访问apache2

    4. 此时你以为无法再继续使用192.168.0.2:8080访问apache2了,但事实并非如此,因为worker node工作在swarm模式下,192.168.0.2:8080请求会被docker swarm ingress路由到一个可用的contianer上继续执行(192.168.0.3:8080),并且它不同于重定向,响应IP地址仍然是192.168.0.2:8080)