1. 程式人生 > >calico網路原理、組網方式和使用

calico網路原理、組網方式和使用

calico的好處是endpoints組成的網路是單純的三層網路,報文的流向完全通過路由規則控制,沒有overlay等額外開銷。

calico的endpoint可以漂移,並且實現了acl。

calico的缺點是路由的數目與容器數目相同,非常容易超過路由器、三層交換、甚至node的處理能力,從而限制了整個網路的擴張。

calico的每個node上會設定大量(海量)的iptables規則、路由,運維、排障難度大。

calico的原理決定了它不可能支援VPC,容器只能從calico設定的網段中獲取ip。

calico目前的實現沒有流量控制的功能,會出現少數容器搶佔node多數頻寬的情況。

calico的網路規模受到BGP網路規模的限制。

名詞解釋

endpoint:  接入到calico網路中的網絡卡稱為endpoint
AS:        網路自治系統,通過BGP協議與其它AS網路交換路由資訊
ibgp:      AS內部的BGP Speaker,與同一個AS內部的ibgp、ebgp交換路由資訊。
ebgp:      AS邊界的BGP Speaker,與同一個AS內部的ibgp、其它AS的ebgp交換路由資訊。

workloadEndpoint:  虛擬機器、容器使用的endpoint
hostEndpoints:     物理機(node)的地址

組網原理

calico組網的核心原理就是IP路由,每個容器或者虛擬機器會分配一個workload-endpoint(wl)。

從nodeA上的容器A內訪問nodeB上的容器B時:

+--------------------+              +--------------------+ 
|   +------------+   |              |   +------------+   | 
|   |            |   |              |   |            |   | 
|   |    ConA    |   |              |   |    ConB    |   | 
|   |            |   |              |   |            |   | 
|   +-----+------+   |              |   +-----+------+   | 
|         |veth      |              |         |veth      | 
|       wl-A         |              |       wl-B         | 
|         |          |              |         |          |
+-------node-A-------+              +-------node-B-------+ 
        |    |                               |    |
        |    | type1.  in the same lan       |    |
        |    +-------------------------------+    |
        |                                         |
        |      type2. in different network        |
        |             +-------------+             |
        |             |             |             |
        +-------------+   Routers   |-------------+
                      |             |
                      +-------------+

從ConA中傳送給ConB的報文被nodeA的wl-A接收,根據nodeA上的路由規則,經過各種iptables規則後,轉發到nodeB。

如果nodeA和nodeB在同一個二層網段,下一條地址直接就是node-B,經過二層交換機即可到達。
如果nodeA和nodeB在不同的網段,報文被路由到下一跳,經過三層交換或路由器,一步步跳轉到node-B。

核心問題是,nodeA怎樣得知下一跳的地址?答案是node之間通過BGP協議交換路由資訊。

每個node上執行一個軟路由軟體bird,並且被設定成BGP Speaker,與其它node通過BGP協議交換路由資訊。

可以簡單理解為,每一個node都會向其它node通知這樣的資訊:

我是X.X.X.X,某個IP或者網段在我這裡,它們的下一跳地址是我。

通過這種方式每個node知曉了每個workload-endpoint的下一跳地址。

BGP與AS

BGP是路由器之間的通訊協議,主要用於AS(Autonomous System,自治系統)之間的互聯。

AS是一個自治的網路,擁有獨立的交換機、路由器等,可以獨立運轉。

每個AS擁有一個全球統一分配的16位的ID號,64512到65535共1023個AS號碼可以用於私有網路。

calico預設使用的AS號是64512,可以修改:

calicoctl config get asNumber         //檢視
calicoctl config set asNumber 64512   //設定

AS內部有多個BGP speaker,分為ibgp、ebgp,ebgp與其它AS中的ebgp建立BGP連線。

AS內部的BGP speaker通過BGP協議交換路由資訊,最終每一個BGP speaker擁有整個AS的路由資訊。

BGP speaker一般是網路中的物理路由器,可以形象的理解為:

calico將node改造成了一個軟路由器(通過軟路由軟體bird)
node上的執行的虛擬機器或者容器通過node與外部溝通

AS內部的BGP Speaker之間有兩種互聯方式:

Mesh: BGP Speaker之間全互聯,網路成網狀
RR:   Router reflection模式,BGP Speaker連線到一個或多箇中心BGP Speaker,網路成星狀

BGP Speaker 全互聯模式(node-to-node mesh)

全互聯模式,就是一個BGP Speaker需要與其它所有的BGP Speaker建立bgp連線(形成一個bgp mesh)。

網路中bgp總連線數是按照O(n^2)增長的,有太多的BGP Speaker時,會消耗大量的連線。

calico預設使用全互聯的方式,擴充套件性比較差,只能支援小規模叢集:

say 50 nodes - although this limit is not set in stone and 
Calico has been deployed with over 100 nodes in a full mesh topology

可以開啟/關閉全互聯模式:

calicoctl config set nodeTonodeMesh off
calicoctl config set nodeTonodeMesh on

BGP Speaker RR模式

RR模式,就是在網路中指定一個或多個BGP Speaker作為Router Reflection,RR與所有的BGP Speaker建立BGP連線。

每個BGP Speaker只需要與RR交換路由資訊,就可以得到全網路由資訊。

RR則必須與所有的BGP Speaker建立BGP連線,以保證能夠得到全網路由資訊。

在calico中可以通過Global Peer實現RR模式。

Global Peer是一個BGP Speaker,需要手動在calico中建立,所有的node都會與Global peer建立BGP連線。

A global BGP peer is a BGP agent that peers with every calico node in the network. 
A typical use case for a global peer might be a mid-scale deployment where all of
the calico nodes are on the same L2 network and are each peering with the same Route
Reflector (or set of Route Reflectors).

關閉了全互聯模式後,再將RR作為Global Peers新增到calico中,calico網路就切換到了RR模式,可以支撐容納更多的node。

calico中也可以通過node Peer手動構建BGP Speaker(也就是node)之間的BGP連線。

node Peer就是手動建立的BGP Speaker,只有指定的node會與其建立連線。

A BGP peer can also be added at the node scope, meaning only a single specified node 
will peer with it. BGP peer resources of this nature must specify a node to inform 
calico which node this peer is targeting.

因此,可以為每一個node指定不同的BGP Peer,實現更精細的規劃。

例如當叢集規模進一步擴大的時候,可以使用AS Per Pack model:

