kube-proxy ipvs模式詳解


 

一、kube-proxy 開啟 ipvs

1、環境准備:

測試環境為kubernetes集群,一台master節點,一台node節點。集群網絡使用flanneld搭建。

注意:master節點上也需要進行kubelet配置。因為ipvs在有些情況下是依賴iptables的,iptables中KUBE-POSTROUTING,KUBE-MARK-MASQ, KUBE-MARK-DROP這三條鏈是被 kubelet創建和維護的, ipvs不會創建它們。

2、建議關閉SELinux,firewall

firewall是Linux 的一個安全子系統,SELinux 主要作用就是最大限度地減小系統中服務進程可訪問的資源。

關閉SELinux

docker1.node ➜  ~ cat /etc/selinux/config
# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

 

重啟驗證:

[root@master140 ~]# sestatus
SELinux status:                 disabled

 

關閉firewall

systemctl stop firewalld
systemctl disable firewalld

 

3、開啟路由轉發功能:
[root@master140 ~]# cat /etc/sysctl.conf
# sysctl settings are defined through files in
# /usr/lib/sysctl.d/, /run/sysctl.d/, and /etc/sysctl.d/.
#
# Vendors settings live in /usr/lib/sysctl.d/.
# To override a whole file, create a new file with the same in
# /etc/sysctl.d/ and put new settings there. To override
# only specific settings, add a file with a lexically later
# name in /etc/sysctl.d/ and put new settings there.
#
# For more information, see sysctl.conf(5) and sysctl.d(5).
net.ipv4.ip_forward=1

 

必須有net.ipv4.ip_forward=1,有了它,ipvs才能進行轉發

執行 sysctl -p 使之生效

[root@node147 ~]# sysctl -p
net.ipv4.ip_forward = 1

 

4、內核模塊加載
cat > /etc/sysconfig/modules/ipvs.modules <<EOF
#!/bin/bash
ipvs_modules="ip_vs ip_vs_lc ip_vs_wlc ip_vs_rr ip_vs_wrr ip_vs_lblc ip_vs_lblcr ip_vs_dh ip_vs_sh ip_vs_fo ip_vs_nq ip_vs_sed ip_vs_ftp nf_conntrack_ipv4"
for kernel_module in \${ipvs_modules}; do
    /sbin/modinfo -F filename \${kernel_module} > /dev/null 2>&1
    if [ $? -eq 0 ]; then
        /sbin/modprobe \${kernel_module}
    fi
done
EOF
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash /etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs

 

檢查測試:

[root@master140 ~]# lsmod | grep ip_vs 
ip_vs_ftp              13079  0 
nf_nat                 26787  3 ip_vs_ftp,nf_nat_ipv4,nf_nat_masquerade_ipv4
ip_vs_sed              12519  0 
ip_vs_nq               12516  0 
ip_vs_sh               12688  0 
ip_vs_dh               12688  0 
ip_vs_lblcr            12922  0 
ip_vs_lblc             12819  0 
ip_vs_wrr              12697  0 
ip_vs_rr               12600  17 
ip_vs_wlc              12519  0 
ip_vs_lc               12516  0 
ip_vs                 141092  39 ip_vs_dh,ip_vs_lc,ip_vs_nq,ip_vs_rr,ip_vs_sh,ip_vs_ftp,ip_vs_sed,ip_vs_wlc,ip_vs_wrr,ip_vs_lblcr,ip_vs_lblc
nf_conntrack          133387  7 ip_vs,nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c              12644  4 xfs,ip_vs,nf_nat,nf_conntrack

 

5、修改kube-proxy配置

Node:

KUBE_PROXY_ARGS="--bind-address=0.0.0.0 \
  --hostname-override=node147 \
  --kubeconfig=/etc/kubernetes/kube-proxy.conf \
  --logtostderr=true \
  --v=2 \
  --feature-gates=SupportIPVSProxyMode=true \
  --proxy-mode=ipvs"

 

如果kubelet設置了–hostname-override選項,則kube-proxy也需要設置該選項,並且名字一致否則會出現找不到Node的情況。

Master:

KUBE_PROXY_ARGS="--proxy-mode=ipvs \
  --ipvs-scheduler=rr \
  --kubeconfig=/etc/kubernetes/kube-proxy.conf \
  --logtostderr=true \
  --v=2"

 

 

