Calico网络的原理、组网方式与使用
目錄
目錄
calico
名詞解釋
組網(wǎng)原理
BGP與AS
BGP Speaker 全互聯(lián)模式(node-to-node mesh)
BGP Speaker RR模式
calico網(wǎng)絡(luò)的部署
calico在Ethernet interconnect fabric中的部署方式
calico在ip fabric中的部署方式
AS per rack
AS per server
優(yōu)化:“Downward Default model”減少需要記錄的路由
calico系統(tǒng)結(jié)構(gòu)
calico中的概念
bgpPeer
ipPool
node
policy
profile
workloadEndpoint
hostEndpoint
node的報(bào)文處理過(guò)程
路由決策之前:流入node的報(bào)文的處理
進(jìn)入raw表
進(jìn)入nat表
路由決策之后:發(fā)送到本node的host endpoint 和 workload endpoint
進(jìn)入filter表
來(lái)自其它node的報(bào)文
來(lái)自本node上workload endpoint的報(bào)文
路由決策之后:需要轉(zhuǎn)發(fā)的報(bào)文
node發(fā)送本地發(fā)出的報(bào)文
calico系統(tǒng)的部署
CentOS上安裝
安裝calicoctl
安裝felix
二進(jìn)制安裝
容器的方式
calico的使用
node管理
運(yùn)行時(shí)設(shè)置
創(chuàng)建/查看/更新/刪除資源
IP地址管理
測(cè)試環(huán)境
查看狀態(tài)
模擬一個(gè)租戶網(wǎng)絡(luò)
endpoints
policy
profile
參考
calico
calico是一個(gè)比較有趣的虛擬網(wǎng)絡(luò)解決方案,完全利用路由規(guī)則實(shí)現(xiàn)動(dòng)態(tài)組網(wǎng),通過(guò)BGP協(xié)議通告路由。
calico的好處是endpoints組成的網(wǎng)絡(luò)是單純的三層網(wǎng)絡(luò),報(bào)文的流向完全通過(guò)路由規(guī)則控制,沒(méi)有overlay等額外開銷。
calico的endpoint可以漂移,并且實(shí)現(xiàn)了acl。
calico的缺點(diǎn)是路由的數(shù)目與容器數(shù)目相同,非常容易超過(guò)路由器、三層交換、甚至node的處理能力,從而限制了整個(gè)網(wǎng)絡(luò)的擴(kuò)張。
calico的每個(gè)node上會(huì)設(shè)置大量(海量)的iptables規(guī)則、路由,運(yùn)維、排障難度大。
calico的原理決定了它不可能支持VPC,容器只能從calico設(shè)置的網(wǎng)段中獲取ip。
calico目前的實(shí)現(xiàn)沒(méi)有流量控制的功能,會(huì)出現(xiàn)少數(shù)容器搶占node多數(shù)帶寬的情況。
calico的網(wǎng)絡(luò)規(guī)模受到BGP網(wǎng)絡(luò)規(guī)模的限制。
名詞解釋
endpoint: 接入到calico網(wǎng)絡(luò)中的網(wǎng)卡稱為endpoint
AS: 網(wǎng)絡(luò)自治系統(tǒng),通過(guò)BGP協(xié)議與其它AS網(wǎng)絡(luò)交換路由信息
ibgp: AS內(nèi)部的BGP Speaker,與同一個(gè)AS內(nèi)部的ibgp、ebgp交換路由信息。
ebgp: AS邊界的BGP Speaker,與同一個(gè)AS內(nèi)部的ibgp、其它AS的ebgp交換路由信息。
workloadEndpoint: 虛擬機(jī)、容器使用的endpoint
hostEndpoints: 物理機(jī)(node)的地址
組網(wǎng)原理
calico組網(wǎng)的核心原理就是IP路由,每個(gè)容器或者虛擬機(jī)會(huì)分配一個(gè)workload-endpoint(wl)。
從nodeA上的容器A內(nèi)訪問(wèn)nodeB上的容器B時(shí):
+--------------------+ +--------------------+
| +------------+ | | +------------+ |
| | | | | | | |
| | ConA | | | | ConB | |
| | | | | | | |
| +-----+------+ | | +-----+------+ |
| |veth | | |veth |
| wl-A | | wl-B |
| | | | | |
+-------node-A-------+ +-------node-B-------+
| | | |
| | type1. in the same lan | |
| +-------------------------------+ |
| |
| type2. in different network |
| +-------------+ |
| | | |
+-------------+ Routers |-------------+
| |
+-------------+
從ConA中發(fā)送給ConB的報(bào)文被nodeA的wl-A接收,根據(jù)nodeA上的路由規(guī)則,經(jīng)過(guò)各種iptables規(guī)則后,轉(zhuǎn)發(fā)到nodeB。
如果nodeA和nodeB在同一個(gè)二層網(wǎng)段,下一條地址直接就是node-B,經(jīng)過(guò)二層交換機(jī)即可到達(dá)。
如果nodeA和nodeB在不同的網(wǎng)段,報(bào)文被路由到下一跳,經(jīng)過(guò)三層交換或路由器,一步步跳轉(zhuǎn)到node-B。
核心問(wèn)題是,nodeA怎樣得知下一跳的地址?答案是node之間通過(guò)BGP協(xié)議交換路由信息。
每個(gè)node上運(yùn)行一個(gè)軟路由軟件bird,并且被設(shè)置成BGP Speaker,與其它node通過(guò)BGP協(xié)議交換路由信息。
可以簡(jiǎn)單理解為,每一個(gè)node都會(huì)向其它node通知這樣的信息:
我是X.X.X.X,某個(gè)IP或者網(wǎng)段在我這里,它們的下一跳地址是我。
通過(guò)這種方式每個(gè)node知曉了每個(gè)workload-endpoint的下一跳地址。
BGP與AS
BGP是路由器之間的通信協(xié)議,主要用于AS(Autonomous System,自治系統(tǒng))之間的互聯(lián)。
AS是一個(gè)自治的網(wǎng)絡(luò),擁有獨(dú)立的交換機(jī)、路由器等,可以獨(dú)立運(yùn)轉(zhuǎn)。
每個(gè)AS擁有一個(gè)全球統(tǒng)一分配的16位的ID號(hào),64512到65535共1023個(gè)AS號(hào)碼可以用于私有網(wǎng)絡(luò)。
calico默認(rèn)使用的AS號(hào)是64512,可以修改:
calicoctl config get asNumber //查看
calicoctl config set asNumber 64512 //設(shè)置
AS內(nèi)部有多個(gè)BGP speaker,分為ibgp、ebgp,ebgp與其它AS中的ebgp建立BGP連接。
AS內(nèi)部的BGP speaker通過(guò)BGP協(xié)議交換路由信息,最終每一個(gè)BGP speaker擁有整個(gè)AS的路由信息。
BGP speaker一般是網(wǎng)絡(luò)中的物理路由器,可以形象的理解為:
calico將node改造成了一個(gè)軟路由器(通過(guò)軟路由軟件bird)
node上的運(yùn)行的虛擬機(jī)或者容器通過(guò)node與外部溝通
AS內(nèi)部的BGP Speaker之間有兩種互聯(lián)方式:
Mesh: BGP Speaker之間全互聯(lián),網(wǎng)絡(luò)成網(wǎng)狀
RR: Router reflection模式,BGP Speaker連接到一個(gè)或多個(gè)中心BGP Speaker,網(wǎng)絡(luò)成星狀
BGP Speaker 全互聯(lián)模式(node-to-node mesh)
全互聯(lián)模式,就是一個(gè)BGP Speaker需要與其它所有的BGP Speaker建立bgp連接(形成一個(gè)bgp mesh)。
網(wǎng)絡(luò)中bgp總連接數(shù)是按照O(n^2)增長(zhǎng)的,有太多的BGP Speaker時(shí),會(huì)消耗大量的連接。
calico默認(rèn)使用全互聯(lián)的方式,擴(kuò)展性比較差,只能支持小規(guī)模集群:
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
可以打開/關(guān)閉全互聯(lián)模式:
calicoctl config set nodeTonodeMesh off
calicoctl config set nodeTonodeMesh on
BGP Speaker RR模式
RR模式,就是在網(wǎng)絡(luò)中指定一個(gè)或多個(gè)BGP Speaker作為Router Reflection,RR與所有的BGP Speaker建立BGP連接。
每個(gè)BGP Speaker只需要與RR交換路由信息,就可以得到全網(wǎng)路由信息。
RR則必須與所有的BGP Speaker建立BGP連接,以保證能夠得到全網(wǎng)路由信息。
在calico中可以通過(guò)Global Peer實(shí)現(xiàn)RR模式。
Global Peer是一個(gè)BGP Speaker,需要手動(dòng)在calico中創(chuàng)建,所有的node都會(huì)與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).
關(guān)閉了全互聯(lián)模式后,再將RR作為Global Peers添加到calico中,calico網(wǎng)絡(luò)就切換到了RR模式,可以支撐容納更多的node。
calico中也可以通過(guò)node Peer手動(dòng)構(gòu)建BGP Speaker(也就是node)之間的BGP連接。
node Peer就是手動(dòng)創(chuàng)建的BGP Speaker,只有指定的node會(huì)與其建立連接。
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.
因此,可以為每一個(gè)node指定不同的BGP Peer,實(shí)現(xiàn)更精細(xì)的規(guī)劃。
例如當(dāng)集群規(guī)模進(jìn)一步擴(kuò)大的時(shí)候,可以使用AS Per Pack model:
每個(gè)機(jī)架是一個(gè)AS
node只與所在機(jī)架TOR交換機(jī)建立BGP連接
TOR交換機(jī)之間作為各自的ebgp全互聯(lián)
calico網(wǎng)絡(luò)的部署
calico網(wǎng)絡(luò)對(duì)底層的網(wǎng)絡(luò)的要求很少,只要求node之間能夠通過(guò)IP聯(lián)通。
Any technology that is capable of transporting IP packets can be used as the interconnect fabric in a Calico network.
在calico中,全網(wǎng)路由的數(shù)目和endpoints的數(shù)目一致,通過(guò)為node分配網(wǎng)段,可以減少路由數(shù)目,但不會(huì)改變數(shù)量級(jí)。
如果有1萬(wàn)個(gè)endpoints,那么就至少要有一臺(tái)能夠處理1萬(wàn)條路由的設(shè)備。
無(wú)論用哪種方式部署始終會(huì)有一臺(tái)設(shè)備上存放著calico全網(wǎng)的路由。
當(dāng)要部署calico網(wǎng)絡(luò)的時(shí)候,第一步就是要確認(rèn),網(wǎng)絡(luò)中處理能力最強(qiáng)的設(shè)備最多能設(shè)置多少條路由。
calico在Ethernet interconnect fabric中的部署方式
calico over an Ethernet interconnect fabric中介紹了在Ethernet interconnect fabric部署calico網(wǎng)絡(luò)方案。在每個(gè)vlan中部署一套calico。
為了保證鏈路可靠,圖中設(shè)計(jì)了四個(gè)并列的二層網(wǎng),形成fabric。
每個(gè)node同時(shí)接入四個(gè)二層網(wǎng)絡(luò),對(duì)應(yīng)擁有四個(gè)不同網(wǎng)段的IP。
在每個(gè)二層網(wǎng)絡(luò)中,node與node之間用RR模式建立BGP通信鏈路:
一個(gè)node做為RR,其余的node連接到做為RR的node
整個(gè)網(wǎng)絡(luò)中最終有四個(gè)RR,分別負(fù)責(zé)四個(gè)網(wǎng)絡(luò)中的BGP
當(dāng)從node上去訪問(wèn)另一個(gè)node上的endpoint的時(shí)候,會(huì)有四條下一跳為不同網(wǎng)段的等價(jià)路由。
根據(jù)ECMP協(xié)議,報(bào)文將會(huì)平均分配給這四個(gè)等價(jià)路由,提高了可靠性的同時(shí)增加了網(wǎng)絡(luò)的吞吐能力。
calico在ip fabric中的部署方式
如果底層的網(wǎng)絡(luò)是ip fabric的方式,三層網(wǎng)絡(luò)是可靠的,只需要部署一套calico。
剩下的關(guān)鍵點(diǎn)就是怎樣設(shè)計(jì)BGP網(wǎng)絡(luò),calico over ip fabrics中給出兩種設(shè)計(jì)方式:
1. AS per rack: 每個(gè)rack(機(jī)架)組成一個(gè)AS,每個(gè)rack的TOR交換機(jī)與核心交換機(jī)組成一個(gè)AS
2. AS per server: 每個(gè)node做為一個(gè)AS,TOR交換機(jī)組成一個(gè)transit AS
這兩種方式采用的是Use of BGP for routing in large-scale data centers中的建議。
AS per rack
1. 一個(gè)機(jī)架作為一個(gè)AS,分配一個(gè)AS號(hào),node是ibgp,TOR交換機(jī)是ebgp
2. node只與TOR交換機(jī)建立BGP連接,TOR交換機(jī)與機(jī)架上的所有node建立BGP連接
3. 所有TOR交換機(jī)之間以node-to-node mesh方式建立BGP連接
TOR交換機(jī)之間可以是接入到同一個(gè)核心交換機(jī)二層可達(dá)的,也可以只是IP可達(dá)的。
TOR二層聯(lián)通:
TOR三層聯(lián)通:
每個(gè)機(jī)架上node的數(shù)目是有限的,BGP壓力轉(zhuǎn)移到了TOR交換機(jī)。當(dāng)機(jī)架數(shù)很多,TOR交換機(jī)組成BGP mesh壓力會(huì)過(guò)大。
endpoints之間的通信過(guò)程:
EndpointA發(fā)出報(bào)文 --> nodeA找到了下一跳地址nodeB --> 報(bào)文送到TOR交換機(jī)A --> 報(bào)文送到核心交換機(jī)
|
v
EndpointB收到了報(bào)文 <-- nodeB收到了報(bào)文 <-- TOR交換機(jī)B收到了報(bào)文 <-- 核心交換機(jī)將報(bào)文送達(dá)TOR交換機(jī)B
AS per server
1. 每個(gè)TOR交換機(jī)占用一個(gè)AS
2. 每個(gè)node占用一個(gè)AS
3. node與TOR交換機(jī)交換BGP信息
3. 所有的TOR交換機(jī)組成BGP mesh,交換BGP信息
這種方式消耗了大量的AS,RFC 4893 - BGP Support for Four-octet AS Number Space中考慮將AS號(hào)增加到32位。
不是特別明白這種方式的好處在哪里。
TOR二層聯(lián)通:
TOR三層聯(lián)通:
優(yōu)化:“Downward Default model”減少需要記錄的路由
Downward Default Model在上面的幾種組網(wǎng)方式的基礎(chǔ)上,優(yōu)化了路由的管理。
在上面的三種方式中,每個(gè)node、每個(gè)TOR交換機(jī)、每個(gè)核心交換機(jī)都需要記錄全網(wǎng)路由。
“Downward Default model”模式中:
1. 每個(gè)node向上(TOR)通告所有路由信息,而TOR向下(node)只通告一條默認(rèn)路由
2. 每個(gè)TOR向上(核心交換機(jī))通告所有路由,核心交換機(jī)向下(TOR)只通告一條默認(rèn)路由
3. node只知曉本地的路由
4. TOR只知道接入到自己的所有node上的路由
5. 核心交換機(jī)知曉所有的路由
這種模式減少了TOR交換機(jī)和node上的路由數(shù)量,但缺點(diǎn)是,發(fā)送到無(wú)效IP的流量必須到達(dá)核心交換機(jī)以后,才能被確定為無(wú)效。
endpoints之間的通信過(guò)程:
EndpointA發(fā)出報(bào)文 --> nodeA默認(rèn)路由到TOR交換機(jī)A --> TOR交換機(jī)A默認(rèn)路由到核心交換機(jī) --+
|
v
EndpointB收到了報(bào)文 <-- nodeB收到了報(bào)文 <-- TOR交換機(jī)B收到了報(bào)文 <-- 核心交換機(jī)找到了下一跳地址nodeB
calico系統(tǒng)結(jié)構(gòu)
calico系統(tǒng)組成:
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負(fù)責(zé)管理設(shè)置node,
bird是一個(gè)開源的軟路由,支持多種路由協(xié)議。
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的報(bào)文處理過(guò)程
報(bào)文處理過(guò)程中使用的標(biāo)記位:
一共使用了3個(gè)標(biāo)記位,0x7000000對(duì)應(yīng)的標(biāo)記位
0x1000000: 報(bào)文的處理動(dòng)作,置1表示放行,默認(rèn)0表示拒絕
0x2000000: 是否已經(jīng)經(jīng)過(guò)了policy規(guī)則檢測(cè),置1表示已經(jīng)過(guò)
0x4000000: 報(bào)文來(lái)源,置1,表示來(lái)自host-endpoint
流入報(bào)文來(lái)源:
1. 以cali+命名的網(wǎng)卡收到的報(bào)文,這部分報(bào)文是node上的endpoint發(fā)出的
(k8s中,容器的內(nèi)發(fā)出的所有報(bào)文都會(huì)發(fā)送到對(duì)應(yīng)的cali網(wǎng)卡上)
(通過(guò)在容器內(nèi)添加靜態(tài)arp,將容器網(wǎng)關(guān)的IP映射到cali網(wǎng)卡的MAC上實(shí)現(xiàn))
2. 其他網(wǎng)卡接收的報(bào)文,這部分報(bào)文是其它node發(fā)送或者在node本地發(fā)出的
流入的報(bào)文去向:
1. 訪問(wèn)本node的host endpoint,通過(guò)INPUT過(guò)程處理
2. 訪問(wèn)本node的workload endpoint,通過(guò)INPUT過(guò)程處理
3. 訪問(wèn)其它node的host endpoint,通過(guò)FORWARD過(guò)程處理。
4. 訪問(wèn)其它node的workload endpoint,通過(guò)FORWARD過(guò)程處理。
流入的報(bào)文在路由決策之前的處理過(guò)程相同的,路由決策之后,分別進(jìn)入INPUT規(guī)則鏈和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的版本比較老,和最新版中的規(guī)則有一些出入,但是原理相同。
新版本的calico的iptables規(guī)則可讀性更好,可以直接閱讀規(guī)則。
報(bào)文處理流程(全):
from-XXX: XXX發(fā)出的報(bào)文 tw: 簡(jiǎn)寫,to wordkoad endpoint
to-XXX: 發(fā)送到XXX的報(bào)文 po: 簡(jiǎn)寫,policy outbound
cali-: 前綴,calico的規(guī)則鏈 pi: 簡(jiǎn)寫,policy inbound
wl: 簡(jiǎn)寫,workload endpoint pro: 簡(jiǎn)寫,profile outbound
fw: 簡(jiǎn)寫,from workload endpoint pri: 簡(jiǎn)寫,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本地發(fā)出的報(bào)文,經(jīng)過(guò)路由決策之后,直接進(jìn)入raw,OUTPUT規(guī)則鏈:
raw.OUTPUT -> mangle.OUTPUT -> nat.OUTPUT -> filter.OUTPUT -> mangle.POSTROUTING -> nat.POSTROUTING
路由決策之前:流入node的報(bào)文的處理
進(jìn)入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
規(guī)則1,清空所有標(biāo)記
規(guī)則2,從cali+網(wǎng)卡進(jìn)入的報(bào)文,設(shè)置mark: 0x4000000/0x4000000
規(guī)則3,非cali+網(wǎng)卡收到的報(bào)文,即從host-endpoint進(jìn)入的報(bào)文,進(jìn)入cali-from-host-endpoints規(guī)則鏈條
這里沒(méi)有設(shè)置host-endpoint的策略,所有cali-from-host-endpoint規(guī)則鏈?zhǔn)强盏摹?/p>
進(jìn)入nat表
PREROUTING@nat:
-A PREROUTING -m comment --comment "cali:6gwbT8clXdHdC1b1" -j cali-PREROUTING
-A PREROUTING -m addrtype --dst-type LOCAL -j DOCKER
直接進(jìn)入cali-PREROUTING
cali-PREROUTING@nat:
-A cali-PREROUTING -m comment --comment "cali:r6XmIziWUJsdOK6Z" -j cali-fip-dnat
如果目標(biāo)地址是fip(floating IP),會(huì)在cali-fip-dnat中做dnat轉(zhuǎn)換
nat表中做目的IP轉(zhuǎn)換,這里沒(méi)有設(shè)置,所以cali-fip-dnat是空的。
經(jīng)過(guò)nat表之后,會(huì)進(jìn)行路由決策:
1. 如果是發(fā)送給slave1的報(bào)文,經(jīng)過(guò)規(guī)則鏈: INPUT@mangle、INPUT@filter
2. 如果不是發(fā)送給slave1報(bào)文,經(jīng)過(guò)規(guī)則鏈: FORWARD@mangle、FORWARD@filer、POSTROUTING@mangle、POSTROUTING@nat
路由決策之后:發(fā)送到本node的host endpoint 和 workload endpoint
進(jìn)入filter表
INPUT@filter:
-A INPUT -m comment --comment "cali:Cz_u1IQiXIMmKD4c" -j cali-INPUT
直接進(jìn)入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
規(guī)則4,從cali+網(wǎng)卡進(jìn)入的報(bào)文,進(jìn)入wl-to-host的規(guī)則鏈,wl是workload的縮
規(guī)則6,非cali+網(wǎng)卡收到的報(bào)文,host-endpoint的規(guī)則鏈
來(lái)自其它node的報(bào)文
這里沒(méi)有對(duì)host endpoint設(shè)置規(guī)則,所以規(guī)則鏈時(shí)空
cali-from-host-endpoint@filter:
空
來(lái)自本node上workload endpoint的報(bào)文
檢察一下是否允許workload enpoint發(fā)出這些報(bào)文。
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
規(guī)則1,允許請(qǐng)求DHCP
規(guī)則2,允許請(qǐng)求DNS
規(guī)則3,匹配workload endpoint各自的規(guī)則,將會(huì)依次檢察policy的egress、各自綁定的profile的egress。
根據(jù)接收?qǐng)?bào)文的網(wǎng)卡做區(qū)分,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
規(guī)則1,cali0ef24b1是slave1-frontend1
規(guī)則2,cali0ef24b2是slave1-frontend2
只查看其中一個(gè),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
這個(gè)endpoint沒(méi)有綁定profile,所以只做了policy的egress規(guī)則檢測(cè)
規(guī)則4,cali-po-namespace-default,policy“namespace-default”的egress規(guī)則,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
可以看到,多了一個(gè)cali-pro-profile-database的檢測(cè)
規(guī)則6,cali-pro-profile-database, profile"profile-database"的egress規(guī)則,pro表示profile outbound。
policy的egress規(guī)則,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規(guī)則是allow,所以規(guī)則1直接打了標(biāo)記"0x1000000/0x1000000"。
slave2上的endpoint綁定的profile規(guī)則的egress規(guī)則,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,直接打標(biāo)記0x1000000/0x1000000。
路由決策之后:需要轉(zhuǎn)發(fā)的報(bào)文
filter.FORWARD:
-A FORWARD -m comment --comment "cali:wUHhoiAYhphO9Mso" -j cali-FORWARD
直接進(jìn)入cali-FROWARD
filter.cali-FORWARD,根據(jù)接收網(wǎng)卡做egress規(guī)則匹配,根據(jù)目標(biāo)網(wǎng)卡做ingress規(guī)則匹配:
-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
規(guī)則4,報(bào)文是workload endpoint發(fā)出的,過(guò)對(duì)應(yīng)endpoint的規(guī)則的egress規(guī)則。
規(guī)則5,報(bào)文要轉(zhuǎn)發(fā)給本地的workload endpoint的,過(guò)對(duì)應(yīng)endpoint的ingress規(guī)則。
規(guī)則6,規(guī)則7,默認(rèn)允許轉(zhuǎn)發(fā)。
規(guī)則9,報(bào)文是其它node發(fā)送過(guò)來(lái)的,過(guò)host endpoint的ingress規(guī)則。
規(guī)則10,報(bào)文要轉(zhuǎn)發(fā)給host endpoint,過(guò)host endpoint的egress規(guī)則。
filter.cali-from-wl-dispatch,過(guò)對(duì)應(yīng)endpoint的egress規(guī)則:
-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
規(guī)則1, 過(guò)對(duì)應(yīng)endpoint的inbound規(guī)則, fw表示from workload
filter.cali-to-wl-dispatch,過(guò)對(duì)應(yīng)endpoint的ingress規(guī)則:
-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
規(guī)則1,過(guò)對(duì)應(yīng)endpoint的規(guī)則鏈,tw表示to workload
workload endpoint的outbound規(guī)則,在前面已經(jīng)看過(guò)了,這里省略,只看inbound。
查看一個(gè)workload-endpoint的inbound規(guī)則,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
首先過(guò)policy的ingress規(guī)則,然后過(guò)綁定的profile的ingress規(guī)則:
規(guī)則3: cali-pi-namespace-default,pi表示policy inbound。
filter.cali-pi-namespace-default,policy inbound規(guī)則:
-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
注意,規(guī)則1直接丟棄了報(bào)文,但是規(guī)則2又在設(shè)置標(biāo)記,這是因?yàn)檫@里policy的egress規(guī)則設(shè)置是有問(wèn)題的:
ingress:
- action: deny
- action: allow
source:
selector: namespace == 'default'
配置了兩條ingress規(guī)則,第一條直接deny,第二條則是對(duì)指定的source設(shè)置為allwo。這樣的規(guī)則配置是有問(wèn)題的。
從上面的iptables規(guī)則中也可以看到,iptables規(guī)則是按照ingress中的規(guī)則順序設(shè)定的。
如果第一條規(guī)則直接deny,那么后續(xù)的規(guī)則就不會(huì)發(fā)生作用了。
所以結(jié)果就是allow規(guī)則不生效。
salve1上的workload endpoint沒(méi)有綁定profile,所有沒(méi)有profile的inbound規(guī)則。
slave2上的endpoint設(shè)置了profile,允許訪問(wèn)TCP 3306端口,可以看到profile的inbound規(guī)則,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
規(guī)則6,多出的profile inboud規(guī)則。
salve2上的profile的inbound規(guī)則,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
同樣也是因?yàn)閜rofile的ingress第一條是deny的原因,規(guī)則1直接全部drop。
規(guī)則2,允許訪問(wèn)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
這里沒(méi)有設(shè)置fip,所以cali-fip-snat和cali-nat-outging都是空的
node發(fā)送本地發(fā)出的報(bào)文
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
規(guī)則4,如果是發(fā)送到cali網(wǎng)卡的,報(bào)文不出node,沒(méi)有必要繼續(xù)匹配了
規(guī)則6,過(guò)host-endpoint的outbond規(guī)則。
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系統(tǒng)的部署
CentOS上安裝
需要提前準(zhǔn)備一個(gè)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"
...
如果配置文件不存在,則使用環(huán)境變量,spec中的field與環(huán)境變量的對(duì)應(yīng)關(guān)系:
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
可以直接在每個(gè)機(jī)器上安裝felix的二進(jìn)制文件,也可以用容器的方式部署felix。
二進(jìn)制安裝
或者在每個(gè)節(jié)點(diǎn)上單獨(dú)安裝felix,創(chuàng)建文件/etc/yum.repos.d/calico.repo,并添加內(nèi)容:
[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
查看已經(jīng)安裝文件:
$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
容器的方式
默認(rèn)使用的鏡像quay.io/calico/node,但quay.io在國(guó)內(nèi)被墻,用docker.io中的鏡像代替:
docker pull docker.io/calico/node
啟動(dòng)felix:
calicoctl node run --node-image=docker.io/calico/node:latest
下面是啟動(dòng)過(guò)程中日志:
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、通過(guò)-e傳入環(huán)境變量。
calico的使用
在calico中,IP被稱為Endpoint,宿主機(jī)上的容器IP稱為workloadEndpoint,物理機(jī)IP稱為hostEndpoint。ipPool等一同被作為資源管理。
查看默認(rèn)的地址段:
./calicoctl get ippool -o wide
CIDR NAT IPIP
192.168.0.0/16 true false
fd80:24e2:f998:72d6::/64 true false
node管理
查看當(dāng)前node是否滿足運(yùn)行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.
運(yùn)行時(shí)設(shè)置
calicoctl config更改calico的配置項(xiàng).
創(chuàng)建/查看/更新/刪除資源
分別使用creat/get/replace/delete來(lái)創(chuàng)建/查看/更新/刪除資源。
創(chuàng)建資源:
calicoctl create --filename=<FILENAME> [--skip-exists] [--config=<CONFIG>]
資源使用yaml文件描述,可以創(chuàng)建以下資源:
node //物理機(jī)
bgpPeer //與本機(jī)建立了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>]
可以通過(guò)下面命令查看所有資源:
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.
測(cè)試環(huán)境
三臺(tái)機(jī)器:
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"
安裝啟動(dòng)etcd:
yum install -y etcd
systemctl start etcd
在slave1和slave2上安裝calicoctl并啟動(dòng):
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
查看狀態(tài)
$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
模擬一個(gè)租戶網(wǎng)絡(luò)
在名為”default”的namespace中,創(chuàng)建兩個(gè)”frontend”和”database”兩個(gè)service。
“frontend”有兩個(gè)endpoint位于slave1上。
“database”有一個(gè)endpoint位于salve2上。
為namespace “default”設(shè)置的默認(rèn)策略是全互通的。
為”database”做了額外設(shè)置(“profile”),只允許同一個(gè)namespace的中endpoint訪問(wèn)它的3306端口。
endpoints
一個(gè)endpoints屬于哪個(gè)namespace、哪個(gè)service,都是用labels標(biāo)記的。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
創(chuàng)建:
$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”設(shè)置的policy,namespace內(nèi)部互通。
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”設(shè)置的profile,只允許訪問(wèn)3306端口。
apiVersion: v1
kind: profile
metadata:
name: profile-database
labels:
profile: profile-database
spec:
ingress:
- action: deny <-- 這個(gè)規(guī)則是有問(wèn)題的,第一條規(guī)則直接drop,就不會(huì)進(jìn)入第二天規(guī)則了
- action: allow 這里故意保留了這個(gè)有問(wèn)題的設(shè)置,在下面分析時(shí)候,就會(huì)遇到這個(gè)問(wèn)題的根源。
source:
selector: namespace == 'default' && service == 'frontend'
ports:
- int: 3306
egress:
- action: allow
參考
洪強(qiáng)寧:宜信PaaS平臺(tái)基于calico的容器
calico architecture
felix code
felix bare-metal-install
calicoctl
calicoctl config
calicoctl resource definitions
Battlefield-calico-Flannel-Weave-and-Docker-Overlay-Network
calico bgpPeer
AS Per Rack model
calico over an Ethernet interconnect fabric
bird
ECMP
calico over ip fabrics
Use of BGP for routing in large-scale data centers
RFC 4893 - BGP Support for Four-octet AS Number Space
總結(jié)
以上是生活随笔為你收集整理的Calico网络的原理、组网方式与使用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 《像艺术家一样思考》 Think Lik
- 下一篇: rancher学习:rancher组成