企業實戰(13)LVS負載均衡NAT(網絡地址轉換)模式實戰詳解(一)

什麼是集羣

  • 一組通過高速網絡互連的計算組,並以單一系統的模式加以管理。
  • 將很多服務器集中起來一起,提供同一種服務,在客戶端看起來就像是隻有一個服務器。
  • 可以在付出較低成本的情況下獲得在性能、可靠性、靈活性方面的相對較高的收益。
  • 任務調度是集羣系統中的核心技術。

集羣分類

  • 高性能計算集羣HPC
     -通過以集羣開發的並行應用程序,解決 複雜的科學問題

  • 負載均衡(LB)集羣
     -客戶端負載在計算機集羣中儘可能平均分攤

  • 高可用(HA)集羣
     -避免單點故障,當一個系統發生故障時,可以快速遷移

負載均衡類型

- DNS 實現負載均衡

 DNS 實現負載均衡是最基礎簡單的方式。一個域名通過 DNS 解析到多個 IP,每個 IP 對應不同的服務器實例,這樣就完成了流量的調度,雖然沒有使用常規的負載均衡器,但也的確完成了簡單負載均衡的功能。

- 硬件負載均衡

 硬件負載均衡是通過專門的硬件設備來實現負載均衡功能,類似於交換機、路由器,是一個負載均衡專用的網絡設備。目前業界典型的硬件負載均衡設備有兩款:F5 和 A10。這類設備性能強勁、功能強大,但價格非常昂貴,一般只有 “土豪” 公司纔會使用此類設備,普通業務量級的公司一般負擔不起,二是業務量沒那麼大,用這些設備也是浪費。

- 軟件負載均衡

 軟件負載均衡,可以在普通的服務器上運行負載均衡軟件,實現負載均衡功能。目前常見的有 Nginx、HAproxy、LVS。
 區別:
  -Nginx :是 7 層負載均衡,支持 HTTP、E-mail 協議,貌似也支持 4 層負載均衡了。
  -HAproxy :是 7 層負載均衡軟件,支持 7 層規則的設置,性能也很不錯。OpenStack 默認使用的負載均衡軟件就是 HAproxy
  -LVS :是純 4 層的負載均衡,運行在內核態,性能是軟件負載均衡中最高的,因爲是在四層,所以也更通用一些。

負載均衡LVS簡介

 LB集羣的架構和原理很簡單,就是當用戶的請求過來時,會直接分發到Director Server上,然後它把用戶的請求根據設置好的調度算法,智能均衡地分發到後端真正服務器(real server)上。爲了避免不同機器上用戶請求得到的數據不一樣,需要用到了共享存儲,這樣保證所有用戶請求的數據是一樣的。

 LVS是 Linux Virtual Server 的簡稱,也就是Linux虛擬服務器。這是一個由章文嵩博士發起的一個開源項目, 現在 LVS 已經是 Linux 內核標準的一部分。使用 LVS 可以達到的技術目標是:通過 LVS 達到的負載均衡技術和 Linux 操作系統實現一個高性能高可用的 Linux 服務器集羣,它具有良好的可靠性、可擴展性和可操作性。從而以低廉的成本實現最優的性能。LVS 是一個實現負載均衡集羣的開源軟件項目,LVS架構從邏輯上可分爲調度層、Server集羣層和共享存儲。

LVS的基本工作原理

在這裏插入圖片描述
 1.當用戶向負載均衡調度器(Director Server)發起請求,調度器將請求發往至內核空間

 2.PREROUTING鏈首先會接收到用戶請求,判斷目標IP確定是本機IP,將數據包發往INPUT鏈

  3.IPVS是工作在INPUT鏈上的,當用戶請求到達INPUT時,IPVS會將用戶請求和自己已定義好的集羣服務進行比對,如果用戶請求的就是定義的集羣服務,那麼此時IPVS會強行修改數據包裏的目標IP地址及端口,並將新的數據包發往POSTROUTING鏈

 4.POSTROUTING鏈接收數據包後發現目標IP地址剛好是自己的後端服務器,那麼此時通過選路,將數據包最終發送給後端的服務器

LVS負載均衡調度算法

  • LVS目前實現了10種調度算法
  • 常用調度算法有4種
     -輪詢
      -將客戶端請求平均分發到Real Server
     -加權輪詢
      -根據Real Server權重值進行輪詢調度
     -最少連接
      -選擇連接數最少的服務器
     -加權最少連接
      -根據Real Server權重值,選擇連接數最少的服務器
     -源地址散列
      -根據請求的目標IP地址,作爲散列鍵(Hash Key)從靜態分配的散列表找出對應的服務器

LVS集羣組成

- 前端:負載均衡層
  -由一臺或多臺負載調度器構成

- 中間:服務器羣組層
  -由一組實際運行應用服務的服務器組成

- 底端:數據共享存儲層
  -提供共享存儲空間的存儲區域

相關術語

DS Director Server。指的是前端負載均衡器節點。

RS Real Server。後端真實的工作服務器。

CIP Client IP,表示的是客戶端 IP 地址。

VIP Virtual IP,表示負載均衡對外提供訪問的 IP 地址,一般負載均衡 IP 都會通過 Virtual IP 實現高可用。

RIP RealServer IP,表示負載均衡後端的真實服務器 IP 地址。

DIP Director IP,表示負載均衡與後端服務器通信的 IP 地址。

LVS工作模式

LVS/NAT:網絡地址轉換

 -通過網絡地址轉換實現的虛擬服務器

 -大併發訪問時,調度器的性能成爲瓶頸

-LVS/DR:直接路由

 -直接使用路由技術實現虛擬服務器

 -節點服務器需要配置VIP,注意MAC地址廣播

-LVS/TUN:IP隧道

 -通過隧道方式實現虛擬服務器

LVS各工作模式原理

 更詳細原理可參考博客:https://blog.csdn.net/liwei0526vip/article/details/103104483

1.網絡地址轉換(LVS-NAT)
在這裏插入圖片描述

1.當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP 。

2.PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈

3.IPVS比對數據包請求的服務是否爲集羣服務,若是,修改數據包的目標IP地址爲後端服務器IP,然後將數據包發至POSTROUTING鏈。 此時報文的源IP爲CIP,目標IP爲RIP 4.POSTROUTING鏈通過選路,將數據包發送給Real Server

5.Real Server比對發現目標爲自己的IP,開始構建響應報文發回給Director Server。 此時報文的源IP爲RIP,目標IP爲CIP

6.Director Server在響應客戶端前,此時會將源IP地址修改爲自己的VIP地址,然後響應給客戶端。 此時報文的源IP爲VIP,目標IP爲CIP

2.直接路由(LVS-DR)
在這裏插入圖片描述

1.當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP 。

2.PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈

3.IPVS比對數據包請求的服務是否爲集羣服務,若是則將請求報文中的源MAC地址[CIP]修改爲DIP的MAC地址,將目標MAC地址[VIP]修改RIP的MAC地址,然後將數據包發至POSTROUTING鏈[LVS]。 此時的源IP和目的IP均未修改,僅修改了源MAC地址爲DIP的MAC地址,目標MAC地址爲RIP的MAC地址

4.由於DS和RS在同一個網絡中,所以是通過二層來傳輸。POSTROUTING鏈檢查目標MAC地址爲RIP的MAC地址[ARP廣播],那麼此時數據包將會發至Real Server。

5.RS發現請求報文的MAC地址是自己的MAC地址,就接收此報文。處理完成之後,將響應報文通過自己的lo接口傳送給eth0網卡然後向外發出[ARP廣播]。此時的源IP地址爲VIP,目標IP爲CIP.         

