天天看点

可自动扩展的高可用Swarm集群EdgeScaler的搭建

    • 项目简介
    • 应用场景
    • 集群架构
    • 组件描述
    • 集群搭建
      • 环境准备
      • Swarm工作节点搭建
      • Swarm管理节点搭建
      • ConfdHAProxy节点搭建
    • 小结

项目简介

随着虚拟化和容器技术的日趋成熟,Docker越来越受到人们的关注,目前Docker已经发展到1.10版本,并且已经可以在生产环境大规模部署。本文介绍EdgeScaler集群系统,使用Swarm+Docker+Registrator+Etcd+Confd+HAProxy搭建了一个可自动可扩展的docker集群。

应用场景

EdgeScaler能满足一下两种业务场景:

1. 提供APP服务器集群服务,并提供负载均衡,端口暴露,资源隔离等基本功能。

2. 为开发人员提供内部PaaS级的测试环境。

集群架构

在EdgeScaler中,我们使用swarm对集群进行管理,其架构如下:

可自动扩展的高可用Swarm集群EdgeScaler的搭建

其中:

  • swarm管理集群可以使用主从节点提高管理节点高可用性,通过标准RESTFul API对管理需求提供服务。
  • 由于Docker属于系统级别的虚拟化隔离,其功能特性依然依赖宿主机,目前在隔离性方面还有待完善,所以在实际生成环境中会将docker host运行在虚拟机中,虚拟机网络可以根据不同情况配置成互相隔离的专用网络,形成局部的封闭环境,保护物理主机的正常运行。
  • 在本图中左侧虚拟机为单独的局域网络

组件描述

Swarm:版本号为1.1.2。Swarm是一个docker官方提供的服务,他可以将多个docker实例抽象成一个ip加端口的地址,供其他docker管理工具调用。

Docker:版本号为1.10.2,自1.9+版本以后docker支持overlay网络,此网络为swarm跨主机网络方案。

Registrator:为最新registrator镜像,Registrator为docker端口服务映射服务,它监听docker socket端口信息,并对信息进行整理,存入如Etcd这样的服务发现的K-V存储系统中。

Etcd:在分布式系统中,如何管理节点间的状态同样一直是一个难题,Etcd是专门为集群环境的服务发现和注册而设计,它提供了数据TTL失效、数据改变监视、多值、目录监听、分布式锁原子操作等功能,可以方便的跟踪并管理集群节点的状态。

Confd: Confd是一个轻量级的配置管理工具,通过定期从etcd中读出关心数据,并更新本地配置文件,同时reload读取配置文件的应用。

HAProxy: HAProxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理。

集群搭建

环境准备

IP定义:

etcd_host:为发现服务集群IP地址

swarm_manager_host:为swarm管理节点IP地址

swarm_local_node_host:为swarm从节点本地IP地址

  1. Docker 安装并配置

    获取最新的docker程序

    curl -fsSL https://get.docker.com/ | sh
    在所有swarm节点中配置docker daemon监听配置,使用nohup命令使daemon后台运行。
    nohup docker daemon -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock –cluster-store etcd://etcd_host:2379 –cluster-advertise swarm_local_node_host:2375 &

    -H 代表daemon监听所有2375端口的网络请求,并监听本地客户端socket请求信息

    –cluster-store 指定发现服务系统

    –cluster-advertise 广播本地节点服务地址

    启动后,可运行如下命令测试

    docker version
  2. 获取swarm

    最简单的获取安装swarm方法是直接拉去swarm镜像:

    docker pull swarm
  3. Etcd集群搭建

    在所有节点上搭建etcd服务发现系统,可从https://github.com/coreos/etcd/releases下载最新版本的Etcd,并用如下shell脚本运行Etcd服务,推荐节点数目>3并且为奇数。

    NAME=infra0
    MASTER_NAME=infra0
    SLAVE_NAME_1=infra1
    SLAVE_NAME_2=infra2
    LOCAL_IP=
    MASTER=
    SLAVE_IP_1=
    SLAVE_IP_2=
    etcd -name $NAME -initial-advertise-peer-urls http://$LOCAL_IP:2380 \
             -listen-peer-urls http://$LOCAL_IP:2380 \
             -listen-client-urls http://$LOCAL_IP:2379,http://127.0.0.1:2379 \
             -advertise-client-urls http://$LOCAL_IP:2379 \
             -initial-cluster-token etcd-cluster- \
             -initial-cluster MASTER_NAME=http://$MASTER:2380, \
                                     SLAVE_NAME_1=http://$SLAVE_IP_1:2380, \
                                     SLAVE_NAME_2=http://$SLAVE_IP_2:2380 \
             -initial-cluster-state new > /var/log/etcd.log >& &
               

    ETCD_NODE_NAME 为所定义的etcd节点名称,不能出现重复

    LOCAL_IP 为本地ip地址

    MASTER_IP 所定义的Master节点IP地址

    SLAVE_IP 所定义的Slave节点IP地址

    :2379 为etcd对外提供服务端口

    :2380 为etcd节点间通信端口

    启动后可运行如下命令进行测试

    etcdctl member list