二、ipvs原理:

ipvs的模型中有兩個角色:

調度器:Director,又稱為Balancer。 調度器主要用於接受用戶請求。

真實主機:Real Server,簡稱為RS。用於真正處理用戶的請求。

IP地址類型分為三種:

Client IP:客戶端請求源IP,簡稱CIP。

Director Virtual IP:調度器用於與客戶端通信的IP地址,簡稱為VIP。

Real Server IP: 后端主機的用於與調度器通信的IP地址,簡稱為RIP。
在這里插入圖片描述

工作過程:

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

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

3、ipvs會監聽到達input鏈的數據包,比對數據包請求的服務是否為集群服務,若是,修改數據包的目標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。

三 ipvs在kube-proxy中的使用

開啟ipvs后,本機里面的一些信息會改變。

1、網卡

明顯的變化是,多了一個綁定很多cluster service ip的kube-ipvs0網卡

[root@master140 ~]# ip addr
5: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN group default 
    link/ether d2:b0:08:01:3e:52 brd ff:ff:ff:ff:ff:ff
    inet 172.18.13.31/32 brd 172.18.13.31 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    inet 172.18.13.1/32 brd 172.18.13.1 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    inet 172.18.13.187/32 brd 172.18.13.187 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    inet 172.18.13.113/32 brd 172.18.13.113 scope global kube-ipvs0
       valid_lft forever preferred_lft forever
    inet 172.18.13.222/32 brd 172.18.13.222 scope global kube-ipvs0
       valid_lft forever preferred_lft forever

 

2、router

查看router時候,會發現多了一下一些route信息。這些route信息是和上面的網卡信息對應的。

[root@master140 ~]# ip route show table local
local 172.18.13.1 dev kube-ipvs0 proto kernel scope host src 172.18.13.1 
local 172.18.13.31 dev kube-ipvs0 proto kernel scope host src 172.18.13.31 
local 172.18.13.113 dev kube-ipvs0 proto kernel scope host src 172.18.13.113 
local 172.18.13.187 dev kube-ipvs0 proto kernel scope host src 172.18.13.187 
local 172.18.13.222 dev kube-ipvs0 proto kernel scope host src 172.18.13.222 

 

3、ipvs 規則
[root@master140 ~]# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  127.0.0.1:30001 rr
TCP  127.0.0.1:30002 rr
  -> 10.0.3.5:8080                Masq    1      0          0         
  -> 10.0.3.7:8080                Masq    1      0          0         
TCP  127.0.0.1:30094 rr
  -> 10.0.3.2:80                  Masq    1      0          0         
TCP  172.17.0.1:30001 rr
TCP  172.17.0.1:30002 rr
  -> 10.0.3.5:8080                Masq    1      0          0         
  -> 10.0.3.7:8080                Masq    1      0          0         
TCP  172.17.0.1:30094 rr
  -> 10.0.3.2:80                  Masq    1      0          0         
TCP  172.18.13.1:443 rr
  -> 192.168.204.142:6443         Masq    1      0          0         
TCP  172.18.13.31:80 rr
TCP  172.18.13.113:8082 rr
  -> 10.0.3.5:8080                Masq    1      0          0         
  -> 10.0.3.7:8080                Masq    1      0          0         
TCP  172.18.13.187:3306 rr
  -> 10.0.3.4:3306                Masq    1      0          0         
TCP  172.18.13.222:80 rr
  -> 10.0.3.2:80                  Masq    1      0          0         
TCP  192.168.204.142:30001 rr
TCP  192.168.204.142:30002 rr
  -> 10.0.3.5:8080                Masq    1      0          0         
  -> 10.0.3.7:8080                Masq    1      0          0         
TCP  192.168.204.142:30094 rr
  -> 10.0.3.2:80                  Masq    1      0          0         
TCP  10.0.1.0:30001 rr
TCP  10.0.1.0:30002 rr
  -> 10.0.3.5:8080                Masq    1      0          0         
  -> 10.0.3.7:8080                Masq    1      0          0         
TCP  10.0.1.0:30094 rr
  -> 10.0.3.2:80                  Masq    1      0          0         

 

4、新增網卡和route的作用