每個機架是一個AS
node只與所在機架TOR交換機建立BGP連線
TOR交換機之間作為各自的ebgp全互聯

calico網路的部署

calico網路對底層的網路的要求很少,只要求node之間能夠通過IP聯通。

Any technology that is capable of transporting IP packets can be used as the interconnect fabric in a Calico network.

在calico中,全網路由的數目和endpoints的數目一致,通過為node分配網段,可以減少路由數目,但不會改變數量級。

如果有1萬個endpoints,那麼就至少要有一臺能夠處理1萬條路由的裝置。

無論用哪種方式部署始終會有一臺裝置上存放著calico全網的路由。

當要部署calico網路的時候,第一步就是要確認,網路中處理能力最強的裝置最多能設定多少條路由。

calico在Ethernet interconnect fabric中的部署方式

calico over an Ethernet interconnect fabric中介紹了在Ethernet interconnect fabric部署calico網路方案。在每個vlan中部署一套calico。

calico-l2-rr-spine-planes

為了保證鏈路可靠,圖中設計了四個並列的二層網,形成fabric。

每個node同時接入四個二層網路,對應擁有四個不同網段的IP。

在每個二層網路中,node與node之間用RR模式建立BGP通訊鏈路:

一個node做為RR,其餘的node連線到做為RR的node
整個網路中最終有四個RR,分別負責四個網路中的BGP

當從node上去訪問另一個node上的endpoint的時候,會有四條下一跳為不同網段的等價路由。

根據ECMP協議,報文將會平均分配給這四個等價路由,提高了可靠性的同時增加了網路的吞吐能力。

calico在ip fabric中的部署方式

如果底層的網路是ip fabric的方式,三層網路是可靠的,只需要部署一套calico。

剩下的關鍵點就是怎樣設計BGP網路,calico over ip fabrics中給出兩種設計方式:

1. AS per rack:   每個rack(機架)組成一個AS,每個rack的TOR交換機與核心交換機組成一個AS
2. AS per server: 每個node做為一個AS,TOR交換機組成一個transit AS

這兩種方式採用的是Use of BGP for routing in large-scale data centers中的建議。

AS per rack

1. 一個機架作為一個AS,分配一個AS號,node是ibgp,TOR交換機是ebgp
2. node只與TOR交換機建立BGP連線,TOR交換機與機架上的所有node建立BGP連線 
3. 所有TOR交換機之間以node-to-node mesh方式建立BGP連線

TOR交換機之間可以是接入到同一個核心交換機二層可達的,也可以只是IP可達的。

TOR二層聯通:

calico-l3-fabric-diagrams-as-rack-l2-spine

TOR三層聯通:

calico-l3-fabric-diagrams-as-rack-l3-spine

每個機架上node的數目是有限的,BGP壓力轉移到了TOR交換機。當機架數很多,TOR交換機組成BGP mesh壓力會過大。

endpoints之間的通訊過程:

EndpointA發出報文  --> nodeA找到了下一跳地址nodeB --> 報文送到TOR交換機A --> 報文送到核心交換機
                                                                                      |
                                                                                      v
EndpointB收到了報文 <--  nodeB收到了報文 <-- TOR交換機B收到了報文 <--  核心交換機將報文送達TOR交換機B

AS per server

1. 每個TOR交換機佔用一個AS
2. 每個node佔用一個AS
3. node與TOR交換機交換BGP資訊
3. 所有的TOR交換機組成BGP mesh,交換BGP資訊

這種方式消耗了大量的AS,RFC 4893 - BGP Support for Four-octet AS Number Space中考慮將AS號增加到32位。

不是特別明白這種方式的好處在哪裡。

TOR二層聯通:

calico-l3-fabric-diagrams-as-server-l2-spine

TOR三層聯通:

calico-l3-fabric-diagrams-as-server-l3-spine

優化:“Downward Default model”減少需要記錄的路由

Downward Default Model在上面的幾種組網方式的基礎上,優化了路由的管理。

在上面的三種方式中,每個node、每個TOR交換機、每個核心交換機都需要記錄全網路由。

“Downward Default model”模式中:

1. 每個node向上(TOR)通告所有路由資訊,而TOR向下(node)只通告一條預設路由
2. 每個TOR向上(核心交換機)通告所有路由,核心交換機向下(TOR)只通告一條預設路由
3. node只知曉本地的路由
4. TOR只知道接入到自己的所有node上的路由
5. 核心交換機知曉所有的路由

這種模式減少了TOR交換機和node上的路由數量,但缺點是,傳送到無效IP的流量必須到達核心交換機以後,才能被確定為無效。

endpoints之間的通訊過程:

EndpointA發出報文  --> nodeA預設路由到TOR交換機A --> TOR交換機A預設路由到核心交換機 --+
                                                                                      |
                                                                                      v
EndpointB收到了報文 <--  nodeB收到了報文 <-- TOR交換機B收到了報文 <-- 核心交換機找到了下一跳地址nodeB

calico系統結構

calico系統組成:

1. Felix, the primary calico agent that runs on each machine that hosts endpoints.
2. etcd, the data store.
3. BIRD, a BGP client that distributes routing information.
4. BGP Route Reflector (BIRD), an optional BGP route reflector for higher scale.
5. The Orchestrator plugin, orchestrator-specific code that tightly integrates calico into that orchestrator.

Felix負責管理設定node,

bird是一個開源的軟路由,支援多種路由協議。

calico中的概念

calicoctl resource definitions介紹了每類資源的格式。

bgpPeer

apiVersion: v1
kind: bgpPeer
metadata:
  scope: node
  node: rack1-host1
  peerIP: 192.168.1.1
spec:
  asNumber: 63400

bgpPeer的scope可以是node、global。

ipPool

apiVersion: v1
kind: ipPool
metadata:
  cidr: 10.1.0.0/16
spec:
  ipip:
    enabled: true
    mode: cross-subnet
  nat-outgoing: true
  disabled: false

node

apiVersion: v1
kind: node
metadata:
  name: node-hostname
spec:
  bgp:
    asNumber: 64512
    ipv4Address: 10.244.0.1/24
    ipv6Address: 2001:db8:85a3::8a2e:370:7334/120

policy

A Policy resource (policy) represents an ordered set of rules which are applied to a collection of endpoints which match a label selector.

Policy resources can be used to define network connectivity rules between groups of calico endpoints and host endpoints, and take precedence over Profile resources if any are defined.

