[高度な運用保守知識] クラスター アーキテクチャ - Nginx 高可用性キープアライブ

高可用性とは、2 台のマシンがまったく同じ業務システムを起動することを意味し、1 台のマシンがダウンしても、ユーザーが気付かないうちにもう 1 台をすぐに起動できることを意味します。高可用性ハードウェアは通常 F5 を使用し、ソフトウェアは通常キープアライブを使用します。keepalived ソフトウェアは、主に単一障害点を解決するために使用される VRRP プロトコル (VRRP 仮想ルーティング冗長プロトコル) に基づいて実装されています。

目次

VRRP実装原理

Keepalived のコアコンセプト

キープアライブのインストール構成

キープアライブのプリエンプティブおよび非プリエンプティブ

キープアライブのグリッチ スプリット ブレイン

1. 失敗の一般的な原因

2. スプリットブレイン故障テスト

3. スプリットブレイン問題の解決策

キープアライブとNginx

1. スクリプトの作成と権限の追加

2. スクリプトのテスト

3. 設定ファイルでこのスクリプトを呼び出します。


VRRP実装原理

会社のルーターを例に挙げると、ルーターに障害が発生すると、ゲートウェイがパケットを転送できなくなり、全員がインターネットにアクセスできなくなります。

通常はルーターを追加することになりますが、メインルーターが故障した場合、ユーザーは手動でバックアップルーターを指定する必要があり、ユーザー数が多い場合、変更するのは非常に面倒です。また、メインルーターが修理された後は、メイン ルータは使用されません。メイン ルータに障害が発生した後、バックアップ ルータのゲートウェイ構成をメイン ルータに変更できますか? 多くの問題が関係しています。

実は、単にゲートウェイの設定を変更しただけでは機能せず、PC は初めて ARP ブロードキャストを通じてメインルータの MAC アドレスと IP アドレスを見つけ、その情報を ARP キャッシュ テーブルに書き込みます。接続では、キャッシュテーブル情報に基づいて接続され、データパケットが転送されます。IPを変更しても、Macアドレスは一意であり、PCのデータパケットはメインルータに送信されます(そうでない場合)。 PC の ARP キャッシュ テーブルの有効期限が切れた場合、ARP ブロードキャストが再度開始された場合にのみ、新しいバックアップ ルータの MAC アドレスと IP アドレスを取得できます)

次に、仮想 MAC アドレス (VMAC) と仮想 IP アドレス (VIP) を、ソフトウェアまたはハードウェアを介してメイン ルータとセカンダリ ルータの外部に追加する VRRP が必要になります。この場合、PC が VIP を要求したときに、それが処理されるかどうかに関係なく、メイン ルータまたはバックアップ ルータの場合、PC は ARP キャッシュ テーブルに VMAC および VIP 情報のみを記録します。

Keepalived のコアコンセプト

Keepalived をマスターする前に、その中心となる概念を理解する必要があります。

1. 誰がマスター ノードで誰がバックアップ ノードであるかを決定する方法 (選挙投票と同様に、より効率的で高速な方が使用されます。手動による介入が優先されます)

2. マスター ノードに障害が発生した場合、バックアップ ノードが自動的に引き継ぎます。マスター ノードが回復すると、マスターノードがプリエンプティブな方法で自動的に引き継ぎます。これは、電源を掌握するのと同様ですプリエンプティブな方法の代わりに、マスター ノードは、回復しても自動的には引き継がれません。

3. マスター ノードとバックアップ ノードはグループ内にあり、マスター ノードが正常な場合は、1 秒に 1 回ハートビートをグループに送信します (時間はカスタマイズ可能)。プライマリ ノードもバックアップ ノードもハートビートを送信しない場合、両方のサーバーが自分たちがプライマリ ノードであると認識し、スプリット ブレインが発生します

キープアライブのインストール構成

1. LB01 (10.0.0.5) と LB02 (10.0.0.6) の 2 つの仮想ホストを用意します。

2. 両方のホストに keepalived をインストールします。

[root@LB01 ~]# yum -y install keepalived

[root@LB02 ~]# yum -y install keepalived

3.LB01の設定

[root@LB01 ~]# rpm -qc keepalived    #查询keepalived的配置文件
/etc/keepalived/keepalived.conf
/etc/sysconfig/keepalived
[root@LB01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {                   #全局配置
    router_id LB01              #标识身份->名称
}

vrrp_instance VI_1 {
    state MASTER                #标识角色状态
    interface eth0              #网卡绑定接口
    virtual_router_id 50        #虚拟路由id
    priority 150                #优先级
    advert_int 1                #监测间隔时间
    authentication {            #认证
        auth_type PASS          #认证方式
        auth_pass 1111          #认证密码
    }
    virtual_ipaddress {         
        10.0.0.3                #虚拟的VIP地址
    }
}

4.LB02の設定

[root@LB02 ~]# cat /etc/keepalived/keepalived.conf global_defs {
    router_id LB02            #与主结点区别1:唯一标识
}