由於 IPVS 的 DNAT 鈎子掛在 INPUT 鏈上,因此必須要讓內核識別 VIP 是本機的 IP。這樣才會過INPUT 鏈,要不然就通過OUTPUT鏈出去了。k8s 通過設置將service cluster ip 綁定到虛擬網卡kube-ipvs0。

5、使用ipvs的kube-proxy的工作原理

![屏幕快照 2019-05-15 下午1.00.20](/Users/tcy/Documents/Typora/Picture/屏幕快照 2019-05-15 下午1.00.20.png)
在這里插入圖片描述
①因為service cluster ip 綁定到虛擬網卡kube-ipvs0上,內核可以識別訪問的 VIP 是本機的 IP.

②數據包到達INPUT鏈.

③ipvs監聽到達input鏈的數據包,比對數據包請求的服務是為集群服務,修改數據包的目標IP地址為對應pod的IP,然后將數據包發至POSTROUTING鏈.

④數據包經過POSTROUTING鏈選路,將數據包通過flannel網卡發送出去。從flannel虛擬網卡獲得源IP.

⑤pod接收到請求之后,構建響應報文,改變源地址和目的地址,返回給客戶端。

四、實例-集群內部通過clusterIP訪問到pod的流程

本例子中有兩台機器,master和node,pod都在node機器上運行。訪問命令為curl 172.18.13.222:80,對應的pod的ip為10.0.7.7。

![屏幕快照 2019-05-15 上午9.36.27](/Users/tcy/Documents/Typora/Picture/屏幕快照 2019-05-15 上午9.36.27.png)
在這里插入圖片描述

1、本機接受請求

內核通過本機的路由和虛擬網卡,可以識別訪問的 VIP 是本機的 IP

//路由
local 172.18.13.222 dev kube-ipvs0 proto kernel scope host src 172.18.13.222
//網卡
inet 172.18.13.222/32 brd 172.18.13.222 scope global kube-ipvs0
valid_lft forever preferred_lft forever
2、將數據包送至INPUT鏈。

驗證是否經過INPUT鏈

首先、我們在INPUT鏈中加入一條如下過濾規則。該規則的意思是當有目的地址為172.18.13.222時,都拒絕掉。

iptables -t filter -I INPUT -d 172.18.13.222 -j DROP

 

查看INPUT鏈,確實多了此條規則。
在這里插入圖片描述
之后,我們watch INPUT鏈

watch -n 0.1 "iptables --line-number -nvxL INPUT"

當我們訪問172.18.13.222時

curl 172.18.13.222

 

發現無法訪問,並且watch到INPUT確實有拒絕的包。驗證成功后。
在這里插入圖片描述

3、ipvs對請求做轉發

ipvs會監聽到達input鏈的數據包,比對數據包請求的服務是為集群服務,所以修改數據包的目標IP地址為真實服務器IP,然后將數據包發至POSTROUTING鏈。 此時報文的源IP為CIP,目標IP為RIP(真實ip)
在這里插入圖片描述

4、通過網卡發出數據包

數據包經過POSTROUTING鏈選路,將數據包通過flannel網卡發送出去,pod所在機器也通過flannel網卡進行接收。數據包經過master上的flannel網卡第一次被賦予源IP。此時源IP,目的IP分別是10.0.6.0,10.0.7.7

驗證是否通過flnanel網卡進行通信:

首先:master上flannel網卡信息是10.0.6.0/16。
在這里插入圖片描述
node上flannel網卡信息是10.0.7.0/16。在這里插入圖片描述
當我們從master上進行curl命令時
在這里插入圖片描述
對pod所在機器node的flannel網卡進行監聽,發現是請求從10.0.6.0發送過來的。10.0.6.0正是master上的網卡信息。
在這里插入圖片描述

5、pod接收到請求,處理,返回

pod接收到請求之后,開始構建響應報文返回給客戶端。 此時報文的源IP為pod的IP:10.0.7.7,目標IP為10.0.6.0。最終又通過flannel網絡將響應報文發回master。

注意:

我們上文所說的通過flannel網絡進行通信,最終還是要過機器的真實網卡,因為flannel網絡設置的網卡也是虛擬的。

例如我們監聽機器的真實網卡eth0

tcpdump -nn -i eth0 src port not 22  and dst port not 22

 

在這里插入圖片描述
我們是能夠發現通過flannel網絡進行通信還是會經過真實網卡eth0


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM