HECK:haproxy+etcd+confd+kvm 實現高可用自動化發現基礎架構

【HECK】javascript

  目的實現自動縮/擴容的高可用web架構。php

 

【軟件介紹】css

  一、Etcdhtml

    Etcd是一個高可用的 Key/Value 存儲系統,主要用於分享配置和服務發現。java

     簡單:支持 curl 方式的用戶 API (HTTP+JSON)
     安全:可選 SSL 客戶端證書認證
     快速:單實例可達每秒 1000 次寫操做
     可靠:使用 Raft 實現分佈式node

  二、Confdpython

    Confd是一個輕量級的配置管理工具。經過查詢Etcd,結合配置模板引擎,保持本地配置最新,同時具有按期探測機制,配置變動自動reload。linux

  三、Haproxy介紹nginx

    HAProxy是提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速而且可靠的一種解決方案。git

  

【方案介紹】

  首先web解決方案是haproxy+web(nginx)實現。

  KVM+Etcd+Confd實現自動發現上線到haproxy裏面。

  

  web方案:haproxy+nginx。haproxy公用配置,http reuest路由到不一樣的ha如:a.domain.com經過ha1轉發,b.domain.com經過ha2轉發

  haproxy高可用:haproxy+keepalived實現haproxy高可用

  etcd高可用:haproxy+keepalived實現etcd的高可用(etcd自己只實現寫操做被轉發到etcd leader上)

  confd:配置管理,配置自動拉去etcd中的配置項

  web服務:kvm+web鏡像(linux+nginx+php),經過kvm實現web增刪

 

  舉例:添加一臺bbs組下的web

  一、建立一個web vm,ip:172.16.1.100

  二、向etcd中添加一條配置相似以下:「group:bbs;name:bbs03;ip:172.16.1.100;」

  三、confd會按期從etcd中拉取配置,從而發現。

  四、圖例

  

  PS:kvm的可替代方案docker,etcd+confd的可替代方案puppet

 

【安裝過程】

  搭建概述

  [test01:172.17.59.81] ha+confd
    HA-Proxy version 1.5.2
    Confd version confd 0.9.0
  [test02:172.17.59.82] etcd
    etcd version 2.0.5
  [web01:172.17.59.110] vm
    CentOS release 6.5 (Final)

  

  test01:安裝haproxy、confd
    #yum install haproxy

    # wget https://github.com/kelseyhightower/confd/releases/download/v0.9.0/confd-0.9.0-linux-amd64 -O confd //得到git當時最新版本的confd
    # mv confd /usr/local/bin/confd
    # chmod +x /usr/local/bin/confd
    # /usr/local/bin/confd -version

  test02:安裝etcd
    # curl -L https://github.com/coreos/etcd/releases/download/v2.0.5/etcd-v2.0.5-linux-amd64.tar.gz -o etcd-v2.0.5-linux-amd64.tar.gz
    # tar xzvf etcd-v2.0.5-linux-amd64.tar.gz
    # cd etcd-v2.0.5-linux-amd64
    # cp etcd* /bin/
    # etcd --version

  test03:安裝kvm
    一、安裝 KVM 和 virtinst (一個建立 virtual machines 的工具 )
      # yum install kvm kmod-kvm qemu libvirt python-virtinst
      或者
      # yum groupinstall KVM

    二、裝完後記的重起,重起後檢查模塊是否有加載
      # lsmod | grep kvm
      可使用 virsh 來測試
      # virsh -c qemu:///system list

    3. 安裝橋接管理的工具
      # yum install bridge-utils

    四、 virt-install安裝虛擬機
      光盤安裝:( 在圖形界面下)
      # virt-install --name Kcentos_01 --ram 700 --vcpus=2 --disk path=/var/virt_images/Kcentos_01.img,size=10 –bridge=br0 --os-type=linux --os-variant=rhel5.4 --accelerate --cdrom=/dev/cdrom –vnc

      其餘安裝能夠查看:virt-install –help

    五、圖形界面安裝:
      安裝 GUI 的管理軟件
      # yum install virt-manager
      # virt-manager安裝虛擬機

    ============================================================================================

    3 網絡配置(br0)
      # vim /etc/sysconfig/network-scripts/ifcfg-br0

      BOOTPROTO=static
      DEVICE=br0
      TYPE=Bridge
      ONBOOT=yes
      IPADDR=172.16.0.99
      NETMASK=255.255.0.0
      GATEWAY=172.16.0.1

 

      # vim /etc/sysconfig/network-scripts/ifcfg-eth0

      DEVICE=eth0
      ONBOOT=yes
      BRIDGE=br0    

      # /etc/init.d/network restart

      #沒嘗試vnc連接,直接在服務器端視窗裏面運行了 virt-viewer red-1 安裝的。
      #vnc配置
      #修改vnc監聽端口,放開使vnc監聽全部網段
      # vim /etc/libvirt/qemu.conf

      vnc_listen = "0.0.0.0"
      vnc_password = "123456"

 

 

 【配置過程】

  [Etcd配置]

    【啓動】沒有配置 直接啓動
    #/bin/etcd -name etcd01 \

    -peer-addr 172.17.59.82:7001 \

    -addr 172.17.59.82:4001 \

    -data-dir /data/etcd \

    -peer-bind-addr 0.0.0.0:7001 \

    -bind-addr 0.0.0.0:4001 \

    -initial-cluster etcd01='http://172.17.59.82:4001' \

    -initial-cluster-state new &

  

    

    【使用方法】
    # curl -L http://172.17.59.82:4001/v2/keys/mykey -XPUT -d value="my value"
    {"action":"set","node":{"key":"/mykey","value":"my value","modifiedIndex":6,"createdIndex":6},"prevNode":{"key":"/mykey","value":"my value","modifiedIndex":5,"createdIndex":5}}
    # curl -L http://172.17.59.82:4001/v2/keys/mykey
    {"action":"get","node":{"key":"/mykey","value":"my value","modifiedIndex":6,"createdIndex":6}}
    # curl -L http://172.17.59.82:4001/v2/keys/mykey -XDELETE
    {"action":"delete","node":{"key":"/mykey","modifiedIndex":7,"createdIndex":6},"prevNode":{"key":"/mykey","value":"my value","modifiedIndex":6,"createdIndex":6}}
    # curl -L http://172.17.59.82:4001/v2/keys/mykey&?recursive=true ###批量獲取

  

  [confd + haproxy 配置] haproxy使用的配置是confd的haproxy模板生成的

    【在etcd中添加配置】
    # curl -XPUT http://172.17.59.82:4001/v2/keys/app/servers/{servername} -d value="{ip}:{port}"

    

    【cond 啓動】
    # /usr/local/bin/confd -verbose -interval 10 -node '172.17.59.82:4001' -confdir /etc/confd > /var/log/confd.log &

  

    【haproxy 啓動】
    # /etc/init.d/haproxy start

    【confd配置:只有haproxy的配置】

      [配置文件]

      # cat /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"

 

      [模板文件]

      # cat /etc/confd/templates/haproxy.cfg.tmpl
      

global
    log         127.0.0.1 local2

    chroot      /var/lib/haproxy
    pidfile     /var/run/haproxy.pid
    maxconn     4000
    user        haproxy
    group       haproxy
    daemon

    stats socket /var/lib/haproxy/stats

defaults
    mode                    http
    log                     global
    option                  httplog
    option                  dontlognull
    option http-server-close
    option forwardfor       except 127.0.0.0/8
    option                  redispatch
    retries                 3
    timeout http-request    10s
    timeout queue           1m
    timeout connect         10s
    timeout client          1m
    timeout server          1m
    timeout http-keep-alive 10s
    timeout check           10s
    maxconn                 3000

frontend  main *:80
    acl url_static       path_beg       -i /static /images /javascript /stylesheets
    acl url_static       path_end       -i .jpg .gif .png .css .js

    use_backend static          if url_static
    default_backend             app


backend static
    balance     roundrobin
    server      static 172.17.59.83:80 check

backend app
    balance     roundrobin
    {{range gets "/app/servers/*"}}
    server {{base .Key}} {{.Value}} check inter 5000 fall 1 rise 2
    {{end}}


listen status *:8080
    stats enable
    stats uri /stats
    stats auth admin:123456
    stats realm (Haproxy\ statistic)

 

    【confd語法】
    一、做爲path.Base函數的別名,獲取路徑最後一段。
    {{ with get "/app/servers/prickly_blackwell"}}
      server {{base .Key}} {{.Value}} check
    {{end}}

    結果:prickly_blackwell 192.168.1.22:49162

 

 

    二、返回一對匹配的KV,找不到則返回錯誤。
    {{with get "/app/servers/prickly_blackwell"}}
      key: {{.Key}}
      value: {{.Value}}
    {{end}}

    結果:/app/servers/prickly_blackwell 192.168.1.22:49162

    三、gets 返回全部匹配的KV,找不到則返回錯誤。
    {{range gets "/app/servers/*"}}
      {{.Key}} {{.Value}}
    {{end}}

    /app/servers/backstabbing_rosalind 192.168.1.22:49156
    /app/servers/cocky_morse 192.168.1.22:49158
    /app/servers/goofy_goldstine 192.168.1.22:49160
    /app/servers/prickly_blackwell 192.168.1.22:49162

    四、getv
      返回一個匹配key的字符串型Value,找不到則返回錯誤。
      {{getv "/app/servers/cocky_morse"}}

      結果:192.168.1.22:49158

    五、getvs
      返回全部匹配key的字符串型Value,找不到則返回錯誤。
      {{range getvs "/app/servers/*"}}
        value: {{.}}
      {{end}}

      結果:

      value: 192.168.1.22:49156
      value: 192.168.1.22:49158
      value: 192.168.1.22:49160
      value: 192.168.1.22:49162

    

    六、split 對輸入的字符串作split處理,即將字符串按指定分隔符拆分紅數組。
      {{ $url := split (getv "/app/servers/cocky_morse") ":" }}
      host: {{index $url 0}}
      port: {{index $url 1}}

      結果: 

      host: 192.168.1.22 

      port: 49158


    七、ls 返回全部的字符串型子key,找不到則返回錯誤。
      {{range ls "/app/servers/"}}
        subkey: {{.}}
      {{end}}

 

      結果:

      subkey: backstabbing_rosalind
      subkey: cocky_morse
      subkey: goofy_goldstine
      subkey: prickly_blackwell

    八、lsdir 返回全部的字符串型子目錄,找不到則返回一個空列表。
      {{range lsdir "/app/"}}
        subdir: {{.}}
      {{end}}

      結果:subdir: servers

  

  【kvm clone】
  # virt-clone 是能夠指定mac和uuid的,不指定的話會自動生成
  # virt-clone -o rhel5.4_32_2 -n rhel5.4_32_3 -f /dev/libvirt_lvm/rhel5.4-3 -m 52:54:00:31:15:40

  PS:博主鏡像建立的時候只安裝了nginx,須要將 chkconfig nginx on 

 

