[Kube-router 實踐]K8s 1.9 Kube-router 對接外部BGP和發佈內部路由

實驗背景

新版本特性:

  • k8s 1.9 做了很大組件性能改進 ,
  • 本版本用kube-router組件取代kube-proxy,用lvs做svc負載均衡,更快穩定。
  • 用coredns取代kube-dns,DNS更穩定。
  • 經過測試1.9版,消除了以往的kubelet docker狂報錯誤日誌的錯誤 ,更完美
  • 支持 add動態插件

功能需求:

  • 發佈內部k8s網絡,到機房全網
  • cluster-ip,external-ip 全網路由
  • 解決iptables 性能和負載聚合問題
  • 還有iptables 負載NAT 丟失源ip問題
k8s測試版本
kubeadm version: &version. GitVersion:"v1.9.0", BuildDate:"2017-12-15T20:55:30Z"
網絡設備
Cisco 7200 
R1 10.129.6.91
R2 10.129.6.92
Vrrp 10.129.6.8

K8s Node網絡
node01 10.129.6.211
node03 10.129.6.213
K8s 網絡
10.244.0.0/16
SVC 網絡
NAMESPACE     NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)         AGE
default       kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP         6d
nginx01      ClusterIP   10.110.133.162   10.33.1.11    80/TCP    6d

網絡拓撲如圖:

image

  • 網絡高可用,目前我的方案是
  • 雙核心交換機跑VRRP
  • 模擬器,模擬網絡設備拓撲 R1 R2 主備路由器
    image
#R1 Cisco Config

interface FastEthernet0/0
 ip address 10.129.6.91 255.255.255.0
 vrrp 1 ip 10.129.6.8
 vrrp 1 priority 150

router bgp 64513
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.129.6.92 remote-as 64513
 neighbor 10.129.6.211 remote-as 64512
 neighbor 10.129.6.213 remote-as 64512
 maximum-paths 2
 no auto-summary

ip route 0.0.0.0 0.0.0.0 10.129.6.1

###############################
#R2 Cisco Config
interface FastEthernet0/0
 ip address 10.129.6.92 255.255.255.0
 vrrp 1 ip 10.129.6.8
 vrrp 1 priority 110

router bgp 64513
 no synchronization
 bgp log-neighbor-changes
 neighbor 10.129.6.92 remote-as 64513
 neighbor 10.129.6.211 remote-as 64512
 neighbor 10.129.6.213 remote-as 64512
 maximum-paths 2
 no auto-summary

ip route 0.0.0.0 0.0.0.0 10.129.6.1

部署k8s 1.9

此處省略,測試使用所以用
kubeadm 部署簡單快速
具體可以參看官方文檔

https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/

部署 kube-router

體系結構

Kube路由器是圍繞觀察者和控制器的概念而建立的。 觀察者使用Kubernetes監視API來獲取與創建,更新和刪除Kubernetes對象有關的事件的通知。 每個觀察者獲取與特定API對象相關的通知。 在從API服務器接收事件時,觀察者廣播事件。 控制器註冊以獲取觀察者的事件更新,並處理事件。
Kube-router由3個核心控制器和多個觀察者組成,如下圖所示。
image
主要改進

  • 使用ipvs 替代 Iptables 方案 -性能更好
  • 使用BGP 組網 更易發佈和擴展對接 之前方案要使用caclio 其他方案
  • 集成police 網絡策略 之前網絡層控制很弱
  • 負載均衡 更多可選功能 如rr sip hash ip回話保持
    更多信息關注https://cloudnativelabs.github.io
deployment部署Yaml文件

在Kubernetes上部署Kube-router的最好的入門方法是使用集羣安裝程序.

  • kubeadm 部署Kube-router,比較簡單就是導入yaml文件即可
    我們使用的是如下,爲了對接Cisco 網絡設備發佈路由
wget https://github.com/cloudnativelabs/kube-router/blob/master/daemonset/kube-router-all-service-daemonset-advertise-routes.yaml