Swarm工作节点搭建

  1. 启动swarm工作节点
    docker run -d swarm join –addr=swarm_local_node_host:2375 etcd://etcd_host:2379/swarm

    -d 后台运行swarm镜像

    –addr 本地IP地址

  2. 开启Registrator
    docker run -d –name=registrator –net=host –privileged –volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest etcd://etcd_host:2379/services

    –name 指定运行容器名

    –net 指定网络模式

    –privileged 给容器指定特权权限

    –volume 建立容器与主机目录映射关系

Swarm管理节点搭建

  1. 启动swarm管理节点
    docker run -d -p 8888:2375 swarm manage –replication –advertise swarm_manager_host:8888 etcd://etcd_host:2379/swarm

    主管理节点标志,从管理节点无需配置

    –replication 告诉swarm此管理节点为多管理配置,并且此管理节点为主管理节点

    –advertise 指定主管理节点地址,主管理节点会广播信息给其它从管理节点

  2. 设置docker host环境变量
    export DOCKER_HOST=”tcp://swarm_manager_host:8888”
    当运行docker命令时,不必使用-H 指定docker daemon位置
  3. 检验并查看集群状态
    docker info
    输出如下:
    Containers: 
    Running: 
    Paused: 
    Stopped: 
    Images: 
    Server Version: swarm/
    Role: primary
    Strategy: spread
    Filters: health, port, dependency, affinity, constraint
    Nodes: 
     slave1: :
          ?.Status: Healthy
          ?.Containers: 
          ?.Reserved CPUs:  / 
          ?.Reserved Memory:  B /  GiB
          ?.Labels: executiondriver=native-, kernelversion=-el7.x86_64, operatingsystem=CentOS Linux  (Core), storagedriver=devicemapper
          ?.Error: (none)
          ?.UpdatedAt: --T13::Z
     slave2: :
          ?.Status: Healthy
          ?.Containers: 
          ?.Reserved CPUs:  / 
          ?.Reserved Memory:  B /  GiB
          ?.Labels: executiondriver=native-, kernelversion=-el7.x86_64, operatingsystem=CentOS Linux  (Core), storagedriver=devicemapper
          ?.Error: (none)
          ?.UpdatedAt: --T13::Z
    Plugins: 
    Volume: 
    Network: 
    Kernel Version: -el7.x86_64
    Operating System: linux
    Architecture: amd64
    CPUs: 
    Total Memory:  GiB
    Name: c269b1e4ba40
               

Confd+HAProxy节点搭建

  1. 下载并配置

    可从https://github.com/kelseyhightower/confd/releases/下载最新的Confd程序,并将confd移动到指定目录。

    mv confd-linux-amd64 /usr/local/bin/confd

    chmod +x /usr/local/bin/confd

    confd -version

    安装HAProxy
    yum -y install haproxy
  2. 建立资源文件

    Confd的资源文件分为两种,一种为资源配置文件,路径为/etc/confd/conf.d;另一种为配置模板文件,路径为/etc/confd/templates。

  3. 建立配置文件
    vim /etc/confd/conf.d/haproxy.toml
    并编辑
    [template]
     src = "haproxy.cfg.tmpl"
     dest = "/etc/haproxy/haproxy.cfg"
     keys = [
       "/app/servers",
     ]
     reload_cmd = "/etc/init.d/haproxy reload"
               
  4. 建立模板文件
    vim /etc/confd/conf.d//haproxy.cfg.tmpl
    并编辑
    global  
            log  local_log  
            maxconn   
            uid   
            gid   
            daemon  
    defaults  
            log  local_log  
            mode http  
            option dontlognull  
            retries   
            option redispatch  
            maxconn   
            contimeout    
            clitimeout    
            srvtimeout    
    listen frontend :  
            mode http  
            balance roundrobin  
            maxconn   
            option forwardfor  
            {{range gets "/services/*"}}  
            server {{base .Key}} {{.Value}} check inter  fall  rise   
            {{end}}  
    
        stats enable  
        stats uri /admin-status  
        stats auth admin:  
        stats admin if TRUE  
               
  5. 启动Confd

    confd -onetime -backend etcd -node etcd_host:2379

    /usr/local/bin/confd -verbose -interval 10 -node ‘etcd_host:2379′ -confdir /etc/confd > /var/log/confd.log &

  6. Confd基本命令
    • base

      作为path.Base函数的别名,获取路径最后一段。

      {{ with get “/services/key”}}
      server {{base .Key}} {{.Value}} check
      {{end}}
                 
    • get

      返回一对匹配的KV,找不到则返回错误

      {{with get “/services/key”}}
      key: {{.Key}}
      value: {{.Value}}
      {{end}}
                 
    • gets

      返回所有匹配的KV,找不到则返回错误

      {{range gets “/services/*”}}
      {{.Key}} {{.Value}}
      {{end}}
                 
    • getv

      返回一个匹配key的字符串型Value,找不到则返回错误

    • getvs

      返回所有匹配key的字符串型Value,找不到则返回错误

      {{range getvs “/app/servers/*”}}
      value: {{.}}
      {{end}}
                 
    • splite

      对输入的字符串做split处理,即将字符串按指定分隔符拆分成数组

      {{ $url := split (getv “/services/key”) “:” }}
      host: {{index $url 0}}
      port: {{index $url 1}}
                 
    • ls

      返回所有的字符串型子key,找不到则返回错误

      {{range ls “/services/*”}}
      subkey: {{.}}
      {{end}}
                 
    • lsdir

      返回所有的字符串型子目录,找不到则返回一个空列表

      {{range lsdir “/services/*”}}
      subdir: {{.}}
      {{end}}
                 
    这样当Confd会定期查询etcd服务,并取出关心字段,并更新haproxy.cfg文件,并重新加载HAProxy服务。在etcd中的Registrator字段如下
    /services/service-port/dhost:cname:cport value: ipaddress:cport
    service:    容器的镜像名字
    port:       容器公开的端口
    dhost:      容器运行的Docker主机
    cport:      容器公开的端口
    ipaddress:  容器运行的Docker主机的ip地址
               

小结

以上就是EdgeScaler的主要内容,其中还使用了Pyhon EVE + Flask框架开发了RESTFul风格的API接口,供前端页面调用并返回数据,此接口在LAN Network中调用。

对于客户来说,为客户提供VPN接入服务,直接接入为不同客户所定制的虚拟网络中,客户可以选择登录集群网络环境或者开发测试网络环境,系统通过代码自动对用户所选择的环境进行自动配置,配置过程对客户透明。

由于具体网络设置涉及到OpenStack虚拟网络配置,相对复杂,我对在未来的文章中单独进行介绍。

继续阅读