1. 程式人生 > >Haproxy+etcd+confd+Docker搭建節點自動發現的高可用負載均衡框架

Haproxy+etcd+confd+Docker搭建節點自動發現的高可用負載均衡框架

作業系統:Centos 6.5

先扔出一張圖來解釋這四個元件之間的關係

Haproxy+etcd+confd+Docker

下面細說

1.Haproxy

Haproxy不用多說,負載均衡軟體,安裝Haproxy

yum -y install haproxy

版本是haproxy-1.5.4-3.el6.x86_64.rpm

2.etcd

etcd,是一個高可用的 Key/Value 的記憶體資料庫,提供 釋出/訂閱 模式的操作,每當有新的後端節點加入的時候,我們都會用指令碼操作到etcd上去釋出新節點資訊,而已經訂閱該訊息的confd客戶端就會收到新節點的釋出資訊,它會修改配置檔案且分發去覆蓋本機的Haproxy的配置,並且重啟Haproxy,以達到給Haproxy新增後端分發節點的目的,安裝etcd

wget https://github.com/coreos/etcd/releases/download/v3.0.3/etcd-v3.0.3-linux-amd64.tar.gz
tar xvf etcd-v3.0.3-linux-amd64.tar.gz 
[root@201 data]# cd etcd-v3.0.3-linux-amd64/
[root@201 etcd-v3.0.3-linux-amd64]# cp etcd* /bin/
[root@201 etcd-v3.0.3-linux-amd64]# etcd -version
etcd Version: 3.0.3
Git SHA: 24a90ba
Go Version: go1.6
.2 Go OS/Arch: linux/amd64

啟動etcd

[root@201 data]# etcd --listen-peer-urls 'http://192.168.1.204:2380' --advertise-client-urls 'http://192.168.1.204:2379' --listen-client-urls 'http://192.168.1.204:2379' -data-dir /data/default.etcd -name etcd1 &

檢視其監聽的埠
[root@201 data]# netstat -npl|grep etcd
tcp        0      0
127.0.0.1:2379 0.0.0.0:* LISTEN 4750/etcd tcp 0 0 127.0.0.1:2380 0.0.0.0:* LISTEN 4750/etcd 設定測試key value [root@201 data]# curl -L http://192.168.1.204:2379/v2/keys/key1 -XPUT -d value="Hello world" {"action":"set","node":{"key":"/key1","value":"Hello world","modifiedIndex":5,"createdIndex":5}} 查詢測試key [root@201 data]# curl -L http://192.168.1.204:2379/v2/keys/key1 {"action":"get","node":{"key":"/key1","value":"Hello world","modifiedIndex":5,"createdIndex":5}} 刪除key curl -XDELETE http://192.168.1.204:2379/v2/keys/app/servers 另外還可以用etcdctl命令來操作,建立一個新的目錄和鍵分別使用 etcdctl mkdir 和 etcdctl mk 命令。 [root@201 data]# etcdctl mkdir /demo [root@201 data]# etcdctl get /demo /demo: is a directory [root@201 data]# etcdctl mk /demo/hello "Hello Etcd" # 實際情況中這裡會回顯輸出“Hello Etcd”,省略 [root@201 data]# etcdctl get /demo/hello Hello Etcd

3.confd

上面說過了,confd是分發新的配置到Haproxy中,安裝confd

wget https://github.com/kelseyhightower/confd/releases/download/v0.11.0/confd-0.11.0-linux-amd64
[root@201 data]# mv confd-0.11.0-linux-amd64 /usr/local/bin/confd
[root@201 data]# chmod +x /usr/local/bin/confd 
[root@201 data]# confd -version
confd 0.11.0

confd要與haproxy安裝在同一臺主機上,以便能生成給Haproxy用的配置。建立confd的預設配置存放路徑,confd會根據該檔案找到要修改的haproxy檔案路徑

[[email protected]201 data]# mkdir -p /etc/confd/templates
vim /etc/confd/conf.d/haproxy.toml
[template]
#模板檔案,基於它進行修改
src = "haproxy.cfg.tmpl"
#haproxy的預設配置路徑
dest = "/etc/haproxy/haproxy.cfg"
#keys是在etcd上訂閱訊息的字首
keys = [
  "/app/servers",
]
#更新配置後重啟haproxy
reload_cmd = "/etc/init.d/haproxy reload"

建立haproxy.cfg的模板檔案,以便confd能根據模板生成配置,語法格式是基於Go語言的語法

vim /etc/confd/templates/haproxy.cfg.tmpl

global
        log 127.0.0.1 local3
        maxconn 5000
        uid 99
        gid 99
        daemon

defaults
        log 127.0.0.1 local3
        mode http
        option dontlognull
        retries 3
        option redispatch
        maxconn 2000
        timeout connect 5000
        timeout client  50000
        timeout server  50000

frontend myhttp
        mode http
        bind 192.168.1.204:80
        use_backend myserver
backend myserver
        mode http
        balance roundrobin
        #confd的語法會替換下面的變數
        {{range gets "/app/servers/*"}}
        server {{base .Key}}{{.Value}} weight 10
        {{end}}

啟動confd

confd -interval 10 -node '192.168.1.204:2379' -confdir /etc/confd > /var/log/confd.log &

這樣當我們手動修改haproxy.cfg.tmpl檔案以後,每隔不到10s左右的時間,confd都會發現模板檔案已經更新,會重新生成配置釋出,看到更新時候的日誌如下

2016-07-23T21:45:39+08:00 204.localdomain confd[3317]: INFO /etc/haproxy/haproxy.cfg has md5sum 4b3b5d42ffd945117fe74d5d234ae49b should be e81aa47326241d0d1530c9d4b13e1e39
2016-07-23T21:45:39+08:00 204.localdomain confd[3317]: INFO Target config /etc/haproxy/haproxy.cfg out of sync
2016-07-23T21:45:39+08:00 204.localdomain confd[3317]: INFO Target config /etc/haproxy/haproxy.cfg has been updated

4.docker啟動指令碼

我們啟動docker要寫一個指令碼,先啟動docker,得到容器id。然後更新資訊到etcd上,進而出發confd釋出新的配置給Haproxy,這樣在Haproxy配置檔案中將我們新啟動的容器ip地址新增到後端列表,以達到註冊新節點的目的。記住啟動和停止docker都要用這個指令碼,不要直接使用docker命令,因為指令碼還要處理etcd的資訊。

docker.sh

 --dns 172.17.42.1

#!/bin/bash

if [ -z $1 ]; then
        echo "Usage: c start <image name>:<version>"
        echo "       c stop <container name>"
        exit 1
fi

# etcd地址我先寫死了,最好改成用指令碼獲取
if [ -z $ETCD_HOST ]; then
  ETCD_HOST="192.168.1.204:2379"
fi

if [ -z $ETCD_PREFIX ]; then
  ETCD_PREFIX="app/servers"
fi

if [ -z $CPORT ]; then
  CPORT="80"
fi

# 網絡卡是eth?要寫清楚
if [ -z $FORREST_IP ]; then
  FORREST_IP=`ifconfig eth1| grep "inet addr" | head -1 | cut -d : -f2 | awk '{print $1}'`
fi