注意:
 如果沒有給RS設置外網IP,RS將ARP廣播查找CIP,內網沒有就提交給網關,網關直接外網發送出去,會有可能提高網關壓力
 
6.響應報文最終送達至客戶端

特點: 多了一個Mac地址,作用是讓真實服務器可以找到客戶端,直接發送響應報文,並且整個過程的客戶端IP(CIP)和負載均衡器的IP都沒有改變,只是Mac地址變了,目的是讓客戶端知道,你發送請求的報文,和響應你報文的是一個人。

3.IP隧道(LVS-TUN)
在這裏插入圖片描述

1.當用戶請求到達Director Server,此時請求的數據報文會先到內核空間的PREROUTING鏈。 此時報文的源IP爲CIP,目標IP爲VIP 。

2.PREROUTING檢查發現數據包的目標IP是本機,將數據包送至INPUT鏈

3.IPVS比對數據包請求的服務是否爲集羣服務,若是,在請求報文的首部再次封裝一層IP報文,封裝源IP爲爲DIP,目標IP爲RIP。然後發至POSTROUTING鏈。 此時源IP爲DIP,目標IP爲RIP ④、POSTROUTING鏈根據最新封裝的IP報文,將數據包發至RS(因爲在外層封裝多了一層IP首部,所以可以理解爲此時通過隧道傳輸)。 此時源IP爲DIP,目標IP爲RIP

4.RS接收到報文後發現是自己的IP地址,就將報文接收下來,拆除掉最外層的IP後,會發現裏面還有一層IP首部,而且目標是自己的lo接口VIP,那麼此時RS開始處理此請求,處理完成之後,通過lo接口送給eth0網卡,然後向外傳遞。 此時的源IP地址爲VIP,目標IP爲CIP

5.響應報文最終送達至客戶端

三種工作模式比較

在這裏插入圖片描述

ipvsadm命令選項

  ipvsadm -A   創建虛擬服務器
  ipvsadm -E   修改虛擬服務器
  ipvsadm -D   刪除虛擬服務器

  ipvsadm -t   設置集羣地址(VIP,Virtual IP)
  ipvsadm -s   指定集羣算法     ----> rr(輪詢)、wrr(加權輪詢)、lc(最少連接)、wlc(加權最少連接)、sh(ip_hash)
        
  ipvsadm -a   添加真實服務器
  ipvsadm -e   修改真實服務器
  ipvsadm -d   刪除真實服務器

  ipvsadm -r   指定真實服務器的地址
  ipvsadm -w   爲節點服務器設置權重,默認爲1

  ipvsadm -C   清空所有
  ipvsadm -L   查看LVS規則表   ---> 一般跟n一起用,以數字形式輸出(-Ln)
        
  ipvsadm -m   使用NAT模式
  ipvsadm -g   使用DR模式
  ipvsadm -i   使用TUN模式

LVS-NAT模式實戰

NAT模式特性

RS應該使用私有地址,RS的網關必須指向DIP(調度器IP)
DIP和RIP必須在同一個網段內,
請求和響應報文都需要經過Director Server,高負載場景中,Director Server易成爲性能瓶頸
支持端口映射
RS可以使用任意操作系統
缺陷:對Director Server壓力會比較大,請求和響應都需經過director server

環境介紹

客戶端:192.168.4.132 (4網段充當外網)

負載均衡服務器: ens37:192.168.4.133 (4網段充當外網) ens33:192.168.2.130(test3)

後端服務器1:192.168.2.128(localhost)網關:192.168.2.130

後端服務器2:192.168.2.129(test2)網關:192.168.2.130

內核版本:3.10.0-862.el7.x86_64

系統版本:CentOS 7.5

注意:

 1.兩臺後端服務器必須配置網關地址,且網關地址都要指定爲調度服務器的內網地址。(即:192.168.2.130)

2.LVS無論NAT及DR模式,均要求LVS server(調度器)和Real server在同一個網段內,NAT需要把LVS server(調度器)當作各個Real server的默認網關,

