HECK:haproxy+etcd+confd+kvm 实现高可用自动化发现基础架构
【HECK】目的实现自动缩/扩容的高可用web架构。
【软件介绍】
1、Etcd
Etcd是一个高可用的 Key/Value 存储系统,主要用于分享配置和服务发现。
简单:支持 curl 方式的用户 API (HTTP+JSON)
安全:可选 SSL 客户端证书认证
快速:单实例可达每秒 1000 次写操作
可靠:使用 Raft 实现分布式
2、Confd
Confd是一个轻量级的配置管理工具。通过查询Etcd,结合配置模板引擎,保持本地配置最新,同时具备定期探测机制,配置变更自动reload。
3、Haproxy介绍
HAProxy是提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
【方案介绍】
首先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
1、创建一个web vm,ip:172.16.1.100
2、向etcd中添加一条配置类似如下:“group:bbs;name:bbs03;ip:172.16.1.100;”
3、confd会定期从etcd中拉取配置,从而发现。
4、图例
PS:kvm的可替代方案docker,etcd+confd的可替代方案puppet
【安装过程】
搭建概述
ha+confd
HA-Proxy version 1.5.2
Confd version confd 0.9.0
etcd
etcd version 2.0.5
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 -Lhttps://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
1、安装 KVM 和 virtinst (一个创建 virtual machines 的工具 )
# yum install kvm kmod-kvm qemu libvirt python-virtinst
或者
# yum groupinstall KVM
2、装完后记的重起,重起后检查模块是否有加载
# lsmod | grep kvm
可以使用 virsh 来测试
# virsh -c qemu:///system list
3. 安装桥接管理的工具
# yum install bridge-utils
4、 virt-install安装虚拟机
光盘安装:( 在图形界面下)
# virt-install --name Kcentos_01 --ram 700 --vcpus=2 --diskpath=/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
5、图形界面安装:
安装 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"
【配置过程】
【启动】没有配置 直接启动
#/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 ###批量获取
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
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
frontendmain *: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语法】
1、作为path.Base函数的别名,获取路径最后一段。
{{ with get "/app/servers/prickly_blackwell"}}
server {{base .Key}} {{.Value}} check
{{end}}
结果:prickly_blackwell 192.168.1.22:49162
2、返回一对匹配的KV,找不到则返回错误。
{{with get "/app/servers/prickly_blackwell"}}
key: {{.Key}}
value: {{.Value}}
{{end}}
结果:/app/servers/prickly_blackwell 192.168.1.22:49162
3、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
4、getv
返回一个匹配key的字符串型Value,找不到则返回错误。
{{getv "/app/servers/cocky_morse"}}
结果:192.168.1.22:49158
5、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
6、split 对输入的字符串做split处理,即将字符串按指定分隔符拆分成数组。
{{ $url := split (getv "/app/servers/cocky_morse") ":" }}
host: {{index $url 0}}
port: {{index $url 1}}
结果:
host: 192.168.1.22
port: 49158
7、ls 返回所有的字符串型子key,找不到则返回错误。
{{range ls "/app/servers/"}}
subkey: {{.}}
{{end}}
结果:
subkey: backstabbing_rosalind
subkey: cocky_morse
subkey: goofy_goldstine
subkey: prickly_blackwell
8、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"
核心命令:
1、virt-clone -n $vmname -o $image -f $vmfile
2、virt-edit $vmfile /etc/sysconfig/network-scripts/ifcfg-eth0 -e 's/^IPADDR.*/IPADDR='$vmip'/m'
3、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;
indexindex.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 : 拒绝眼高手低
页:
[1]