apiVersion: v1
kind: policy
metadata:
  name: allow-tcp-6379
spec:
  selector: role == 'database'
  ingress:
  - action: allow
    protocol: tcp
    source:
      selector: role == 'frontend'
    destination:
      ports:
      - 6379
  egress:
  - action: allow

profile

A Profile resource (profile) represents a set of rules which are applied to the individual endpoints to which this profile has been assigned.

apiVersion: v1
kind: profile
metadata:
  name: profile1
  labels:
    profile: profile1 
spec:
  ingress:
  - action: deny
    source:
      net: 10.0.20.0/24
  - action: allow
    source:
      selector: profile == 'profile1'
  egress:
  - action: allow 

workloadEndpoint

A Workload Endpoint resource (workloadEndpoint) represents an interface connecting a calico networked container or VM to its host.

apiVersion: v1
kind: workloadEndpoint
metadata:
  name: eth0 
  workload: default.frontend-5gs43
  orchestrator: k8s
  node: rack1-host1
  labels:
    app: frontend
    calico/k8s_ns: default
spec:
  interfaceName: cali0ef24ba
  mac: ca:fe:1d:52:bb:e9 
  ipNetworks:
  - 192.168.0.0/16
  profiles:
  - profile1

hostEndpoint

apiVersion: v1
kind: hostEndpoint
metadata:
  name: eth0
  node: myhost
  labels:
    type: production
spec:
  interfaceName: eth0
  expectedIPs:
  - 192.168.0.1
  - 192.168.0.2
  profiles:
  - profile1
  - profile2

node的報文處理過程

報文處理過程中使用的標記位:

一共使用了3個標記位,0x7000000對應的標記位
0x1000000:  報文的處理動作,置1表示放行,預設0表示拒絕
0x2000000:  是否已經經過了policy規則檢測,置1表示已經過
0x4000000:  報文來源,置1,表示來自host-endpoint

流入報文來源:

1. 以cali+命名的網絡卡收到的報文,這部分報文是node上的endpoint發出的
   (k8s中,容器的內發出的所有報文都會發送到對應的cali網絡卡上)
   (通過在容器內新增靜態arp,將容器閘道器的IP對映到cali網絡卡的MAC上實現)
2. 其他網絡卡接收的報文,這部分報文是其它node傳送或者在node本地發出的

流入的報文去向:

1. 訪問本node的host endpoint,通過INPUT過程處理
2. 訪問本node的workload endpoint,通過INPUT過程處理
3. 訪問其它node的host endpoint,通過FORWARD過程處理。
4. 訪問其它node的workload endpoint,通過FORWARD過程處理。

流入的報文在路由決策之前的處理過程相同的,路由決策之後,分別進入INPUT規則鏈和FORWARD鏈。

raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.INPUT -> filter.INPUT 
raw.PREROUTING -> mangle.PREROUTING -> nat.PREROUTING -> mangle.FORWARD -> filter.FORWARD -> mangle.POSTROUTING -> nat.POSTROUTING

這裡分析的calico的版本比較老,和最新版中的規則有一些出入,但是原理相同。

新版本的calico的iptables規則可讀性更好,可以直接閱讀規則。

報文處理流程(全):

from-XXX: XXX發出的報文            tw: 簡寫,to wordkoad endpoint
to-XXX: 傳送到XXX的報文            po: 簡寫,policy outbound
cali-: 字首,calico的規則鏈        pi: 簡寫,policy inbound
wl: 簡寫,workload endpoint        pro: 簡寫,profile outbound
fw: 簡寫,from workload endpoint   pri: 簡寫,profile inbound