一、基礎環境配置

1.兩臺後端服務器128/129分別安裝Nginx

[root@localhost ~]# wget http://nginx.org/download/nginx-1.16.1.tar.gz

[root@localhost ~]# yum -y install gcc pcre-devel openssl-devel

[root@localhost ~]# useradd -s /sbin/nologin nginx   //創建禁止登陸解釋器的用戶(爲了安全)

[root@localhost ~]# id nginx
uid=1001(nginx) gid=1001(nginx) 組=1001(nginx)

[root@localhost ~]# tar -xf nginx-1.16.1.tar.gz

[root@localhost ~]# cd nginx-1.16.1

[root@localhost nginx-1.16.1]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

         --prefix=/usr/local/nginx                   //指定安裝路徑
         --user=nginx                               //指定用戶
         --group=nginx                              //指定組
         --with-http_ssl_module                    //安裝ssl模塊,開啓其中的SSL加密功能(需要什麼模塊就安裝什麼模塊)
  ......
  ......
  nginx modules path: "/usr/local/nginx/modules"
  nginx configuration prefix: "/usr/local/nginx/conf"
  nginx configuration file: "/usr/local/nginx/conf/nginx.conf"
  nginx pid file: "/usr/local/nginx/logs/nginx.pid"
  nginx error log file: "/usr/local/nginx/logs/error.log"
  nginx http access log file: "/usr/local/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

[root@localhost nginx-1.16.1]#  make && make install    //編譯並且安裝
......
	'/usr/local/nginx/conf/scgi_params.default'
test -f '/usr/local/nginx/conf/nginx.conf' \
	|| cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf'
cp conf/nginx.conf '/usr/local/nginx/conf/nginx.conf.default'
test -d '/usr/local/nginx/logs' \
	|| mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/logs' \
	|| mkdir -p '/usr/local/nginx/logs'
test -d '/usr/local/nginx/html' \
	|| cp -R html '/usr/local/nginx'
test -d '/usr/local/nginx/logs' \
	|| mkdir -p '/usr/local/nginx/logs'
make[1]: 離開目錄“/root/nginx-1.16.1”

[root@localhost ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

[root@test2 ~]# /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.16.1
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-39) (GCC)
built with OpenSSL 1.0.2k-fips  26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_ssl_module

2.創建測試頁面

[root@localhost ~]# echo "I am 192.168.2.128" > /usr/local/nginx/html/index.html

[root@test2 ~]# echo "I am 192.168.2.129" > /usr/local/nginx/html/index.html

3.啓動Nginx

[root@localhost nginx-1.16.1]# /usr/local/nginx/sbin/nginx 

[root@localhost nginx-1.16.1]# netstat -antulp | grep :80
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6079/nginx: master

或者[root@localhost nginx-1.16.1]# netstat -antulp | grep nginx
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      6079/nginx: master

3.關閉防火牆與selinux

 兩臺後端服務器都需要操作。

[root@test2 ~]# systmctl stop firewalld

[root@test2 ~]# setenforce 0

[root@test2 ~]# getenforce
Disabled

[root@test2 ~]# vim /etc/sysconfig/selinux     //永久關閉selinux
SELINUX=disabled

二、部署LVS-NAT模式調度器

1.確認調度器的路由轉發功能是否開啓(必須開啓)

[root@test3 ~]# cat /proc/sys/net/ipv4/ip_forward
1

若沒有開啓,則:
[root@test3 ~]# echo 1 > /proc/sys/net/ipv4/ip_forward

[root@test3 ~]# echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf  
     ////修改配置文件,設置路由轉發永久規則

2.調度器再添加一張網卡