kubectl apply -f kube-router-all-service-daemonset-advertise-routes.yaml
#我們根據實際環境修改下
containers:
      - args:
        - --run-router=true 
        #啓用Pod網絡 - 通過iBGP發佈並學習到Pod的路由。 (默認爲true)
        - --run-firewall=true
        #啓用網絡策略 - 設置iptables爲pod提供入口防火牆。 (默認爲true)
        - --run-service-proxy=true 
        #啓用服務代理 - 爲Kubernetes服務設置IPVS。 (默認爲true)
        - --advertise-cluster-ip=true
        #將該服務的集羣IP添加到RIB,以便通告給BGP peers.
        - --advertise-external-ip=true
        #將服務的外部IP添加到RIB,以便將其通告給BGP peers.
        - --cluster-asn=64512
        #集羣自身節點運行iBGP的ASN編號.
        - --peer-router-ips=10.129.6.8
        #所有節點將對等的外部路由器的IP地址,並通告集羣ip和pod cidr。 (默認[])
        - --peer-router-asns=64513
        #集羣節點將向其通告集羣ip和節點的pid cidr的BGP peers的ASN編號。 (默認[])
  • 更多部署請自行查詢
https://github.com/cloudnativelabs/kube-router/tree/master/daemonset

部署的nginx 測試服務

#
apiVersion: v1
kind: Service
metadata:
  annotations:
    kube-router.io/service.scheduler: sh
  labels:
    app: nginx01
    group: default
    role: master
    tier: backend
  name: nginx01
  namespace: default
spec:
  clusterIP: 10.110.133.162
  externalIPs:
  - 10.33.1.11
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx01
    group: default
    role: master
    tier: backend
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx01
  # these labels can be applied automatically
  # from the labels in the pod template if not set
  # labels:
  #   app: redis
  #   role: master
  #   tier: backend
  namespace: default
spec:
  # this replicas value is default
  # modify it according to your case
  replicas: 1
  # selector can be applied automatically
  # from the labels in the pod template if not set
  # selector:
  #   matchLabels:
  #     app: guestbook
  #     role: master
  #     tier: backend
  template:
    metadata:
      labels:
        app: nginx01
        role: master
        tier: backend
        group: default
    spec:
      containers:
      - name: nginx01
        image: devhub.beisencorp.com/test/nginx:v3  # or just image: redis
        resources:
          requests:
            cpu: 100m
            memory: 80Mi
          limits:
            cpu: 500m
            memory: 200M
        ports:
        - containerPort: 80

測試路由

[root@node01 k8s]#kubectl get svc            
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   6d
nginx01      ClusterIP   10.110.133.162   10.33.1.11    80/TCP    6d
[root@node01 k8s]# curl 10.33.1.11
< !DOCTYPE html>
< html>
< head>
< meta charset="UTF-8">
< title> 主標題 | 副標題< /title>
< /head>
< body>
<p>Hello, world! 我是版本V1
My V2 e WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>ZX
< /body>
< /html>

## 我們查看下 網絡設備路由器信息是否學習過來
#BGP鄰居已建立
R1#sh bgp sum 
BGP router identifier 10.129.6.91, local AS number 64513
Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.129.6.92     4 64513     147     146       25    0    0 02:16:05        6
10.129.6.211    4 64512     306     269        0    0    0 01:28:40 Active
10.129.6.213    4 64512     314     270        0    0    0 01:28:40 Active
R1#sh ip route
     10.0.0.0/8 is variably subnetted, 7 subnets, 2 masks
B       10.33.1.11/32 [200/0] via 10.129.6.92, 01:28:33
B       10.110.133.162/32 [200/0] via 10.129.6.92, 01:28:33
B       10.96.0.10/32 [200/0] via 10.129.6.92, 01:28:33
B       10.96.0.1/32 [200/0] via 10.129.6.92, 01:28:33
C       10.129.6.0/24 is directly connected, FastEthernet0/0
B       10.244.0.0/24 [200/0] via 10.129.6.211, 01:28:33
B       10.244.1.0/24 [200/0] via 10.129.6.213, 01:28:33
S*   0.0.0.0/0 [1/0] via 10.129.6.1

#R2 同上類同  R2備節點從R1主節點 學習全網路由

### 我們在看下 kube-router鄰居和路由是否學習過來
Here's a quick look at what's happening on this Node
--- BGP Server Configuration ---
AS:        ======64512======
Router-ID: 10.129.6.211
Listening Port: 179, Addresses: 0.0.0.0, ::

--- BGP Neighbors ---
Peer            AS  Up/Down State       |#Received  Accepted
10.129.6.8   64513 00:00:15 Establ      |        6         0
10.129.6.213 64512 03:40:40 Establ      |        1         1

--- BGP Route Info ---
   Network              Next Hop             AS_PATH              Age        Attrs
*> 10.33.1.11/32        10.129.6.211                              00:00:58   [{Origin: i}]
*> 10.96.0.1/32         10.129.6.211                              00:00:58   [{Origin: i}]
*> 10.96.0.10/32        10.129.6.211                              00:00:58   [{Origin: i}]
*> 10.110.133.162/32    10.129.6.211                              00:00:58   [{Origin: i}]
*> 10.244.0.0/24        10.129.6.211                              00:00:58   [{Origin: i}]
*> 10.244.1.0/24        10.129.6.213                              03:40:40   [{Origin: i} {LocalPref: 100}]

--- IPVS Services ---
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.33.1.11:80 sh
  -> 10.244.1.16:80               Masq    1      0          0         
TCP  10.96.0.1:443 rr persistent 10800
  -> 10.129.6.211:6443            Masq    1      0          0         
TCP  10.96.0.10:53 rr
  -> 10.244.0.13:53               Masq    1      0          0         
TCP  10.110.133.162:80 sh
  -> 10.244.1.16:80               Masq    1      0          0         
UDP  10.96.0.10:53 rr
  -> 10.244.0.13:53               Masq    1      0          0         

NAME                      

我們找臺機器加下靜態路由 指向網絡設備測試下 訪問

# 獲取 SVC 和pod ip
[root@node01 k8s]# kubectl get svc -o wide
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE       SELECTOR
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   6d        <none>
nginx01      ClusterIP   10.110.133.162   10.33.1.11    80/TCP    6d        app=nginx01,group=default,role=master,tier=backend
[root@node01 k8s]# kubectl get pod -o wide                 
NAME                      READY     STATUS    RESTARTS   AGE       IP            NODE
nginx01-d87b4fd74-7tw2x   1/1       Running   0          6d        10.244.1.16   node03

ClusterIP 路由

#ClusterIP 路由
route add -net 10.96.0.0 netmask 255.255.0.0 gw 10.129.6.8

ping 10.96.0.1
64 bytes from 10.96.0.1: icmp_seq=2 ttl=64 time=38.2 ms
64 bytes from 10.96.0.1: icmp_seq=3 ttl=64 time=0.258 ms
64 bytes from 10.96.0.1: icmp_seq=4 ttl=64 time=0.374 ms

external-ip 路由

#external-ip 路由
route add -net 10.33.1.11 netmask 255.255.255.255 gw 10.129.6.8

[root@haproxy02 zeming]# ping 10.33.1.11
PING 10.33.1.11 (10.33.1.11) 56(84) bytes of data.
From 10.129.6.8: icmp_seq=1 Redirect Host(New nexthop: 10.129.6.211)
64 bytes from 10.33.1.11: icmp_seq=1 ttl=64 time=41.4 ms
^C
--- 10.33.1.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 755ms
rtt min/avg/max/mdev = 41.459/41.459/41.459/0.000 

# 獲取頁面
[root@haproxy02 zeming]# curl 10.33.1.11
< !DOCTYPE html>
< html>
< head>
< meta charset="UTF-8">
< title> 主標題 | 副標題< /title>
< /head>
< body>
<p>Hello, world! 我是版本V1
My V2 e WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>
<p>Hello, world!  ^ ^  ^   ^ ^  ^  V1
My V2   Bye WorldZ</p>ZX
< /body>
< /html>

pod 路由

#pod 路由
route add -net 10.244.0.0 netmask 255.255.0.0 gw 10.129.6.8 