(receive pkt)
cali-PREOUTING@raw -> cali-from-host-endpoint@raw -> cali-PREROUTING@nat
                   |                                 ^        |
                   |          (-i cali+)             |        |
                   +--- (from workload endpoint) ----+        |
                                                              |
            (dest  may be container's floating ip)   cali-fip-dnat@nat
                                                              |
                                                     (rotuer decision)
                                                              |
                     +--------------------------------------------+
                     |                                            |
            cali-INPUT@filter                             cali-FORWARD@filter
         (-i cali+)  |                               (-i cali+)   |    (-o cali+)
         +----------------------------+              +------------+-------------+
         |                            |              |            |             |
 cali-wl-to-host           cali-from-host-endpoint   |  cali-from-host-endpoint |
     @filter                       @filter           |         @filter          |
         |                         < END >           |            |             |
         |                                           |   cali-to-host-endpoint  |
         |                                           |         @filter          |
         |                     will return to nat's  |         < END >          |
         |                       cali-POSTROUTING    |                          |
 cali-from-wl-dispatch@filter  <---------------------+   cali-to-wl-dispatch@filter
                      |         \--------------+                       |
          +-----------------------+            |           +----------------------+
          |                       |            |           |                      |
 cali-fw-cali0ef24b1     cali-fw-cali0ef24b2   |  cali tw-cali03f24b1   cali-tw-cali03f24b2
      @filter                 @filter          |       filter                  @filter
  (-i cali0ef24b1)          (-i cali0ef24b2)   |   (-o cali0ef24b1)        (-o cali0ef24b2)
          |                       |            |           |                      |
          +-----------------------+            |           +----------------------+
                      |                        |                       |
           cali-po-[POLICY]@filter             |            cali-pi-[POLICY]@filter
                      |                        |                       |
          cali-pro-[PROFILE]@filter            |           cali-pri-[PROFILE]@filter
                      |                        |                       |
                   < END >                     +------------> cali-POSTROUTING@nat
                                               +---------->/           |
                                               |                cali-fip-snat@nat
                                               |                       |
                                               |              cali-nat-outgoing@nat
                                               |                       |
                                               |       (if dip is local: send to lookup)
                                     +---------+--------+   (else: send to nic's qdisc)
                                     |                  |           < END >    
                     cali-to-host-endpoint@filter       | 
                                     |                  | 
                                     +------------------+ 
                                               ^ (-o cali+)
                                               | 
                                       cali-OUTPUT@filter
                                               ^    
(send pkt)                                     | 
(router descition) -> cali-OUTPUT@nat -> cali-fip-dnat@nat

node本地發出的報文,經過路由決策之後,直接進入raw,OUTPUT規則鏈:

raw.OUTPUT -> mangle.OUTPUT -> nat.OUTPUT -> filter.OUTPUT -> mangle.POSTROUTING -> nat.POSTROUTING

路由決策之前:流入node的報文的處理

進入raw表

PREROUTING@raw:

-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING

cali-PREROUTING@RAW:

-A cali-PREROUTING -m comment --comment "cali:x4XbVMc5P_kNXnTy" -j MARK --set-xmark 0x0/0x7000000
-A cali-PREROUTING -i cali+ -m comment --comment "cali:fQeZek80kVOPa0xO" -j MARK --set-xmark 0x4000000/0x4000000
-A cali-PREROUTING -m comment --comment "cali:xp3NolkIpulCQL_G" -m mark --mark 0x0/0x4000000 -j cali-from-host-endpoint
-A cali-PREROUTING -m comment --comment "cali:fbdE50A0BiINbNiA" -m mark --mark 0x1000000/0x1000000 -j ACCEPT

規則1,清空所有標記
規則2,從cali+網絡卡進入的報文,設定mark: 0x4000000/0x4000000
規則3,非cali+網絡卡收到的報文,即從host-endpoint進入的報文,進入cali-from-host-endpoints規則鏈條

這裡沒有設定host-endpoint的策略,所有cali-from-host-endpoint規則鏈是空的。

進入nat表

PREROUTING@nat:

-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER

直接進入cali-PREROUTING

cali-PREROUTING@nat:

-A cali-PREROUTING -m comment --comment "cali:r6XmIziWUJsdOK6Z" -j cali-fip-dnat

如果目標地址是fip(floating IP),會在cali-fip-dnat中做dnat轉換

nat表中做目的IP轉換,這裡沒有設定,所以cali-fip-dnat是空的。

經過nat表之後,會進行路由決策:

1. 如果是傳送給slave1的報文,經過規則鏈: INPUT@mangle、INPUT@filter
2. 如果不是傳送給slave1報文,經過規則鏈: FORWARD@mangle、FORWARD@filer、POSTROUTING@mangle、POSTROUTING@nat

路由決策之後:傳送到本node的host endpoint 和 workload endpoint

進入filter表

INPUT@filter:

-A INPUT -m comment --comment "cali:Cz_u1IQiXIMmKD4c" -j cali-INPUT

直接進入cali-INPUT

cali-INPUT@filter:

-A cali-INPUT -m comment --comment "cali:46gVAqzWLjH8U4O2" -m mark --mark 0x1000000/0x1000000 -m conntrack --ctstate UNTRACKED -j ACCEPT
-A cali-INPUT -m comment --comment "cali:5M2EkEm-RVlDLAfE" -m conntrack --ctstate INVALID -j DROP
-A cali-INPUT -m comment --comment "cali:8ggYjLbFRX5Ap9Zj" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A cali-INPUT -i cali+ -m comment --comment "cali:mA3ZJKi9nadUmYVF" -g cali-wl-to-host

-A cali-INPUT -m comment --comment "cali:hI4IjifGj0fegLPE" -j MARK --set-xmark 0x0/0x7000000
-A cali-INPUT -m comment --comment "cali:wdegoKfPlcmsZTOM" -j cali-from-host-endpoint
-A cali-INPUT -m comment --comment "cali:r875VVc8vFk1f-ZA" -m comment --comment "Host endpoint policy accepted packet." -m mark --mark 0x1000000/0x1000000 -j ACCEPT

規則4,從cali+網絡卡進入的報文,進入wl-to-host的規則鏈,wl是workload的縮
規則6,非cali+網絡卡收到的報文,host-endpoint的規則鏈

來自其它node的報文

這裡沒有對host endpoint設定規則,所以規則鏈時空

cali-from-host-endpoint@filter:

來自本node上workload endpoint的報文

檢察一下是否允許workload enpoint發出這些報文。

cali-wl-to-host@filter:

-A cali-wl-to-host -p udp -m comment --comment "cali:aEOMPPLgak2S0Lxs" -m multiport --sports 68 -m multiport --dports 67 -j ACCEPT
-A cali-wl-to-host -p udp -m comment --comment "cali:SzR8ejPiuXtFMS8B" -m multiport --dports 53 -j ACCEPT
-A cali-wl-to-host -m comment --comment "cali:MEmlbCdco0Fefcrw" -j cali-from-wl-dispatch
-A cali-wl-to-host -m comment --comment "cali:Q2b2iY2M-vmds5iY" -m comment --comment "Configured DefaultEndpointToHostAction" -j RETURN

規則1,允許請求DHCP
規則2,允許請求DNS
規則3,匹配workload endpoint各自的規則,將會依次檢察policy的egress、各自繫結的profile的egress。

根據接收報文的網絡卡做區分,cali-from-wl-dispatch@filter:

-A cali-from-wl-dispatch -i cali0ef24b1 -m comment --comment "cali:RkM6MKQgU0OTxwKU" -g cali-fw-cali0ef24b1
-A cali-from-wl-dispatch -i cali0ef24b2 -m comment --comment "cali:7hIahXYNmY9JDfKG" -g cali-fw-cali0ef24b2
-A cali-from-wl-dispatch -m comment --comment "cali:YKcphdGNZ1PwfGvt" -m comment --comment "Unknown interface" -j DROP

規則1,cali0ef24b1是slave1-frontend1
規則2,cali0ef24b2是slave1-frontend2

只檢視其中一個,cali-fw-cali0ef24b1@filter:

-A cali-fw-cali0ef24b1 -m comment --comment "cali:KOIFJxkWqvpSMSzk" -j MARK --set-xmark 0x0/0x1000000
-A cali-fw-cali0ef24b1 -m comment --comment "cali:Mm_GAikGLiINmRQh" -m comment --comment "Start of policies" -j MARK --set-xmark 0x0/0x2000000
-A cali-fw-cali0ef24b1 -m comment --comment "cali:c6bGtQzwKsoipZq6" -m mark --mark 0x0/0x2000000 -j cali-po-namespace-default
-A cali-fw-cali0ef24b1 -m comment --comment "cali:46b6gNjtXYDXasAi" -m comment --comment "Return if policy accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-fw-cali0ef24b1 -m comment --comment "cali:6kNf2_vqiCYkwInx" -m comment --comment "Drop if no policies passed packet" -m mark --mark 0x0/0x2000000 -j DROP
-A cali-fw-cali0ef24b1 -m comment --comment "cali:GWdesho87l08Srht" -m comment --comment "Drop if no profiles matched" -j DROP

這個endpoint沒有繫結profile,所以只做了policy的egress規則檢測
規則4,cali-po-namespace-default,policy“namespace-default”的egress規則,po表示policy outbound。

slave2上用於service”database”的endpoint綁定了profile,cali-fw-cali0ef24b3@filter:

-A cali-fw-cali0ef24b3 -m comment --comment "cali:CxOkDjFlTZaT70VP" -j MARK --set-xmark 0x0/0x1000000
-A cali-fw-cali0ef24b3 -m comment --comment "cali:2QQMYVCQs_pXjuNx" -m comment --comment "Start of policies" -j MARK --set-xmark 0x0/0x2000000
-A cali-fw-cali0ef24b3 -m comment --comment "cali:DyV6lV76WK8YZaJX" -m mark --mark 0x0/0x2000000 -j cali-po-namespace-default
-A cali-fw-cali0ef24b3 -m comment --comment "cali:TvuIyAsPjYsOd6oG" -m comment --comment "Return if policy accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-fw-cali0ef24b3 -m comment --comment "cali:TXGkGvhZNM8gWSFv" -m comment --comment "Drop if no policies passed packet" -m mark --mark 0x0/0x2000000 -j DROP
-A cali-fw-cali0ef24b3 -m comment --comment "cali:sc2HAyx9fn5_mw0k" -j cali-pro-profile-database
-A cali-fw-cali0ef24b3 -m comment --comment "cali:LxL3UEOyLww7VztW" -m comment --comment "Return if profile accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-fw-cali0ef24b3 -m comment --comment "cali:PMXWen2JRtHBNBVn" -m comment --comment "Drop if no profiles matched" -j DROP

可以看到,多了一個cali-pro-profile-database的檢測
規則6,cali-pro-profile-database, profile"profile-database"的egress規則,pro表示profile outbound。

policy的egress規則,cali-po-namespace-default@filter:

-A cali-po-namespace-default -m comment --comment "cali:uT-hMQk_SRgHsKxT" -j MARK --set-xmark 0x1000000/0x1000000
-A cali-po-namespace-default -m comment --comment "cali:KDa-ASKrRQu4eYZs" -m mark --mark 0x1000000/0x1000000 -j RETURN

policy“namespace-default”的egress規則是allow,所以規則1直接打了標記"0x1000000/0x1000000"。

slave2上的endpoint繫結的profile規則的egress規則,cali-pro-profile-database@filter:

-A cali-pro-profile-database -m comment --comment "cali:laSwzk9Ihy5ArWJB" -j MARK --set-xmark 0x1000000/0x1000000
-A cali-pro-profile-database -m comment --comment "cali:BpvFNyMPRLC0lDtu" -m mark --mark 0x1000000/0x1000000 -j RETURN

profile-database的egress是allow,直接打標記0x1000000/0x1000000。

路由決策之後:需要轉發的報文

filter.FORWARD:

-A FORWARD -m comment --comment "cali:wUHhoiAYhphO9Mso" -j cali-FORWARD

直接進入cali-FROWARD

filter.cali-FORWARD,根據接收網絡卡做egress規則匹配,根據目標網絡卡做ingress規則匹配:

-A cali-FORWARD -m comment --comment "cali:jxvuJjmmRV135nVu" -m mark --mark 0x1000000/0x1000000 -m conntrack --ctstate UNTRACKED -j ACCEPT
-A cali-FORWARD -m comment --comment "cali:8YeDX9Z0tXyO0Sp8" -m conntrack --ctstate INVALID -j DROP
-A cali-FORWARD -m comment --comment "cali:1GMSV-PhhZ8QbJg4" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A cali-FORWARD -i cali+ -m comment --comment "cali:36TkoGXj9EF7Plkv" -j cali-from-wl-dispatch
-A cali-FORWARD -o cali+ -m comment --comment "cali:URMhBRo8ugd8J8Yx" -j cali-to-wl-dispatch

-A cali-FORWARD -i cali+ -m comment --comment "cali:FyhWsW08U3a5niLK" -j ACCEPT
-A cali-FORWARD -o cali+ -m comment --comment "cali:G655uIfZuidj1gAw" -j ACCEPT

-A cali-FORWARD -m comment --comment "cali:4GbueNC2iWajKnxO" -j MARK --set-xmark 0x0/0x7000000
-A cali-FORWARD -m comment --comment "cali:bq3wVY3mkXk96NQP" -j cali-from-host-endpoint
-A cali-FORWARD -m comment --comment "cali:G8sjbYXH5_QiYnBl" -j cali-to-host-endpoint
-A cali-FORWARD -m comment --comment "cali:wYFYRdMhtSYCqKNm" -m comment --comment "Host endpoint policy accepted packet." -m mark --mark 0x1000000/0x1000000 -j ACCEPT

規則4,報文是workload endpoint發出的,過對應endpoint的規則的egress規則。
規則5,報文要轉發給本地的workload endpoint的,過對應endpoint的ingress規則。

規則6,規則7,預設允許轉發。

規則9,報文是其它node傳送過來的,過host endpoint的ingress規則。
規則10,報文要轉發給host endpoint,過host endpoint的egress規則。

filter.cali-from-wl-dispatch,過對應endpoint的egress規則:

-A cali-from-wl-dispatch -i cali0ef24b1 -m comment --comment "cali:RkM6MKQgU0OTxwKU" -g cali-fw-cali0ef24b1
-A cali-from-wl-dispatch -i cali0ef24b2 -m comment --comment "cali:7hIahXYNmY9JDfKG" -g cali-fw-cali0ef24b2
-A cali-from-wl-dispatch -m comment --comment "cali:YKcphdGNZ1PwfGvt" -m comment --comment "Unknown interface" -j DROP

規則1, 過對應endpoint的inbound規則, fw表示from workload

filter.cali-to-wl-dispatch,過對應endpoint的ingress規則:

-A cali-to-wl-dispatch -o cali0ef24b1 -m comment --comment "cali:ofrbQ8PhcrIR6rgF" -g cali-tw-cali0ef24b1
-A cali-to-wl-dispatch -o cali0ef24b2 -m comment --comment "cali:l9Rs20XXIl4D5AVE" -g cali-tw-cali0ef24b2
-A cali-to-wl-dispatch -m comment --comment "cali:dxGyc_mZA_GT16Wb" -m comment --comment "Unknown interface" -j DROP

規則1,過對應endpoint的規則鏈,tw表示to workload

workload endpoint的outbound規則,在前面已經看過了,這裡省略,只看inbound。

檢視一個workload-endpoint的inbound規則,filter.cali-tw-cali0ef24b1

-A cali-tw-cali0ef24b1 -m comment --comment "cali:v-IVzQuOaLDTvlKQ" -j MARK --set-xmark 0x0/0x1000000
-A cali-tw-cali0ef24b1 -m comment --comment "cali:vE8JWROTKOuSK0cA" -m comment --comment "Start of policies" -j MARK --set-xmark 0x0/0x2000000
-A cali-tw-cali0ef24b1 -m comment --comment "cali:fVy5z1nXaCLhF0EQ" -m mark --mark 0x0/0x2000000 -j cali-pi-namespace-default
-A cali-tw-cali0ef24b1 -m comment --comment "cali:_B9yiomhSoQTzhKL" -m comment --comment "Return if policy accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-tw-cali0ef24b1 -m comment --comment "cali:uNPReN9_BghUJj7S" -m comment --comment "Drop if no policies passed packet" -m mark --mark 0x0/0x2000000 -j DROP

首先過policy的ingress規則,然後過繫結的profile的ingress規則:
規則3: cali-pi-namespace-default,pi表示policy inbound。

filter.cali-pi-namespace-default,policy inbound規則:

-A cali-pi-namespace-default -m comment --comment "cali:K4jTheFcVvdYaw0q" -j DROP
-A cali-pi-namespace-default -m comment --comment "cali:VTQ78plyA8u_8_YC" -m set --match-set cali4-s:CEmFgJFwDvohR01JKvOkO8D src -j MARK --set-xmark 0x1000000/0x1000000
-A cali-pi-namespace-default -m comment --comment "cali:OAWI2ts9a8YpVP2b" -m mark --mark 0x1000000/0x1000000 -j RETURN

注意,規則1直接丟棄了報文,但是規則2又在設定標記,這是因為這裡policy的egress規則設定是有問題的:

ingress:
- action: deny
- action: allow
  source:
    selector: namespace == 'default'

配置了兩條ingress規則,第一條直接deny,第二條則是對指定的source設定為allwo。這樣的規則配置是有問題的。
從上面的iptables規則中也可以看到,iptables規則是按照ingress中的規則順序設定的。
如果第一條規則直接deny,那麼後續的規則就不會發生作用了。
所以結果就是allow規則不生效。

salve1上的workload endpoint沒有繫結profile,所有沒有profile的inbound規則。

slave2上的endpoint設定了profile,允許訪問TCP 3306埠,可以看到profile的inbound規則,filter.cali-tw-cali0ef24b3:

-A cali-tw-cali0ef24b3 -m comment --comment "cali:-l47AwgMbB6upZ-7" -j MARK --set-xmark 0x0/0x1000000
-A cali-tw-cali0ef24b3 -m comment --comment "cali:3qLl7L7-k49jf6Eu" -m comment --comment "Start of policies" -j MARK --set-xmark 0x0/0x2000000
-A cali-tw-cali0ef24b3 -m comment --comment "cali:Q6ycGZQm9W9l4KiJ" -m mark --mark 0x0/0x2000000 -j cali-pi-namespace-default
-A cali-tw-cali0ef24b3 -m comment --comment "cali:_ILnIsDpaSEGOULc" -m comment --comment "Return if policy accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-tw-cali0ef24b3 -m comment --comment "cali:CtKcOQPXG9FZiCN-" -m comment --comment "Drop if no policies passed packet" -m mark --mark 0x0/0x2000000 -j DROP
-A cali-tw-cali0ef24b3 -m comment --comment "cali:NR6mgOGAOw90NLpp" -j cali-pri-profile-database
-A cali-tw-cali0ef24b3 -m comment --comment "cali:_OapaK4JADerp4Fv" -m comment --comment "Return if profile accepted" -m mark --mark 0x1000000/0x1000000 -j RETURN
-A cali-tw-cali0ef24b3 -m comment --comment "cali:ZVuAf3Bzin6dOKSX" -m comment --comment "Drop if no profiles matched" -j DROP

規則6,多出的profile inboud規則。

salve2上的profile的inbound規則,filter.cali-pri-profile-database:

-A cali-pri-profile-database -m comment --comment "cali:viAiQwvuZPt5-44a" -j DROP
-A cali-pri-profile-database -p tcp -m comment --comment "cali:Vcuflyj-wUF-f_Mo" -m set --match-set cali4-s:i357Nlxxj3AMBTQ4WyOllNt src -m multiport --dports 3306 -j MARK --set-xmark 0x1000000/0x1000000
-A cali-pri-profile-database -m comment --comment "cali:JWP_zDo3JNywNc0V" -m mark --mark 0x1000000/0x1000000 -j RETURN

同樣也是因為profile的ingress第一條是deny的原因,規則1直接全部drop。
規則2,允許訪問tcp 3306。

nat.POSTROUTING:

-A cali-POSTROUTING -m comment --comment "cali:Z-c7XtVd2Bq7s_hA" -j cali-fip-snat
-A cali-POSTROUTING -m comment --comment "cali:nYKhEzDlr11Jccal" -j cali-nat-outgoing

這裡沒有設定fip,所以cali-fip-snat和cali-nat-outging都是空的

node傳送本地發出的報文

OUTPUT@nat:

-A OUTPUT -m comment --comment "cali:tVnHkvAo15HuiPy0" -j cali-OUTPUT
-A OUTPUT ! -d 127.0.0.0/8 -m addrtype --dst-type LOCAL -j DOCKER

cali-OUTPUT@nat:

-A cali-OUTPUT -m comment --comment "cali:GBTAv2p5CwevEyJm" -j cali-fip-dnat

OUTPUT@filter:

-A OUTPUT -m comment --comment "cali:tVnHkvAo15HuiPy0" -j cali-OUTPUT

cali-OUTPUT@filter:

-A cali-OUTPUT -m comment --comment "cali:FwFFCT8uDthhfgS7" -m mark --mark 0x1000000/0x1000000 -m conntrack --ctstate UNTRACKED -j ACCEPT
-A cali-OUTPUT -m comment --comment "cali:KQN1p6BZgCGuApYk" -m conntrack --ctstate INVALID -j DROP
-A cali-OUTPUT -m comment --comment "cali:ThMSEAwgeF4nAqRa" -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A cali-OUTPUT -o cali+ -m comment --comment "cali:0YpIH4BWIJL90PfX" -j RETURN
-A cali-OUTPUT -m comment --comment "cali:sUIDpoFnawuqGYyG" -j MARK --set-xmark 0x0/0x7000000
-A cali-OUTPUT -m comment --comment "cali:vQVzNX-dNxUnYjUT" -j cali-to-host-endpoint
-A cali-OUTPUT -m comment --comment "cali:Ry2SAIVyda14xWHB" -m comment --comment "Host endpoint policy accepted packet." -m mark --mark 0x1000000/0x1000000 -j ACCEPT

規則4,如果是傳送到cali網絡卡的,報文不出node,沒有必要繼續匹配了
規則6,過host-endpoint的outbond規則。

POSTROUTING@nat:

-A POSTROUTING -m comment --comment "cali:O3lYWMrLQYEMJtB5" -j cali-POSTROUTING
-A POSTROUTING -s 172.16.163.0/24 ! -o docker0 -j MASQUERADE

nat.cali-POSTROUTING:

-A cali-POSTROUTING -m comment --comment "cali:Z-c7XtVd2Bq7s_hA" -j cali-fip-snat
-A cali-POSTROUTING -m comment --comment "cali:nYKhEzDlr11Jccal" -j cali-nat-outgoing

calico系統的部署

CentOS上安裝

需要提前準備一個etcd,etcd的安裝,這裡不介紹。

安裝calicoctl

calicoctl是calico的管理工具:

wget https://github.com/projectcalico/calicoctl/releases/download/v1.1.0/calicoctl
chmod +x calicoctl

By default calicoctl looks for a configuration file at /etc/calico/calicoctl.cfg:

apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
  datastoreType: "etcdv2"
  etcdEndpoints: "http://etcd1:2379,http://etcd2:2379"
  ...

如果配置檔案不存在,則使用環境變數,spec中的field與環境變數的對應關係:

Spec field     Environment      Examples                 Description   
---------------------------------------------------------------------------
datastoreType  DATASTORE_TYPE    etcdv2               Indicates the datastore to use (optional, defaults to etcdv2)
etcdEndpoints  ETCD_ENDPOINTS    http://etcd1:2379    A comma separated list of etcd endpoints (optional, defaults to http://127.0.0.1:2379)
etcdUsername   ETCD_USERNAME     "user"               Username for RBAC (optional)
etcdPassword   ETCD_PASSWORD     "password"           Password for the given username (optional)
etcdKeyFile    ETCD_KEY_FILE     /etc/calico/key.pem  Path to the etcd key file (optional)     
etcdCertFile   ETCD_CERT_FILE    /etc/calico/cert.pem Path to the etcd client cert (optional)     
etcdCACertFile ETCD_CA_CERT_FILE /etc/calico/ca.pem   Path to the etcd CA file (optional)     

安裝felix

可以直接在每個機器上安裝felix的二進位制檔案,也可以用容器的方式部署felix。

二進位制安裝

或者在每個節點上單獨安裝felix,建立檔案/etc/yum.repos.d/calico.repo,並新增內容:

[calico]
name=calico Repository
baseurl=http://binaries.projectcalico.org/rpm/calico-2.1/
enabled=1
skip_if_unavailable=0
gpgcheck=1
gpgkey=http://binaries.projectcalico.org/rpm/calico-2.1/key
priority=97

安裝:

yum install calico-felix

檢視已經安裝檔案:

$rpm -ql  calico-felix
/etc/calico/felix.cfg.example
/etc/logrotate.d/calico-felix
/usr/bin/calico-felix
/usr/lib/systemd/system/calico-felix.service

$rpm -ql  calico-common
/usr/bin/calico-diags
/usr/bin/calico-gen-bird-conf.sh
/usr/bin/calico-gen-bird-mesh-conf.sh
/usr/bin/calico-gen-bird6-conf.sh
/usr/bin/calico-gen-bird6-mesh-conf.sh
/usr/share/calico/bird/calico-bird-peer.conf.template
/usr/share/calico/bird/calico-bird.conf.template
/usr/share/calico/bird/calico-bird6-peer.conf.template
/usr/share/calico/bird/calico-bird6.conf.template

容器的方式

預設使用的映象quay.io/calico/node,但quay.io在國內被牆,用docker.io中的映象代替:

 docker pull docker.io/calico/node

啟動felix:

calicoctl node run --node-image=docker.io/calico/node:latest

下面是啟動過程中日誌:

Running command to load modules: modprobe -a xt_set ip6_tables
Enabling IPv4 forwarding
Enabling IPv6 forwarding
Increasing conntrack limit
Removing old calico-node container (if running).
Running the following command to start calico-node:

docker run --net=host --privileged --name=calico-node -d --restart=always -e CALICO_NETWORKING_BACKEND=bird -e CALICO_LIBNETWORK_ENABLED=true -e CALICO_LIBNETWORK_CREATE_PROFILES=true -e CALICO_LIBNETWORK_LABEL_ENDPOINTS=false -e ETCD_SCHEME=http -e ETCD_ENDPOINTS= -e NODENAME=compile -e NO_DEFAULT_POOLS= -e IP_AUTODETECTION_METHOD=first-found -e IP6_AUTODETECTION_METHOD=first-found -e CALICO_LIBNETWORK_IFPREFIX=cali -e ETCD_AUTHORITY=127.0.0.1:2379 -v /var/log/calico:/var/log/calico -v /var/run/calico:/var/run/calico -v /lib/modules:/lib/modules -v /run/docker/plugins:/run/docker/plugins -v /var/run/docker.sock:/var/run/docker.sock docker.io/calico/node:latest

Image may take a short time to download if it is not available locally.
Container started, checking progress logs.

Skipping datastore connection test
Using autodetected IPv4 address on interface eth1: 192.168.40.2/24
No AS number configured on node resource, using global value
Created default IPv4 pool (192.168.0.0/16) with NAT outgoing enabled. IPIP mode: off
Created default IPv6 pool (fd80:24e2:f998:72d6::/64) with NAT outgoing enabled. IPIP mode: off
Using node name: compile
Starting libnetwork service
calico node started successfully

從日誌中可以看到,容器使用的是host net、通過-e傳入環境變數。

calico的使用

在calico中,IP被稱為Endpoint,宿主機上的容器IP稱為workloadEndpoint,物理機IP稱為hostEndpoint。ipPool等一同被作為資源管理。

檢視預設的地址段:

./calicoctl get ippool -o wide
CIDR                       NAT    IPIP
192.168.0.0/16             true   false
fd80:24e2:f998:72d6::/64   true   false

node管理

檢視當前node是否滿足執行calico的條件:

calicoctl node <command> [<args>...]

    run          Run the calico node container image.
    status       View the current status of a calico node.
    diags        Gather a diagnostics bundle for a calico node.
    checksystem  Verify the compute host is able to run a calico node instance.

執行時設定

calicoctl config更改calico的配置項.

建立/檢視/更新/刪除資源

分別使用creat/get/replace/delete來建立/檢視/更新/刪除資源。

建立資源:

calicoctl create --filename=<FILENAME> [--skip-exists] [--config=<CONFIG>]

資源使用yaml檔案描述,可以建立以下資源:

node                //物理機
bgpPeer             //與本機建立了bgp連線的node
hostEndpoint 
workloadEndpoint
ipPool 
policy 
profile

檢視資源:

calicoctl get ([--scope=<SCOPE>] [--node=<NODE>] [--orchestrator=<ORCH>]
          [--workload=<WORKLOAD>] (<KIND> [<NAME>]) |
          --filename=<FILENAME>)
          [--output=<OUTPUT>] [--config=<CONFIG>]

可以通過下面命令檢視所有資源:

calicoctl  get  [資源型別]

例如:
    calicoctl get node

IP地址管理

calicoctl ipam <command> [<args>...]

  release      Release a calico assigned IP address.         
  show         Show details of a calico assigned IP address.

測試環境

三臺機器:

etcd: 192.168.40.10:2379
slave1: 192.168.40.11
node2: 192.168.40.12

slave1和node2上的配置檔案:

cat  /etc/calico/calicoctl.cfg
apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
  datastoreType: "etcdv2"
  etcdEndpoints: "http://192.168.40.10:2379"

安裝啟動etcd:

yum install -y etcd
systemctl start etcd

在slave1和slave2上安裝calicoctl並啟動:

yum install -y docker
systemctl start docker
docker pull docker.io/calico/node

wget https://github.com/projectcalico/calicoctl/releases/download/v1.1.0/calicoctl
chmod +x calicoctl

./calicoctl node run --node-image=docker.io/calico/node:latest

檢視狀態

$calicoctl get node
NAME
slave1
slave2

$calicoctl config get nodeTonodeMesh
on

$calicoctl config get logLevel
info

$calicoctl config get asNumber
64512

$calicoctl config get ipip
off

$ calicoctl get bgpPeer
SCOPE   PEERIP   NODE   ASN

$ calicoctl get ipPool
CIDR
172.16.1.0/24
fd80:24e2:f998:72d6::/64

$ calicoctl get workloadEndpoint
NODE   ORCHESTRATOR   WORKLOAD   NAME

模擬一個租戶網路

在名為”default”的namespace中,建立兩個”frontend”和”database”兩個service。

“frontend”有兩個endpoint位於slave1上。

“database”有一個endpoint位於salve2上。

為namespace “default”設定的預設策略是全互通的。

為”database”做了額外設定(“profile”),只允許同一個namespace的中endpoint訪問它的3306埠。

endpoints

一個endpoints屬於哪個namespace、哪個service,都是用labels標記的。lables是完全自定義的。

endpoints.yaml

- apiVersion: v1
  kind: workloadEndpoint
  metadata:
    name: slave1-frontend1
    workload: frontend
    orchestrator: k8s
    node: slave1
    labels:
      service: frontend
      namespace: default
  spec:
    interfaceName: cali0ef24b1
    mac: ca:fe:1d:52:bb:e1
    ipNetworks:
    - 172.16.1.1
- apiVersion: v1
  kind: workloadEndpoint
  metadata:
    name: slave1-frontend2
    workload: frontend
    orchestrator: k8s
    node: slave1
    labels:
      service: frontend
      namespace: default
  spec:
    interfaceName: cali0ef24b2
    mac: ca:fe:1d:52:bb:e2
    ipNetworks:
    - 172.16.1.2
- apiVersion: v1
  kind: workloadEndpoint
  metadata:
    name: slave2-database
    workload: database
    orchestrator: k8s
    node: slave2
    labels:
      service: database
      namespace: default
  spec:
    interfaceName: cali0ef24b3
    mac: ca:fe:1d:52:bb:e3
    ipNetworks:
    - 172.16.1.3
    profiles:
    - profile-database

建立:

$calicoctl create -f endpoints.yaml
Successfully created 3 'workloadEndpoint' resource(s)

檢視:

$ calicoctl get workloadEndpoints -o wide
NODE     ORCHESTRATOR   WORKLOAD   NAME               NETWORKS        NATS   INTERFACE     PROFILES
slave1   k8s            frontend   slave1-frontend1   172.16.1.1/32          cali0ef24b1
slave1   k8s            frontend   slave1-frontend2   172.16.1.2/32          cali0ef24b2
slave2   k8s            database   slave2-database    172.16.1.3/32          cali0ef24b3

policy

為namespace”default”設定的policy,namespace內部互通。

apiVersion: v1
kind: policy
metadata:
  name: namespace-default
spec:
  selector: namespace == 'default'
  ingress:
  - action: allow
    source:
      selector: namespace == 'default'
  egress:
  - action: allow

profile

為service”database”設定的profile,只允許訪問3306埠。

apiVersion: v1
kind: profile
metadata:
  name: profile-database
  labels:
    profile: profile-database
spec:
  ingress:
  - action: deny        <-- 這個規則是有問題的,第一條規則直接drop,就不會進入第二天規則了
  - action: allow           這裡故意保留了這個有問題的設定,在下面分析時候,就會遇到這個問題的根源。
    source:
      selector: namespace == 'default' && service == 'frontend'
    ports:
      - int: 3306
  egress:
  - action: allow

參考

  1. 洪強寧:宜信PaaS平臺基於calico的容器
  2. calico architecture
  3. felix code
  4. felix bare-metal-install
  5. calicoctl
  6. calicoctl config
  7. calicoctl resource definitions
  8. Battlefield-calico-Flannel-Weave-and-Docker-Overlay-Network
  9. calico bgpPeer
  10. AS Per Rack model
  11. calico over an Ethernet interconnect fabric
  12. bird
  13. ECMP
  14. calico over ip fabrics
  15. Use of BGP for routing in large-scale data centers
  16. RFC 4893 - BGP Support for Four-octet AS Num