[root@test3 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.130  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::1e8a:7d4a:beb0:fd6c  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::2c27:a02c:731a:2219  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:53:71:a2  txqueuelen 1000  (Ethernet)
        RX packets 66342  bytes 15217275 (14.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13974  bytes 1254299 (1.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 48  bytes 3781 (3.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 48  bytes 3781 (3.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 

在這裏插入圖片描述

[root@test3 ~]# ifconfig
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.2.130  netmask 255.255.255.0  broadcast 192.168.2.255
        inet6 fe80::1e8a:7d4a:beb0:fd6c  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::2c27:a02c:731a:2219  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:53:71:a2  txqueuelen 1000  (Ethernet)
        RX packets 66416  bytes 15223172 (14.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 13996  bytes 1256226 (1.1 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens37: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.4.133  netmask 255.255.255.0  broadcast 192.168.4.255
        inet6 fe80::7e5e:fea8:ba8e:ee18  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:53:71:ac  txqueuelen 1000  (Ethernet)
        RX packets 5018  bytes 385651 (376.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2524  bytes 269779 (263.4 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 48  bytes 3781 (3.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 48  bytes 3781 (3.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

3.兩臺後端服務器配置網關地址

[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-ens37
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO="static"
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens37
UUID=2d899e46-1b9d-40d5-9fed-8a88cb181d79
DEVICE=ens37
ONBOOT=yes
IPADDR="192.168.2.128"
PREFIX="24"
GATEWAY="192.168.2.130"     //網關地址配置爲調度器的內網地址
DNS1="8.8.8.8"

[root@test2 ~]#  cat /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO="static"
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33
UUID=2d899e46-1b9d-40d5-9fed-8a88cb181d65
DEVICE=ens33
ONBOOT=yes
IPADDR="192.168.2.129"
PREFIX="24"
GATEWAY="192.168.2.130"    //網關地址配置爲調度器的內網地址
DNS1="8.8.8.8"

[root@localhost ~]# systemctl restart network

[root@test2 ~]# systemctl restart network

以下步驟在調度器上操作
     ||

4.創建集羣調度服務器

[root@test3 ~]# yum -y install ipvsadm

[root@test3 ~]# ipvsadm -A -t 192.168.4.133:80 -s wrr  ////創建虛擬集羣服務器並設置調度算法爲加權輪詢wrr

5.添加真實服務器組

[root@test3 ~]# ipvsadm -a -t 192.168.4.133:80 -r 192.168.2.128 -w 1 -m

[root@test3 ~]# ipvsadm -a -t 192.168.4.133:80 -r 192.168.2.129 -w 2 -m

4.查看規則列表,並保存規則

[root@test3 ~]# ipvsadm -Ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  192.168.4.133:80 wrr
  -> 192.168.2.128:80             Masq    1      0          0
  -> 192.168.2.129:80             Masq    2      0          0

[root@test3 ~]# ipvsadm-save -n > /etc/sysconfig/ipvsadm-config

三、客戶端上測試
在這裏插入圖片描述
在這裏插入圖片描述
 可以看到每當我們執行一次curl命令(相當於刷新一次網頁),調度器都會根據權重值輪詢到不同的後端真實服務器。

當我們依次停掉後端兩臺服務器後,調度器會頂替工作嗎?

1.停掉後端129服務器nginx服務

[root@test2 ~]# /usr/local/nginx/sbin/nginx -s stop

2.使用客戶端訪問,查看輪詢結果
在這裏插入圖片描述
3.再停掉後端128服務器nginx服務器

[root@localhost ~]# /usr/local/nginx/sbin/nginx -s stop

4.再使用客戶端訪問,查看輪詢結果
在這裏插入圖片描述
 可以看到負載均衡調度服務器並不會頂替工作。

↓↓↓↓↓↓

最近剛申請了個微信公衆號,上面也會分享一些運維知識,大家點點發財手關注一波,感謝大家。 【原創公衆號】:非著名運維 【福利】:公衆號回覆 “資料” 送運維自學資料大禮包哦!
在這裏插入圖片描述

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