【自動建立vm的shell腳本】

    #!/bin/bash
    vmname=$1
    image=$2
    vmip=$3
    vmfile="/datadir/kvm/$vmname.qcow2"
    etcdurl='http://172.17.59.82:4001'

    if [ ! $1 ]; then
        echo "vmname must specify"
        echo "USAGE : sh addweb.sh {vmname} {image} {vmip}"
        exit
    fi
    if [ ! $3 ]; then
        echo "vmip must specify"
        echo "USAGE : sh addweb.sh {vmname} {image} {vmip}"
        exit
    fi

    ####### mk vm
    #kvm clone
    virt-clone -n $vmname -o $image -f $vmfile
    if [ $? -ne 0 ]; then
        echo "Clone vm $vmname faild"
        exit
    fi

    #specify vm IP
    virt-edit $vmfile /etc/sysconfig/network-scripts/ifcfg-eth0 -e 's/^IPADDR.*/IPADDR='$vmip'/m'
    if [ $? -ne 0 ]; then
        echo "Specify ip faild"
        exit
    fi

    #edit vm vnc port

    #start vm
    virsh start $vmname
    virsh autostart $vmname
    if [ $? -ne 0 ]; then
        echo "start vm:$vmname faild"
        exit
    fi

    ####### virsh start $vmname

    # set etcd
    curl -XPUT $etcdurl/v2/keys/app/servers/$vmname -d value="$vmip:80"

  核心命令:

    一、virt-clone -n $vmname -o $image -f $vmfile
    二、virt-edit $vmfile /etc/sysconfig/network-scripts/ifcfg-eth0 -e 's/^IPADDR.*/IPADDR='$vmip'/m'
    三、curl -XPUT $etcdurl/v2/keys/app/servers/$vmname -d value="$vmip:80"

 

【踩過的坑】  

  1 : etcd啓動失敗
    屏顯報錯:etcd: couldn't find local name "etcdserver01" in the initial cluster configuration
    解決方式:添加-initial-cluster參數,見啓動etcd命令

  2 :啓動vm後沒法當即使用

    #在源鏡像上刪除
    # /etc/udev/rules.d/70-persistent-net.rules

  3 :kvm設置ip
    # virt-edit $vmfile /etc/sysconfig/network-scripts/ifcfg-eth0 -e 's/^IPADDR.*/IPADDR='$vmip'/m'

 

  4 : vnc端口設置

    virsh edit test03  # vnc端口設置成-1,之後經過virsh vncdisplay {domain}查看vnc端口

 

  5 : nginx 輸出當前服務器IP

    樓主使用的sub_filter,替換nginx默認index.html裏面的一段文字,以下圖所示

    location / {
      root   /usr/share/nginx/html;
      index  index.html index.htm;

      sub_filter  'search string' $server_addr;
      sub_filter_once off;
    }

  

 

【參考文檔】

  * HECD 一個高可用及自動發現的Docker基礎架構(博主主要參考的文章)
  http://blog.liuts.com/post/242/ 

  Docker中文文檔
  http://yeasy.gitbooks.io/docker_practice/content/ 

  etcd官網
  https://coreos.com/etcd/ 

  etcd@git
  https://github.com/coreos/etcd 

  etcd集羣
  https://github.com/coreos/etcd/blob/master/Documentation/clustering.md#etcd-discovery 

  confd@git
  https://github.com/kelseyhightower/confd/ 

 

PS : 拒絕眼高手低

相關文章
相關標籤/搜索