[root@haproxy02 xuzeming]# ping 10.244.0.13
PING 10.244.0.13 (10.244.0.13) 56(84) bytes of data.
64 bytes from 10.244.0.13: icmp_seq=1 ttl=63 time=41.8 ms
64 bytes from 10.244.0.13: icmp_seq=2 ttl=63 time=1.15 ms

主備網絡設備BGP 切換測試

  • 測試方式 關閉R1主節點網絡設備 互聯網口 製造 R1離線
  • 觀察 Vrrp 狀態轉移到備機
  • 觀察 BGP 備機 建立所有mesh 鄰居狀態

R2#
*Mar  1 02:58:09.451: %VRRP-6-STATECHANGE: Fa0/0 Grp 1 state Backup -> Master
R10#
*Mar  1 02:58:46.415: %BGP-5-ADJCHANGE: neighbor 10.129.6.211 Up
R10#
*Mar  1 02:58:53.007: %BGP-5-ADJCHANGE: neighbor 10.129.6.213 Up

#
R10#sh ip rou
Codes: C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2
       i - IS-IS, su - IS-IS summary, L1 - IS-IS level-1, L2 - IS-IS level-2
       ia - IS-IS inter area, * - candidate default, U - per-user static route
       o - ODR, P - periodic downloaded static route

Gateway of last resort is 10.129.6.1 to network 0.0.0.0

     10.0.0.0/8 is variably subnetted, 7 subnets, 2 masks
B       10.33.1.11/32 [20/0] via 10.129.6.213, 00:00:19
                      [20/0] via 10.129.6.211, 00:00:25
B       10.110.133.162/32 [20/0] via 10.129.6.213, 00:00:19
                          [20/0] via 10.129.6.211, 00:00:25
B       10.96.0.10/32 [20/0] via 10.129.6.213, 00:00:19
                      [20/0] via 10.129.6.211, 00:00:25
B       10.96.0.1/32 [20/0] via 10.129.6.213, 00:00:19
                     [20/0] via 10.129.6.211, 00:00:27
C       10.129.6.0/24 is directly connected, FastEthernet0/0
B       10.244.0.0/24 [20/0] via 10.129.6.211, 00:00:27
B       10.244.1.0/24 [20/0] via 10.129.6.213, 00:00:21
S*   0.0.0.0/0 [1/0] via 10.129.6.1

R10#sh bgp sum
BGP router identifier 10.129.6.92, local AS number 64513
BGP table version is 69, main routing table version 69
6 network entries using 702 bytes of memory
10 path entries using 520 bytes of memory
4 multipath network entries and 8 multipath paths
3/1 BGP path/bestpath attribute entries using 372 bytes of memory
1 BGP AS-PATH entries using 24 bytes of memory
0 BGP route-map cache entries using 0 bytes of memory
0 BGP filter-list cache entries using 0 bytes of memory
BGP using 1618 total bytes of memory
BGP activity 6/0 prefixes, 64/54 paths, scan interval 60 secs

Neighbor        V    AS MsgRcvd MsgSent   TblVer  InQ OutQ Up/Down  State/PfxRcd
10.129.6.91     4 64513     187     194        0    0    0 00:00:33 Active
10.129.6.211    4 64512     683     364       69    0    0 00:02:38        5
10.129.6.213    4 64512     688     362       69    0    0 00:02:32        5

補充拓展

kube-router 參數一欄

