【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 : 拒絕眼高手低