vrrp_instance VI_1 {
    state BACKUP              #与主节点区别2:角色状态   
    interface eth0
    virtual_router_id 50
    priority 100              #与主节点区别3:竞选优先级
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}

5. 両方のノードでキープアライブを開始します。

[root@LB01 ~]# systemctl start keepalived
[root@LB01 ~]# systemctl enable keepalived

[root@LB02 ~]# systemctl start keepalived
[root@LB02 ~]# systemctl enable keepalived

キープアライブテストのプリエンプティブおよび非プリエンプティブ

1. LB01 の優先度は LB02 よりも高いため、VIP は LB01 よりも上位になります

[root@LB01 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

2. LB01 のキープアライブをオフにすると、LB02 が自動的に引き継ぐことがわかります。

[root@LB01 ~]# systemctl stop keepalived
[root@LB01 ~]# ip add | grep 10.0.0.3

[root@LB02 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

3. LB01 のキープアライブを再起動すると、VIP が強制的に捕捉されたことがわかります。

[root@LB01 ~]# systemctl start keepalived
[root@LB01 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

[root@LB02 ~]# ip add | grep 10.0.0.3

4. 非プリエンプティブの構成

両方のノードの状態は BACKUP として設定され、両方のノードで nopreempt が設定されている必要があり、一方のノードの優先順位は他方のノードの優先順位よりも高くなければなりません。

[root@LB01 ~]# cat /etc/keepalived/keepalived.conf
global_defs {                   #全局配置
    router_id LB01              #标识身份->名称
}

vrrp_instance VI_1 {
    state BACKUP                #标识角色状态
    nopreempt
    interface eth0              #网卡绑定接口
    virtual_router_id 50        #虚拟路由id
    priority 150                #优先级
    advert_int 1                #监测间隔时间
    authentication {            #认证
        auth_type PASS          #认证方式
        auth_pass 1111          #认证密码
    }
    virtual_ipaddress {         
        10.0.0.3                #虚拟的VIP地址
    }
}
[root@LB01 ~]# systemctl restart keepalived

[root@LB02 ~]# cat /etc/keepalived/keepalived.conf
global_defs {
    router_id LB02
}

vrrp_instance VI_1 {
    state BACKUP
    nopreempt        
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}
[root@LB02 ~]# systemctl restart keepalived

5. Windows arp を使用して、MAC アドレスが切り替わるかどうかを確認します。

[root@LB01 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

Windows ローカルホストは 10.0.0.3 に設定され、ブラウザは blog.koten.com にアクセスします (Web01 のドメイン名には LB01 が割り当てられます)。

WIN+R で実行ウィンドウを呼び出し、「cmd」と入力してコマンド プロンプト arp -a を開き、arp キャッシュ領域を確認します。この時点で、物理アドレスは LB01 の 10.0.0.3 MAC アドレスと一致しています。

ノード 1 のキープアライブを停止します

[root@LB01 ~]# systemctl stop keepalived

ノード 2 が VIP を引き継ぎます

[root@LB02 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

 再度 MAC アドレスを確認すると、この時点で物理アドレスは LB02 の MAC アドレス 10.0.0.3 と一致しています。

キープアライブのグリッチ スプリット ブレイン

何らかの理由で、2 つのキープアライブ サーバーは指定された時間内に互いのハートビートを検出できませんでしたが、両方のサーバーは正常に使用できました。

1. 失敗の一般的な原因

1. サーバーネットワークケーブルの緩みなどのネットワーク障害

2. サーバーのハードウェア障害により損傷やクラッシュが発生する

3. firewalld ファイアウォールは、アクティブ デバイスとスタンバイ デバイスの両方で有効になります。

2. スプリットブレイン故障テスト

1. プライマリ ホストとバックアップ ホストの両方のファイアウォールをオンにします。

[root@LB01 ~]# systemctl start firewalld
[root@LB02 ~]# systemctl start firewalld

2. 作成した構成ファイルを元に戻します。

[root@LB01 ~]# vim /etc/keepalived/keepalived.conf  
global_defs {
    router_id LB01
}

vrrp_instance VI_1 {
    state MASTER
    #nopreempt
    interface eth0
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}
[root@LB01 ~]# systemctl restart keepalived

[root@LB02 ~]# cat /etc/keepalived/keepalived.conf  
global_defs {
    router_id LB02
}

vrrp_instance VI_1 {
    state BACKUP
    #nopreempt        
    interface eth0
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {    
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.0.0.3
    }
}
[root@LB02 ~]# systemctl restart keepalived

3. パケットをキャプチャして情報を表示する

4. LB01 と LB02 の IP を確認し、両方とも 10.0.0.3 であることを確認します。

[root@LB01 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

[root@LB02 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

3. スプリットブレイン問題の解決策

解決策: スプリット ブレインが発生した場合、どちらかをカジュアルに殺すことができます。スクリプトを作成できます。両側の ip add が 10.0.0.3 である場合、スプリット ブレインが発生していると考えられます。LB01上でスクリプトを書きます。

キーを使用せずに LB02 の IP 情報を取得する方が簡単です。

[root@LB01 ~]# ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+NyOCiY7aBX8nEPwGeNQHjTLY2EXPKU1o33LTBrm1zk root@LB01
The key's randomart image is:
+---[RSA 2048]----+
|    oB.oo=       |
|   o+o*o= o      |
|  . =*+o.+ o     |
|   o.=..o B o .  |
|    = o So = E   |
|   . = o ..   .  |
| .o o . o .      |
|...+ .   o       |
|. ..  ... .      |
+----[SHA256]-----+
[root@LB01 ~]# 
[root@LB01 ~]# ssh-copy-id -i .ssh/id_rsa 10.0.0.6
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: ".ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh '10.0.0.6'"
and check to make sure that only the key(s) you wanted were added.

[root@LB01 ~]# ssh '10.0.0.6' ip add | grep 10.0.0.3 | wc -l    #免密钥测试
1

作成および実行されたスクリプト:

[root@LB01 ~]# cat check_split_brain.sh
LB01_VIP_Number=`ip add | grep 10.0.0.3 | wc -l`
LB02_VIP_Number=`ssh '10.0.0.6' ip add | grep 10.0.0.3 | wc -l`
if [ $LB01_VIP_Number -eq 1 -a $LB02_VIP_Number -eq 1 ]
then
	systemctl stop keepalived
fi	
[root@LB01 ~]# sh check_split_brain.sh

[root@LB01 ~]# ip add | grep 10.0.0.3

[root@LB02 ~]# ip add | grep 10.0.0.3
    inet 10.0.0.3/32 scope global eth0

キープアライブとNginx

Nginx はデフォルトですべての IP アドレスを監視します。VIP はノードにフローティングされます。これは、Nginx が追加の VIP ネットワーク カードを備えているのと同じなので、Nginx が配置されているマシンにアクセスできます。ただし、Nginx がダウンすると、ユーザーのリクエストは失敗しますが、 keepalived ハングアップしない場合は切り替わらない Nginx の生存状態を検出するスクリプトを書く必要がある 生存していない場合は keepalived を強制終了し、自動的に VIP をバックアップサーバーにフロートさせます。

1. スクリプトの作成と権限の追加

[root@LB01 ~]# cat check_nginx.sh
nginxpid=`ps -C nginx --no-header|wc -l`
if [ $nginxpid -eq 0 ]
then
	systemctl restart nginx &>/etc/null
	if [ $? -ne 0 ]
	then
		systemctl stop keepalived
	fi
fi
	
[root@LB01 ~]# chmod +x check_nginx.sh
[root@LB01 ~]# ll check_nginx.sh
-rwxr-xr-x 1 root root 150 Apr 12 17:37 check_nginx.sh

2. スクリプトのテスト

[root@LB02 ~]# ip add|grep 10.0.0.3            #当前VIP不在LB02

[root@LB01 ~]# ip add|grep 10.0.0.3            #当前VIP在LB01上
    inet 10.0.0.3/32 scope global eth0
[root@LB01 ~]# systemctl stop nginx            #关闭Nginx
[root@LB01 ~]# ip add|grep 10.0.0.3            #VIP依旧在LB0上,因为Nginx对keepalived没有影响
    inet 10.0.0.3/32 scope global eth0
[root@LB01 ~]# vim /etc/nginx/nginx.conf       #修改Nginx配置文件,让其无法重启,查看是否会飘到LB02上

ser  nginx;

[root@LB01 ~]# sh check_nginx.sh               #执行脚本
[root@LB01 ~]# ip add|grep 10.0.0.3            #发现VIP已经不在LB02了

[root@LB02 ~]# ip add | grep 10.0.0.3          #VIP飘移到LB02上了
    inet 10.0.0.3/32 scope global eth0

3. 設定ファイルでこのスクリプトを呼び出します。

[root@LB01 ~]# cat /etc/keepalived/keepalived.conf 
global_defs {        
    router_id LB01  
}

#每5秒执行一次脚本,脚本执行内容不能超过5秒,否则会中断再次重新执行脚本
vrrp_script check_nginx {
    script "/root/check_nginx.sh"
    interval 5
}

vrrp_instance VI_1 {
    state MASTER
    #nopreempt
    interface eth0
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {         
        10.0.0.3
    }
    #调用并运行脚本
    track_script {
    	check_nginx
    }
}

注意:在Master的keepalived中调用脚本,抢占式,仅需在Master配置即可。如果配置为非抢占式,那么需要两台服务器都使用该脚本。

私の名前はKotenです。運用保守の経験は10年あります。運用保守のヒントを共有し続けています。読んで注目していただき、ありがとうございます!

おすすめ

転載: blog.csdn.net/qq_37510195/article/details/130107361