# 啟動docker
function launch_container {
        echo "Launching $1 on $FORREST_IP and mapped port $CPORT to ..."

        CONTAINER_ID=`docker run -d -P $1 python app.py`
        #CONTAINER_ID=`docker run -d -P -v /data:/data -v /etc/httpd/conf:/etc/httpd/conf -v /etc/httpd/conf.d:/etc/httpd/conf.d -v /etc/localtime:/etc/localtime:ro $1 /bin/sh -c "/usr/bin/supervisord -c /etc/supervisord.conf"`
        PORT=`docker inspect $CONTAINER_ID|grep "\"Ports\"" -A 50|grep "\"$CPORT/tcp\"" -A 3| grep HostPort|cut -d '"' -f4|head -1`
        NAME=`docker inspect $CONTAINER_ID | grep Name | cut -d '"' -f4 | sed "s/\///g"|sed -n 1p`

        echo "Announcing to $ETCD_HOST..."
        # 釋出到etcd上去,觸發confd重新整理haproxy的配置,以註冊新節點
        args="http://$ETCD_HOST/v2/keys/$ETCD_PREFIX/$NAME -d value=$FORREST_IP:$PORT"
        #echo "curl -XPUT "$args
        curl -XPUT $args

        echo "$1 running on Port $PORT with name $NAME"
}

# 停止docker
function stop_container {
        echo "Stopping $1..."
        CONTAINER_ID=`docker ps -a| grep $1 | awk '{print $1}'`
        echo "Found container $CONTAINER_ID"
        docker stop $CONTAINER_ID
  echo http://$ETCD_HOST/v2/keys/$ETCD_PREFIX/$1
        curl -XDELETE http://$ETCD_HOST/v2/keys/$ETCD_PREFIX/$1 &> /dev/null
        echo "Stopped."
}

if [ $1 = "start" ]; then
  launch_container $2
else
  stop_container $2
fi

一開始繫結eth0,發現一直失敗,原來網絡卡繫結錯了,後來改成eth1了。

5.測試

啟動兩個後端映象試試

啟動第一個服務
[[email protected]204 data]# ./docker.sh run tutum/lamp
Launching tutum/lamp on 192.168.1.204 and mapped port 80 to ...
Announcing to 192.168.1.204:2379...
{"action":"set","node":{"key":"/app/servers/boring_goldstine","value":"192.168.1.204:32769","modifiedIndex":4,"createdIndex":4}}
tutum/lamp running on Port 32769 with name boring_goldstine

啟動第二個服務
[[email protected]204 data]# ./docker.sh run tutum/lamp
Launching tutum/lamp on 192.168.1.204 and mapped port 80 to ...
Announcing to 192.168.1.204:2379...
{"action":"set","node":{"key":"/app/servers/fervent_curie","value":"192.168.1.204:32771","modifiedIndex":5,"createdIndex":5}}
tutum/lamp running on Port 32771 with name fervent_curie

執行上述命令的同時,由於etcd發生了變化,confd訂閱的訊息會被觸發更新Haproxy的配置,以下日誌表示更新配置

2016-07-25T16:37:59+08:00 204.localdomain confd[1300]: INFO /etc/haproxy/haproxy.cfg has md5sum b363dce20b5df8e4f82a327532623cd8 should be 2ca9875a74f76e9aa3701c3675d768ed
2016-07-25T16:37:59+08:00 204.localdomain confd[1300]: INFO Target config /etc/haproxy/haproxy.cfg out of sync
2016-07-25T16:37:59+08:00 204.localdomain confd[1300]: INFO Target config /etc/haproxy/haproxy.cfg has been updated

查詢下etcd中的配置

[[email protected]204 data]# etcdctl --endpoints "http://192.168.1.204:2379,http://192.168.1.204:2380" ls /app/servers
/app/servers/boring_goldstine
/app/servers/fervent_curie

可見現在有boring_goldstine和fervent_curie兩個服務,那麼docker中應該也對應這兩個NAMES

[[email protected]204 data]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                                            NAMES
965fceb923a0        tutum/lamp          "/run.sh"           52 seconds ago      Up 50 seconds       0.0.0.0:32771->80/tcp, 0.0.0.0:32770->3306/tcp   fervent_curie       
7bedfc46554b        tutum/lamp          "/run.sh"           54 seconds ago      Up 53 seconds       0.0.0.0:32769->80/tcp, 0.0.0.0:32768->3306/tcp   boring_goldstine 

好,現在我們整套框架都搭建起來了,可以開始測試。