Usage of ./kube-router:
      --advertise-cluster-ip                將該服務的集羣IP添加到RIB,以便通告給BGP peers.
      --advertise-external-ip               將服務的外部IP添加到RIB,以便將其通告給BGP peers.
      --cleanup-config                      清理iptables規則,ipvs,ipset配置並退出.
      --cluster-asn uint                    集羣節點運行iBGP的ASN編號.
      --cluster-cidr string                 羣集中的CIDR範圍。它被用來識別pods的範圍.
      --config-sync-period duration         apiserver配置同步之間的延遲(例如“5s”,“1m”)。必須大於0.(默認1m0s)
      --enable-overlay                      當enable-overlay設置爲true時,IP-in-IP隧道將用於跨不同子網中節點的pod-pod聯網。如果設置爲false,則不使用隧道,並且路由基礎架構預計爲不同子網中的節點之間的pod-pod聯網路由流量(默認值爲true)
      --enable-pod-egress                   從Pod到羣集外的SNAT流量。 (默認爲true)
      --hairpin-mode                        爲每個服務端點添加iptable規則以支持流量管控.
  -h, --help                                打印使用信息.
      --hostname-override string            覆蓋節點的NodeName。如果kube-router無法自動確定您的NodeName,請設置此項.
      --iptables-sync-period duration       iptables規則同步之間的延遲(例如'5s','1m')。必須大於0.(默認1m0s)
      --ipvs-sync-period duration           ipvs config同步之間的延遲(例如'5s','1m','2h22m')。必須大於0.(默認1m0s)
      --kubeconfig string                   具有授權信息的kubeconfig文件的路徑(主位置由主標誌設置)。
      --masquerade-all                      SNAT所有流量到羣集IP /節點端口。
      --master string                       Kubernetes API服務器的地址(覆蓋kubeconfig中的任何值)。
      --nodeport-bindon-all-ip              對於NodePort類型的服務,創建監聽節點的所有IP的IPVS服務.
      --nodes-full-mesh                     集羣中的每個節點都將建立與其他節點的BGP對等關係。 (默認爲true)
      --peer-router-asns uintSlice          集羣節點將向其通告集羣ip和節點的pid cidr的BGP peers的ASN編號。 (默認[])
      --peer-router-ips ipSlice             所有節點將對等的外部路由器的IP地址,並通告集羣ip和pod cidr。 (默認[])
      --peer-router-passwords stringSlice   用“--peer-router-ips”定義的BGP peers進行認證的密碼。
      --routes-sync-period duration         路線更新與廣播之間的延遲(例如“5s”,“1m”,“2h22m”)。必須大於0.(默認1m0s)
      --run-firewall                        啓用網絡策略 - 設置iptables爲pod提供入口防火牆。 (默認爲true)
      --run-router                          啓用Pod網絡 - 通過iBGP發佈並學習到Pod的路由。 (默認爲true)
      --run-service-proxy                   啓用服務代理 - 爲Kubernetes服務設置IPVS。 (默認爲true)```

DSR模式

請閱讀以下博客,瞭解如何結合使用DSR和“–advertise-external-ip”構建高度可擴展和可用的入口。 https://cloudnativelabs.github.io/post/2017-11-01-kube-high-available-ingress/
您可以爲每個服務啓用DSR(直接服務器返回)功能。當啓用的服務端點將直接響應客戶端通過簽署服務代理。啓用DSR時,Kube-router將使用LVS的隧道模式來實現此功能。
要啓用DSR,您需要使用kube-router.io/service.dsr = tunnel註釋來註釋服務。例如,

kubectl annotate service my-service "kube-router.io/service.dsr=tunnel"
在當前的實現中,當在服務上應用註釋時,DSR將僅適用於外部IP。
此外,當使用DSR時,當前的實現不支持端口重新映射。所以你需要使用相同的端口和目標端口的服務
你需要在kube-router守護進程清單中啓用hostIPC:true和hostPID:true。並且必須將主路徑/var/run/docker.sock設置爲kube-router的一個volumemount。
上述更改需要kube-router輸入pod namespace,並在pod中創建ipip隧道,並將外部IP分配給VIP。
對於示例清單,請查看啓用DSR要求的[manifest](../ daemonset / kubeadm-kuberouter-all-features-dsr.yaml).

負載均衡調度算法

kube-router使用LVS作爲服務代理。 LVS支持豐富的調度算法。您可以爲該服務添加註釋以選擇一個調度算法。當一個服務沒有註釋時,默認情況下選擇“輪詢”調度策略

For least connection scheduling use:
kubectl annotate service my-service "kube-router.io/service.scheduler=lc"
For round-robin scheduling use:
kubectl annotate service my-service "kube-router.io/service.scheduler=rr"
For source hashing scheduling use:
kubectl annotate service my-service "kube-router.io/service.scheduler=sh"
For destination hashing scheduling use:
kubectl annotate service my-service "kube-router.io/service.scheduler=dh"

參考文獻

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