Docker 安裝 Keepalived + Nginx 並實現高可用

Docker 安裝 Keepalived + Nginx 並實現高可用


需求目標:基於 Centos 鏡像安裝 Keepalived + Nginx 並實現高可用

準備工作

下載 centos 鏡像並配置環境

$ docker pull centos # 拉取最新 centos
$ docker images # 查看鏡像
$ docker run -itd --name centos centos # 後臺啓動一個容器
$ docker exec -it centos bash # 進入容器
$ yum -y upgrade # 升級所有包 
$ yum install -y yum-utils vim make wget gcc openssl openssl-devel popt-devel # 安裝相關依賴

下載安裝 Nginx

配置 yum 源

官方參考文檔 http://nginx.org/en/linux_packages.html

$ cat /etc/yum.repos.d/nginx.repo

[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
$ yum install -y nginx # 安裝 Nginx
$ whereis nginx # 查看安裝路徑,默認配置文件在 /etc/nginx
$ nginx -t # 插件配置
$ nginx # 啓動
$ curl localhost # 檢查啓動是否成功

下載安裝 Keepalived

Keepalived 官網 下載最新版本

$ mkdir -p /mnt/software && cd /mnt/software 
$ wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz
$ docker cp keepalived-2.0.20.tar.gz centos:/mnt/ # 下載慢!!也可以從本地 copy
$ tar -zxvf keepalived-2.0.20.tar.gz 

編譯安裝

$ cd keepalived-2.0.20
$ ./configure --prefix=/usr/local/keepalived

編譯完後可能會出現以下警告

*** WARNING - this build will not support IPVS with IPv6. Please install libnl/libnl-3 dev libraries to support IPv6 with IPVS.

按照提示按照

$ yum -y install libnl libnl-devel
No match for argument: libnl
No match for argument: libnl-devel
Error: Unable to find a match: libnl libnl-devel

what 沒有匹配的軟件源? 我們只需要用到 VRRP 功能,只要確保 Use VRRP Framework 、Use VRRP VMAC、Use VRRP authentication 爲 Yes 即可,當然也可以單獨找 RPM 來安裝 libnl 。

https://centos.pkgs.org/7/centos-x86_64/libnl-1.1.4-3.el7.x86_64.rpm.html

$ wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libnl-1.1.4-3.el7.x86_64.rpm
$ wget http://mirror.centos.org/centos/7/os/x86_64/Packages/libnl-devel-1.1.4-3.el7.x86_64.rpm
$ rpm -ivh libnl-1.1.4-3.el7.x86_64.rpm
$ rpm -ivh libnl-devel-1.1.4-3.el7.x86_64.rpm
$ ./configure --prefix=/usr/local/keepalived
$ make && make install

配置 Keepalived

$ cp /mnt/software/keepalived-2.0.20/keepalived/etc/init.d/keepalived /etc/init.d/
$ cp /mnt/software/keepalived-2.0.20/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
$ cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
$ mkdir -p /etc/keepalived
$ cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
$ chmod +x /etc/init.d/keepalived
$ ip address # 本機 ip 172.17.0.2 網卡 eth0
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
    link/tunnel6 :: brd ::
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

默認將 Keepalived 配置文件放在 /etc/keepalived/keepalived.conf

! Configuration File for keepalived

global_defs {
	 # 負載均衡標識,在局域網內應該是唯一的
   router_id LVS_DEVEL
   enable_script_security
   # 建議新建用戶來執行腳本
   script_user root
}

vrrp_script chk_nginx {
    script "/etc/keepalived/check.sh"
    # 每2秒檢測一次nginx的運行狀態
    interval 2 
    # 失敗一次,將自己的優先級調整爲-5
    weight -5
    # require 2 failures for KO
    fall 2
    # require 2 successes for OK
    rise 2
}

vrrp_instance VI_1 {
    # 標示狀態爲 MASTER 備份機爲 BACKUP
    state MASTER
    # 設置實例綁定的網卡
    interface eth0
    # 同一實例下 virtual_router_id 必須相同
    virtual_router_id 51
    # MASTER 權重要高於 BACKUP 比如 BACKUP 爲99
    priority 100
    # MASTER 與 BACKUP 負載均衡器之間同步檢查的時間間隔,單位是秒
    advert_int 1 
    # 設置認證
    authentication { 
    		# 主從服務器驗證方式
        auth_type PASS
        auth_pass 1111
    }
    # 虛擬IP,兩個節點設置必須一致,可以設置多個
    virtual_ipaddress { 
        172.17.0.200
        172.17.0.210
    }
    track_script {
       chk_nginx
    }
}
$ cd /etc/keepalived
$ touch check.sh
$ chmod +x check.sh

check.sh 腳本內容如下

#!/bin/bash
Nginx=`ps -ef | grep nginx | grep -v grep | wc -l`
echo 'nginx status ' $Nginx
if [ $Nginx -eq 0 ]
then
    echo 'nginx shutdown...'
    nginx
    echo 'start nginx ...'
    sleep 2
    if [ `ps -ef | grep nginx | grep -v grep | wc -l` -eq 0 ]
    then
				ps -ef | grep keepalived | grep -v grep | awk '{print $2}' | xargs kill -9
				echo 'kill keepalived...'
    else
	echo 'nginx started...'
    fi
fi
echo 'script end...'

腳本作用:當 nginx 進程不存在時,會自動重啓 nginx 服務 ,休眠 2 秒再次檢查 nginx 進程,如果不存在就停止 keepalived 服務

測試腳本:

$ ps ax|grep nginx
   40 pts/1    S+     0:00 grep --color=auto nginx
$ ./check.sh
nginx status  0
nginx shutdown...
start nginx ...
nginx started...
script end...
$ ps ax|grep nginx
   48 ?        Ss     0:00 nginx: master process nginx
   49 ?        S      0:00 nginx: worker process
   57 pts/1    S+     0:00 grep --color=auto nginx

檢查配置

$ keepalived -t

至此,Keepalived 以及 Nginx 都配置完成。

測試

容器創建快照

$ docker ps -a | grep centos
ace32d2fa597 centos "/bin/bash" About an hour ago Up About an hour  centos
$ docker commit ace32d2fa597 centos_keepalived_nginx:0.0.1 # 創建該容器的快照
$ docker images | grep centos_keepalived_nginx
centos_keepalived_nginx   0.0.1               801e75c18232        51 seconds ago      569MB

創建主從容器

根據快照創建主從容器

$ docker run --privileged -itd -p 6698:80 --name keepalived_master --hostname keepalived_master centos_keepalived_nginx:0.0.1 /usr/sbin/init
$ docker run --privileged -itd -p 6699:80 --name  keepalived_slave --hostname keepalived_slave centos_keepalived_nginx:0.0.1 /usr/sbin/init

進入 maser 容器修改配置

$ docker exec -it keepalived_master bash # 進入 master 容器
$ vi /usr/share/nginx/html/index.html # 任意修改一點內容與 slave 做區分
$ nginx
$ curl localhoast

進入 slave 容器修改配置

$ docker exec -it keepalived_master bash # 進入 master 容器
$ vi /usr/share/nginx/html/index.html # 任意修改一點內容與 slave 做區分
$ nginx
$ curl localhoast

測試 Keepalived

啓動 master 容器中的 keepalived

$ docker exec -it keepalived_master bash
$ keepalived
$ curl 172.17.0.200 # curl 172.17.0.210
$ ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN group default qlen 1000
    link/tunnel6 :: brd ::
36: eth0@if37: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.17.0.200/32 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.17.0.210/32 scope global eth0
       valid_lft forever preferred_lft forever

啓動 slave 容器中的 keepalived

$ docker exec -it keepalived_slave bash
$ vi /etc/keepalived/keepalived.conf # state 改爲 BACKUP priority 改爲 小於 100 的任意值 比如 99
$ keepalived
$ curl 172.17.0.200 # curl 172.17.0.210

總結:

  • 你會發現訪問 172.17.0.200 以及 172.17.0.210 都是訪問到 maser 容器上的內容

  • 如果關閉 master 上的 keepalived,就會自動切換訪問到 slave 容器上的內容

  • 當 nginx 進程不存在時嘗試重新啓動 nginx,如果 nginx 啓動失敗就關閉 keepalived 服務並實現自動切換

遺留問題:

  • Docker 中設置的虛擬 IP,如何讓外網訪問,如何做映射呢?Docker 研究得不深入,請多多指教。
  • check.sh 腳本檢查 Nginx 服務時有時間返回 0 有時候返回 2 (Nginx 服務都是關閉的狀態),但使用 touch 新建一個文件又沒有問題!!! 這是爲何呢?

歡迎一起交流…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章