1.虛擬IP
在 TCP/IP 的架構下,所有想上網的電腦,不論是用何種方式連上網路,都必須要有一個唯一的 IP-address。事實上IP地址是主機硬件地址的一種抽象,簡單的說,MAC地址是物理地址,IP地址是邏輯地址。
虛擬IP,就是一個未分配給真實主機的IP,也就是說對外提供服務器的主機除了有一個真實IP外還有一個虛IP,使用這兩個IP中的任意一個都可以連接到這台主機。
虛擬IP一般用作達到HA(High Availability)的目的,比如讓所有項目中數據庫鏈接一項配置的都是這個虛IP,當主服務器發生故障無法對外提供服務時,動態將這個虛IP切換到備用服務器。
2.虛擬IP原理
ARP是地址解析協議,它的作用很簡單,將一個IP地址轉換為MAC地址,然后給傳輸層使用。
每台主機中都有一個ARP高速緩存,存儲同一個網絡內的IP地址與MAC地址的對應關 系,以太網中的主機發送數據時會先從這個緩存中查詢目標IP對應的MAC地址,會向這個MAC地址發送數據。操作系統會自動維護這個緩存。
在Linux下可以使用arp命令操作ARP高速緩存。
比如存在物理機A(IP是192.168.192.54 )和物理機器B(IP是192.168.192.40),A作為對外服務的主服務器(比如數據庫主庫),B作為備份機器,兩台服務器之間的通信是通過 Heartbeat,即主服務器會定時的給備份服務器發送數據包,告知主服務器服務正常,當備份服務器在規定時間內沒有收到主服務器的 Heartbeat,就會認為主服務器宕機,則備份服務器就會升級為主服務器。假設物理機A的ARP緩存如下:
另外物理機器B(IP是192.168.192.40)的ARP緩存如下:
當機器B通過BeatHeart得知機器A對外服務質量低於預期的時候(比如發生故障,服務無響應),會將自己的ARP緩存發送出去,讓路由器修改 路由表,告知虛擬地址應該指向我(物理機器B,192.168.192.40),這時候,外界再次訪問虛擬IP的時候,機器B會變成主服務器,而A降級為 備份服務器。這就完成了主從機器的自動切換,這一切對外界是透明的。
用LVS來分析過程
1、VIP(virtual ip):用來提供virtual server服務的ip地址。分別綁定在Director一個物理網卡上(對外接收請求包)和RS的回環設備上(回環設備需要綁定兩個ip,一個是127.0.0.1,另一個就是vip)。
2、DIP(director ip):與vip綁定在一個物理網卡上,用來轉發請求包到RS的RIP對應的mac上,此設備可以通過arp請求獲取RIP對應的mac地址。
3、RIP(real server ip):綁定在RS上的一個物理網卡上,用來接收從Directory轉發過來的請求包。
虛IP。何為虛IP那,就是一個未分配給真實主機的IP,也就是說對外提供數據庫服務器的主機除了有一個真實IP外還有一個虛IP,使用這兩個IP中的 任意一個都可以連接到這台主機,所有項目中數據庫鏈接一項配置的都是這個虛IP,當服務器發生故障無法對外提供服務時,動態將這個虛IP切換到備用主機。
開始我也不明白這是怎么實現的,以為是軟件動態改IP地址,其實不是這樣,其實現原理主要是靠TCP/IP的ARP協議。因為ip地址只是一個邏輯 地址,在以太網中MAC地址才是真正用來進行數據傳輸的物理地址,每台主機中都有一個ARP高速緩存,存儲同一個網絡內的IP地址與MAC地址的對應關 系,以太網中的主機發送數據時會先從這個緩存中查詢目標IP對應的MAC地址,會向這個MAC地址發送數據。操作系統會自動維護這個緩存。這就是整個實現 的關鍵。
下邊就是我電腦上的arp緩存的內容。
(192.168.1.219) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
192.168.1.217、192.168.1.218是兩台真實的電腦,
192.168.1.217 (主)為對外提供數據庫服務的主機。
192.168.1.218 (備)為熱備的機器。
192.168.1.219為虛IP。
大家注意紅字部分,219、217的MAC地址是相同的。
再看看那217宕機后的arp緩存
(192.168.1.219) at 00:21:5A:DB:7F:C2 [ether] on bond0
(192.168.1.217) at 00:21:5A:DB:68:E8 [ether] on bond0
(192.168.1.218) at 00:21:5A:DB:7F:C2 [ether] on bond0
這就是奧妙所在。當218 發現217宕機后會向網絡發送一個ARP數據包,告訴所有主機192.168.1.219這個IP對應的MAC地址是00:21:5A:DB:7F:C2,這樣所有發送到219的數據包都會發送到mac地址為00:21:5A:DB:7F:C2的機器,也就是218的機器。
實例設置虛ip漂移
我們可以通過 Keepalived 來實現這個過程。 Keepalived 是一個基於 VRRP 協議(Virtual Router Redundancy Protocol,即虛擬路由冗余協議)來實現的LVS(負載均衡器)服務高可用方案,可以利用其來避免單點故障。
一個 LVS 服務會有2台服務器運行 Keepalived,一台為主服務器(MASTER),另一台為備份服務器(BACKUP),但是對外表現為一個虛擬IP,主服務器會發送特定的消息給備份服務器,當備份服務器收不到這個消息的時候,即主服務器宕機的時候,備份服務器就會接管虛擬IP,這時就需要根據 VRRP 的優先級來選舉一個 backup 當 master,保證路由器的高可用,繼續提供服務,從而保證了高可用性。
先來准備兩台機器,IP地址如下:
lc1: 172.24.8.101
lc7: 172.24.8.107
我們現在要實現添加一個虛IP:172.24.8.150
,當 lc1
機器正常時,172.24.8.150
指向 lc1
,當 lc1
出現故障時指向 lc7
。
此時通過 ping
可以看到 172.24.8.150
是無法 ping
通的。
在這兩台機器上分別安裝 Keepalived
$ sudo yum install -y keepalived
配置 Keepalived
lc1
的配置
$ cat keepalived.conf vrrp_instance VI_1 { state MASTER interface enp7s0f0 virtual_router_id 51 priority 101 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 172.24.8.150 } }
lc7
的配置
vrrp_instance VI_1 { state MASTER interface enp7s0f0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 123456 } virtual_ipaddress { 172.24.8.150 } }
啟動 lc1 和 lc7 上的 Keepalived 服務
sudo systemctl restart keepalived.service
將 Keepalived 加入開機啟動項
sudo systemctl enable keepalived.service
測試
通過 ping 172.24.8.150
發現已經可以通了。
查看 lc1 的 IP信息
$ ip addr show enp7s0f0 2: enp7s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 6c:92:bf:0d:09:47 brd ff:ff:ff:ff:ff:ff inet 172.24.8.101/24 brd 172.24.8.255 scope global enp7s0f0 valid_lft forever preferred_lft forever inet 172.24.8.150/32 scope global enp7s0f0 valid_lft forever preferred_lft forever inet6 fe80::6e92:bfff:fe0d:947/64 scope link valid_lft forever preferred_lft forever
其中可以看到 inet 172.24.8.150/32 scope global enp7s0f0,說明現在 lc1 是作為虛擬IP的 master 來運行的。
查看 lc7 的 IP信息
$ ip addr show enp7s0f0 2: enp7s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 6c:92:bf:0d:21:49 brd ff:ff:ff:ff:ff:ff inet 172.24.8.107/24 brd 172.24.8.255 scope global enp7s0f0 valid_lft forever preferred_lft forever inet6 fe80::6e92:bfff:fe0d:2149/64 scope link valid_lft forever preferred_lft forever
此時 lc7 中沒有虛擬IP 的信息。
驗證 Failover
我們手動停止 lc1 上的 Keepalived 服務:
sudo systemctl stop keepalived.service
此時 lc1 的 IP信息為:
$ ip addr show enp7s0f0 2: enp7s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 6c:92:bf:0d:09:47 brd ff:ff:ff:ff:ff:ff inet 172.24.8.101/24 brd 172.24.8.255 scope global enp7s0f0 valid_lft forever preferred_lft forever inet6 fe80::6e92:bfff:fe0d:947/64 scope link valid_lft forever preferred_lft forever
可以看到 lc1 已經不在有 虛擬IP 的信息了。
查看 lc7 的 IP信息:
ip addr show enp7s0f0 2: enp7s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 6c:92:bf:0d:21:49 brd ff:ff:ff:ff:ff:ff inet 172.24.8.107/24 brd 172.24.8.255 scope global enp7s0f0 valid_lft forever preferred_lft forever inet 172.24.8.150/32 scope global enp7s0f0 valid_lft forever preferred_lft forever inet6 fe80::6e92:bfff:fe0d:2149/64 scope link valid_lft forever preferred_lft forever
可以看到 lc7
的 IP信息中 已經有虛擬IP 172.24.8.150
的信息了。
此時如果再把 lc1
上的 Keepalived 啟動,可以看到 虛擬IP 又重新綁定到了 lc1
上。