基于Kubeadm的Flannel分析

Flannel概述


Flannel是將多個不同子網(基于主機Node)通過被Flannel維護的Overlay網絡拼接成為一張大網來實現互聯的,通過官方的一張網絡拓撲圖我們可以對其基本原理一目了然:

值得探討的是,flannel的這個overlay網絡支持多種后端實現,除上圖中的UDP,還有VXLAN和host-gw等。此外,flannel支持通過兩種模式來維護隧道端點上FDB的信息,其中一種是通過連接Etcd來實現,另外一種是直接對接K8S,通過K8S添加刪除Node來觸發更新。

Flannel部署常見問題

1. Node狀態顯示為“NotReady”

我的K8S環境使用kubeadm來容器化運行K8S的各個組件(除kubelet直接運行在裸機上外),當我使用kubeadm join命令加入新的Minion Node到K8S集群中后,通過kubectl get node會發現所有的node都還是not ready狀態,這是因為還沒有配置好flannel網絡。

2. 使用kube-flannel.yml無法創建DaemonSet

我使用的是K8S的1.6.4的版本,然后按照官方的說明,使用kube-flannel.yml來創建flannel deamon set,結果始終報錯。正確的姿勢是先使用kube-flannel-rbac.yml來創建flannel的ClusterRole并授權。該yml的主要作用是創建名叫flannel的ClusterRole,然后將該ClusterRole與ServiceAccount(flannel)綁定。接下來,當我們使用kube-flannel.yml來創建flannel daemon set的時候,該daemon set明確指定其Pod的ServiceAccount為flannel,于是通過它啟動起來的Pod就具有了flannel ClusterRole中指定的權限。

3.flannel Pod狀態為Running,網絡不通

我之前在我的Mac Pro上跑了三個VM,為了能夠訪問公網拉取鏡像,我為每個VM分配了一張網卡使用NAT模式,其分配到的IP地址可能重啟后發生變化。另外,為了我本機方便管理,我為每臺VM又分配了一張網卡使用Host-Only網絡模式,每個網卡都有一個固定的IP地址方便SSH。然后,奇怪的事情就這樣發生了….

原因在與在kube-flannel.yml中,kube-flannel容器的command被指定為:

command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr"]

可見,其并沒有指定使用哪一張網卡作為flanneld對外通信的物理網卡,于是,可能由于機器上面路由配置的差異,導致三臺機器并沒有一致通過Host-Only網絡模式的網卡來打通Overlay網絡。遇到這種情況,如果幾臺機器的配置一致,可以手動修改kube-flannel.yml文件中kube-flannel的command的值,添加參數–iface=ethX,這里的ethX就為我們希望flanneld通信使用的網卡名稱。

4.flannel啟動異常,顯示install-cni錯誤

這個現象比較坑,遇到這種情況的第一反應就是去查看install-cni容器到底做了什么。我們打開kube-flannel.yml可以看到,該容器的command字段只有簡單的一行Shell:

command: [ "/bin/sh", "-c", "set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done" ]

也就是將鏡像中做好的cni-conf.json拷貝到cni的netconf目錄下。由于容器的/etc/cni/net.d是掛載主機的對應的目錄,所以該操作主要目的是為CNI準備flannel環境,便于啟動容器的時候正確從netconf目錄中加載到flannel,從而使用flannel網絡。

我發現進入主機的netconf目錄中能夠看到10-flannel.conf:

#ls /etc/cni/net.d/10-flannel.conf /etc/cni/net.d/10-flannel.conf
# cat /etc/cni/net.d/10-flannel.conf
cat: /etc/cni/net.d/10-flannel.conf: No such file or directory

無法打出其內容,而且文件顯示為紅色,說明其內容并沒有正確從容器中拷貝過來。

之前我懷疑該異常是因為kubelet所帶的文件系統參數為systemd,而docker的文件系統參數為cgroupfs所致,結果發現并非如此。當前能夠繞開該異常的workaround為手動進入到主機的netconf目錄,創建10-flannel.conf目錄,并寫入以下數據:

{ "name": "cbr0", "type": "flannel", "delegate": { "isDefaultGateway": true } }

5.flannel網絡啟動正常,能夠創建pod,但是網絡不通

出現該現象一般會想到debug,而debug的思路當然是基于官方的那張網絡拓撲圖。比如在我的機器上,通過參看網卡IP地址有如下信息:

