高可用性とは、2 台のマシンがまったく同じ業務システムを起動することを意味し、1 台のマシンがダウンしても、ユーザーが気付かないうちにもう 1 台をすぐに起動できることを意味します。高可用性ハードウェアは通常 F5 を使用し、ソフトウェアは通常キープアライブを使用します。keepalived ソフトウェアは、主に単一障害点を解決するために使用される VRRP プロトコル (VRRP 仮想ルーティング冗長プロトコル) に基づいて実装されています。
目次
キープアライブのプリエンプティブおよび非プリエンプティブ
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年あります。運用保守のヒントを共有し続けています。読んで注目していただき、ありがとうございます!