單獨在瀏覽器去訪問兩個啟動的server,都有響應(如果半天卡死先把防火牆關閉了,但是啟動docker的時候則需要開啟)http://192.168.1.204:32769/
這裡寫圖片描述

剛才是直接分別訪問兩個後端服務,那麼我們從haproxy的入口處,80埠去訪問下http://192.168.1.204
這裡寫圖片描述

測試haproxy轉發到後端機器成功了。為了更直觀的看到haproxy到底轉發到哪臺後端伺服器了,我們訪問http://192.168.1.204/phpinfo.php,可以在輸出的資訊中看到機器名稱 Linux 7bedfc46554b 2.6.32-431
這裡寫圖片描述
或者Linux 965fceb923a0 2.6.32-431
這裡寫圖片描述
,機器名稱時不時的變化,說明後端訪問分發到不同的伺服器上去了。

6.遇到問題

  1. etcd cluster is unavailable or misconfigured

操作如下命令的時候出錯

[[email protected] data]# etcdctl mkdir /app

Error: client: etcd cluster is unavailable or misconfigured

error #0: dial tcp 127.0.0.1:2379: getsockopt: connection refused

error #1: dial tcp 127.0.0.1:4001: getsockopt: connection refused

這是因為沒有指定ip資訊,加上ip就可以了,比如ls命令,這樣寫

  1. 停止一個容器,不要直接去操作docker,要用指令碼,否則只停了容器而etcd中的配置資訊不會刪除掉,如下
[root@204 data]# ./docker.sh stop thirsty_lovelace
Stopping thirsty_lovelace...
Found container 08e68416006a
08e68416006a
http://192.168.1.204:2379/v2/keys/app/servers/thirsty_lovelace
Stopped.

相關推薦

Haproxy+etcd+confd+Docker搭建節點自動發現可用負載均衡框架

作業系統:Centos 6.5 先扔出一張圖來解釋這四個元件之間的關係 下面細說 1.Haproxy Haproxy不用多說,負載均衡軟體,安裝Haproxy yum -y install haproxy 版本是haproxy-1.5

基於HAProxy+Keepalived可用負載均衡web服務的搭建

1.2 epo cnblogs oba backup 保持 ica mysql redis 一 原理簡介 1.HAProxyHAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速並且可靠的一種解決方案。HAProxy特別適用於那

Keepalived+Haproxy搭建可用負載均衡