6: flannel.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UNKNOWN
link/ether 22:a0:ce:3c:bf:1f brd ff:ff:ff:ff:ff:ffinet 10.244.1.0/32 scope global flannel.1
valid_lft forever preferred_lft forever
inet 10.244.2.0/32 scope global flannel.1
valid_lft forever preferred_lft forever
7:cni0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1450 qdisc noqueue state DOWN qlen 1000link/ether 0a:58:0a:f4:01:01 brd ff:ff:ff:ff:ff:ff
inet 10.244.1.1/24 scope global cni0
valid_lft forever preferred_lft forever
inet6 fe80::4cb6:7fff:fedb:2106/64 scope link
valid_lft forever preferred_lft forever

很明顯,cni0為10.244.1.1/24網段,說明該主機應該位于10.244.1.0/16子網內;但是我們看flannel.1網卡,確有兩個IP地址,分別為于兩個不同的”/16”子網。所以,可以肯定的是,我們一定是在該太主機上部署了多次kubeadm,而kubeadm reset并不會清理flannel創建的flannel.1和cni0接口,這就導致環境上遺留下了上一次部署分配到的IP地址。這些IP地址會導致IP地址沖突,子網混亂,網絡通信異常。

解決的方法就是每次執行kubeadm reset的時候,手動執行以下命令來清楚對應的殘余網卡信息:

ip link del cni0
ip link del flannel.1

K8S如何使用Flannel網絡

Flannel打通Overlay網絡

當使用kubeadm來部署k8s,網絡組件(如flannel)是通過Add-ons的方式來部署的。我們使用這個yml文件來部署的flannel網絡。
我截除了關鍵的一段內容(containers spec):

containers: - name: kube-flannel
image: quay.io/coreos/flannel:v0.7.1-amd64
command: [ "/opt/bin/flanneld", "--ip-masq", "--kube-subnet-mgr" ]
securityContext:
privileged: true
env: - name: POD_NAME
valueFrom:
fieldRef:fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:fieldPath: metadata.namespacevolumeMounts: - name: run
mountPath: /run
- name: flannel-cfg
mountPath: /etc/kube-flannel/ - name: install-cni
image: quay.io/coreos/flannel:v0.7.1-amd64command: [ "/bin/sh", "-c", "set -e -x; cp -f /etc/kube-flannel/cni-conf.json /etc/cni/net.d/10-flannel.conf; while true; do sleep 3600; done" ]
volumeMounts: - name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfgmountPath: /etc/kube-flannel/

通過分析該yaml文件可以知道:該pod內有兩個container,分別為install-cni和 kube-flannel。

  • install-cni

主要負責將config-map中適用于該flannel的CNI netconf配置拷貝到主機的CNI netconf 路徑下,從而使得K8S在創建pod的時候可以遵照標準的CNI流程掛載網卡。

  • kube-flannel

主要啟動flanneld,該command中為flanneld的啟動指定了兩個參數: –ip-masq, –kube-subnet-mgr。第一個參數–ip-masq代表需要為其配置SNAT;第二個參數–kube-subnet-mgr代表其使用kube類型的subnet-manager。該類型有別于使用etcd的local-subnet-mgr類型,使用kube類型后,flannel上各Node的IP子網分配均基于K8S Node的spec.podCIDR屬性。可以參考下圖的方式來查看(該示例中,k8s為node-1節點分配的podCIDR為:10.244.8.0/24):

#kubectl edit node node-1apiVersion: v1
kind: Node ...
name: dev-1
resourceVersion: "2452057"
selfLink: /api/v1/nodesdev-1
uid: 31f6e4c3-57b6-11e7-a0a5-00163e122a49
spec:externalID: dev-1
podCIDR: 10.244.8.0/24

另外,flannel的subnet-manager通過監測K8S的node變化來維護了一張路由表,這張表里面描述了要到達某個Pod子網需要先到達哪個EndPoint。

CNI掛載容器到隧道端點

如果說flannel為Pod打通了一張跨node的大網,那么CNI就是將各個終端Pod掛載到這張大網上的安裝工人。

在剛部署好flannel網絡并未在該Node上啟動任何Pod時,通過ip link我們只能夠看到flannel.1這張網卡,卻無法看到cni0。難道是flannel網絡運行異常嗎?我們接下來就來分析flannel的CNI實現原理,就知道答案了。

通過傳統方式來部署flannel都需要通過腳本來修改dockerd的參數,從而使得通過docker創建的容器能夠掛載到指定的網橋上。但是flannel的CNI實現并沒有采用這種方式。通過分析CNI代碼,

我們可以了解flannel CNI的流程:

  • 讀取netconf配置文件,并加載/run/flannel/subnet.env環境變量信息。
  • 基于加載的信息,生成適用于其delegate的ipam和CNI bridge的netconf文件;其中指定ipam使用host-local,CNI bridge type為bridge。
  • 調用deletgate(CNI bridge type)對應的二進制文件來掛載容器到網橋上。

這里的環境變量文件/run/flannel/subnet.env是由flanneld生成的,里面包含了該主機所能夠使用的IP子網網段,具體內容如下:

# cat /run/flannel/subnet.env
FLANNEL_NETWORK=10.244.0.0/16
FLANNEL_SUBNET=10.244.8.1/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

這些數據生成ipam的配置文件的依據,另外,flannel CNI插件的代碼中,默認指定delegate為bridge:

if !hasKey(n.Delegate, "type") {n.Delegate["type"] = "bridge" }

所以,當flannel CNI插件調用delegate,本質上就是調用bridge CNI插件來將容器掛載到網橋上。分析bridge CNI 插件的過程我們可以看到其指定了默認網橋名稱為cni0:

const defaultBrName = "cni0"func loadNetConf(bytes []byte) (*NetConf, error) {
n := &NetConf{ BrName: defaultBrName, } ... return n, nil }

因此,現在我們可以將整個流程連起來了:flannel CNI插件首先讀取netconf配置和subnet.env信息,生成適用于bridge CNI插件的netconf文件和ipam(host-local)配置,并設置其delegate為bridge CNI插件。然后調用走bridge CNI插件掛載容器到bridge的流程。由于各個Pod的IP地址分配是基于host-local的Ipam,因此整個流程完全是分布式的,不會對API-Server造成太大的負擔。

本文轉自中文社區-基于Kubeadm的Flannel分析

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/252800.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/252800.shtml
英文地址,請注明出處:http://en.pswp.cn/news/252800.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

sensor的skipping and binning 模式

1、第一種理解 關于sensor的縮放存在兩種模式 binning mode 和skip mode skipping mode 就是把想要的數據采集上來 把其余的數據扔掉 如下所示 column skip 2 row skip 2 留下的就是白色的像素 黑色的像素丟掉。 binning mode 就是把相鄰的像素合成一個像素&#xff0c;然后再…

5 結構型模式之 - 適配器模式

5 結構型模式之 - 適配器模式 適配器模式的介紹&#xff1a;適配器模式在開發中使用率很高&#xff0c;適配器是將兩個不兼容的類融合在一起&#xff0c;它有點像粘合劑&#xff0c;將不同的東西通過一種轉換使得它們能夠協作起來。例如經常碰到兩個不相關的類之間進行交互&…

Android進程保活

凡是做過幾年Android開發的&#xff0c;都不能不面對進程保活這一問題。特別是這兩年&#xff0c;面對谷歌&#xff0c;國內定制ROM&#xff0c;安全軟件等多方圍剿的情況下&#xff0c;app在后臺保活的難度越來越大&#xff0c;可以說包括QQ、微信在內的所有app&#xff0c;都…

治安卡口攝像機與電警抓拍機之間有什么區別?

接下來小編和大家說說它們有哪些相同和不同的地方&#xff0c;供大家參考。 治安卡口&#xff1a; 卡口攝像機主要是用于城市道路或高速公路出入口、收費站等重點治安監控地段的全天候實時檢測與記錄收費站、交通或治安檢查站等地點。 治安卡口監控系統的前端部分主要由三個單元…

https證書互信解決方案—創建私有CA并申請證書

前言 https相較于http而言有很大的安全性&#xff0c;當我們一個服務開啟https并與之通信時&#xff0c;往往需要證書的認證&#xff0c;如果是瀏覽器訪問服務&#xff0c;只要在瀏覽器內設置信任證書即可&#xff0c;而如果是程序內訪問服務&#xff08;如java程序&#xff09…

[轉]Unity-移動設備可用的壓縮解壓縮源碼

原文&#xff1a;http://www.manew.com/thread-103250-1-1.html 最近在做客戶端數據的分離&#xff0c;不希望對項目有什么影響&#xff0c;也不太想用AssetBundle&#xff0c;太麻煩&#xff0c;就在網上找了找開源的C#壓縮算法&#xff0c;找來找去&#xff0c;發現不是不支持…

高亮顯示QSS文件

轉【作者&#xff1a;一去丶二三里 博客地址&#xff1a;http://blog.csdn.net/liang19890820】 簡述 語法高亮是文本編輯器用來顯示文本的&#xff0c;特別是源代碼&#xff0c;根據不同的類別來用不同的顏色和字體顯示。這個功能有助于編寫結構化的語言&#xff0c;例如&…

智能識別技術對電子警察設備的影響

電子警察是目前交通管理部門用的最多的一種監控管理系統。這類系統與傳統安防的監控設備有很大區別&#xff0c;原先的系統只能抓拍車輛圖片&#xff0c;準確率又低所以被交通管理部門慢慢的淘汰了&#xff0c;同業興創這款最新的設備系統&#xff0c;有它一個很優質的特點就是…

Mybatis緩存配置

pom文件配置: <dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.1</version> </dependency> <dependency><groupId>org.mybatis</groupId><artifactId>myba…

初入Linux,M35作業第一彈,500字感想

畢業以后&#xff0c;做過很多工作&#xff0c;一直比較迷茫。來這邊上課&#xff0c;其實是我的好同學推薦我來報班的&#xff0c;因為他本身是做運維的&#xff0c;運維前景還可以&#xff0c;而且我對這個也感興趣。有一種冷&#xff0c;叫你媽覺得你冷&#xff0c;明明單衣…

【轉】一篇比較清晰簡單的C++文件操作

from:http://www.vckbase.com/document/viewdoc/?id1439 用C進行簡單的文件I/O操作 原文出處&#xff1a;Simple File I/O Using C 序論 我曾發表過文件輸入輸出的文章&#xff0c;現在覺得有必要再寫一點。文件 I/O 在C中比烤蛋糕簡單多了。 在這篇文章里&#xff0c;我 會詳…

交通治安卡口監控系統解決方案

隨著社會經濟發展、城鎮建設速度的加快&#xff0c;流動人口不斷增加&#xff0c;城市中人口密度逐漸加大&#xff0c;給城市治安監管帶來很大的壓力。因此采用高清網絡攝像監控系統以科技手段提高執法監督效率&#xff0c;成為有力推進“和諧社會”構建的最有力辦法。 同業興創…

細說shiro之三:在獨立應用中使用shiro

官網&#xff1a;https://shiro.apache.org/ 1. 下載在非Web環境的獨立應用中使用Shiro時&#xff0c;只需要shiro-core組件。在Maven項目中的依賴配置如下&#xff1a; <dependency><groupId>org.apache.shiro</groupId><artifactId>shiro-core</a…

高并發架構系列:Redis為什么是單線程、及高并發快的3大原因詳解

Redis的高并發和快速原因 1.redis是基于內存的&#xff0c;內存的讀寫速度非常快&#xff1b;2.redis是單線程的&#xff0c;省去了很多上下文切換線程的時間&#xff1b;3.redis使用多路復用技術&#xff0c;可以處理并發的連接。非阻塞IO 內部實現采用epoll&#xff0c;采用了…

2、C#基礎 - Visual Studio 的版本選擇和下載

有句話說&#xff1a;工欲善其事&#xff0c;必先利其器&#xff0c;我不推薦在學習一個語言時使用記事本練習&#xff0c;甚至說相當的排斥。當然了&#xff0c;你也可以選擇你自己喜歡的方式。本系列推薦使用的IDE為vs2017 community版&#xff0c;銀子不夠的同志不用怕&…

紅外攝像機的原理及選擇

一、紅外基本原理介紹 光是一種電磁波&#xff0c;它的波長區間從幾個納米&#xff08;1nm10-9m&#xff0c;十億分之一米&#xff09;到 1 毫米&#xff08;mm&#xff09;左右。人眼可見的只是其中一部分&#xff0c;我們稱其為可見光&#xff0c;可見光的波長范圍為 380nm …

第六章 預處理器

宏就是文字展開&#xff0c;實際中能夠展開寫出來發現錯誤。6.1 不能忽視宏定義中的空格 6.2 宏并非函數宏定義一個函數時&#xff0c;1、要把每一個參數用括號括起來2、同一時候也要把整個表達式括起來。3、要確保宏中的參數沒有副作用#define max(a,b) ((a)>(b)?(a):(b)…

oracle 數據庫中執行數據庫語句能找到數據,但是程序中卻抓取不到

oracle 數據庫中執行數據庫語句能找到數據&#xff0c;但是程序中卻抓取不到&#xff1f; 原因&#xff1a;數據庫中插入數據時沒有commit&#xff0c;執行COMMIT后就可以查詢到。轉載于:https://www.cnblogs.com/hanje/p/10140307.html

Python3經典100道練習題003

題目&#xff1a;一個整數&#xff0c;它加上100后是一個完全平方數&#xff0c;再加上268又是一個完全平方數&#xff0c;請問該數是多少&#xff1f; 方法&#xff1a;利用循環去判斷x100和x268是否為完全平方數&#xff0c;沒用使用其他函數&#xff0c;缺點運算速度慢 1 x-…

紅外攝像機

在監控市場中&#xff0c;紅外攝像機之所以那么受市場的歡迎&#xff0c;主要還是因為它有強勁的夜視性能。市場上&#xff0c;普通的彩色攝像機基本上沒有夜視能力&#xff0c;如果需要在夜晚獲得清晰的圖像&#xff0c;必須借助額外的可見光源照明才能實現。那么監控攝像機系…