eas 1.5 desc patch ble set 雙機 backend sql global_defs { notification_email { [email protected]/* */ } n

docker下用keepalived+Haproxy實現可用負載均衡叢集

先記錄下遇到的坑,避免之後忘了; 花時間最多去解決的一個題是:在docker下啟動haproxy服務後在這個docker服務內安裝keepalived無法ping通的問題,雖然最後也是莫名其妙就好了,但是加強了不少對docker的理解和還需深入學習的地方。 為什麼要用

LVS-DR+keepalived 搭建web可用負載均衡

lvs-dr+keepalived配置實驗環境 redhat6.5 2.6.32-431.el6.x86_64 keepalived-1.2.16版本ipvsadm-1.26-2.el6.x86_64所有的虛擬機 都 關閉防火墻和selinux 配置好了本地yum源搭建要求是對LVS-DR模式的原理熟

Haproxy + keepalived 可用負載均衡解決方案

haproxy + keepalived文檔作者:amunlinux文檔版本:Version 1.1修改記錄:2017-04-22系統環境:CentOS 6.8 64 bitIP 信息列表: 名稱 IP -----------------------------------VIP 192.1

[轉] Haproxy、Keepalived雙主可用負載均衡

配置過程 virtual dev gnu 文本 tpch margin amp queue http://blog.chinaunix.net/uid-25266990-id-3989321.html 在測試了Nginx+Keepalived的負載均衡後,也對Haprox

公司nginx keepalived tomcat cxf 搭建可用負載均衡實戰系列1- keepalived安裝配置

技術分享 cnblogs start ges idt def auth div .cn 1,ip說明 vip 10.50.13.67 server1 10.50.13.68 server2 10.50.13.140 2

Keepalived+Haproxy可用負載均衡群集

刷新 rfi opened width col vim router 一個 .com 介紹 HAProxy提供高可用性、負載均衡以及基於TCP和HTTP應用的代理,支持虛擬主機,它是免費、快速並且可靠的一種解決方案。HAProxy特別適用於那些負載特大的web站點,

搭建MySQL可用負載均衡集群

分別是 $? 啟動腳本 hang 常見 ase 說明 配置步驟 分享 閱讀目錄1、簡介2、基本環境3、配置MySQL主主復制4、中間件簡述  4.1、Haproxy介紹  4.2、keepalived介紹5、中間件的安裝與配置(haproxy、keepalived)  5.

HAProxy+Varnish+LNMP實現可用負載均衡動靜分離集群部署

else 應用服務器 bash == 開機啟動 多少 heal 啟用 4.0 轉自http://bbs.hfteams.com/forum.php?mod=viewthread&tid=11&extra=page%3D1 HAProxy+Varnish+LN

Nginx+Keeplived+Tomcat搭建可用/負載均衡的web服務器集群

tomcat keepalived nginx 一、集群規劃服務器角色主機名IP地址/VIP軟件Nginx MasterNK120.0.20.101/20.0.20.100Nginx/KeepalivedNginx BackupNK220.0.20.102/20.0.20.100Nginx/Kee

MMM+Amoeba搭建MySQL可用負載均衡群集

模擬 關閉防火墻 同步服務 lan 基礎上 拓撲 編譯安裝mysql 時鐘 命令行 MySQL的主從復制和MySQL的讀寫分離兩者有著緊密聯系,首先要部署主從復制,只有主從復制完成了,才能在此基礎上進行數據的讀寫分離。MySQL的讀寫分離就是只在主服務器上寫,只在從服務器上

docker中部署可用負載均衡前後端專案異常

異常:在基於jdk的docker容器中可以使用jar方式啟動jar檔案,但有時候要終止程式該怎麼做? 當我在宿主機上去殺死對應的容器對映程式時,發現雖然外層宿主機刪除了程序,當容器中還是在執行 當檢視docker容器中nohup.out檔案時總是顯示地址被佔用 測試:ps -ef | g

keepalived+haproxy 可用負載均衡叢集

案例 chkconfig NetworkManager off chkconfig iptables off cat /etc/sysconfig/selinux #例行公事四臺都要這樣selinux為disabled狀態。 #web為配置好的狀態 只有一個頁面。

Centos7.5 配置 Nginx+Keepalived 搭建可用負載均衡

一、系統要求:[[email protected] ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 二、IP 地址規劃:主機名 IP VIP linux-node1 192.168.10.10 192.168.1

Centos7.5 配置 Nginx+Keepalived 搭建可用負載均衡

.rpm pass 創建 綁定 提供服務 網卡 stat -i welcom 一、系統要求:[root@linux-node1 ~]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) 二、IP 地址規

HAProxy+Keepalived 可用負載均衡

link ipad 配置 make type 負載均衡 pro ext figure 轉自 https://www.jianshu.com/p/95cc6e875456 Keepalived+haproxy實現高可用負載均衡 Master 192.168.0

可用負載均衡叢集之 HAProxy 部署

一、HAProxy 簡介     1、HAProxy 是開源、免費、快速並且可靠的一種解決方案,他可以執行在大部分主流的 Linux 伺服器上。     2、HAProxy 適用於負載那些特大的 WEB 站點,而這些站點通常又需要會話保持或者

階段總結——用虛擬機器搭建一個可用負載均衡叢集架構

搭建一個高可用負載均衡叢集架構出來,並執行三個站點,具體需求如下。 ------------------------------------------------------------------------------------------ 基礎: 1 設計你認為合理的架構,用visio把架構圖