Kubernetes Pod 如何獲取 IP 地址

Kubernetes Pod 如何獲取 IP 地址

在學習 Kubernetes 網絡模型的過程當中,瞭解各類網絡組件的做用以及如何交互很是重要。本文就介紹了各類網絡組件在 Kubernetes 集羣中是如何交互的,以及如何幫助每一個 Pod 都能獲取 IP 地址。node

Kubernetes 網絡模型的核心要求之一是每一個 Pod 都擁有本身的 IP 地址並可使用該 IP 地址進行通訊。不少人剛開始使用 Kubernetes 時,還不清楚如何爲每一個 Pod 分配 IP 地址。他們瞭解各類組件如何獨立工做,但不清楚這些組件如何組合在一塊兒使用。例如,他們瞭解什麼是 CNI 插件,可是不知道它們是如何被調用的。本文就介紹了各類網絡組件在 Kubernetes 集羣中是如何交互的,以及如何幫助每一個 Pod 都獲取 IP 地址。api

在 Kubernetes 中有多種網絡設置方法,以及 container runtime 的各類選項。這篇文章將使用 Flannel 做爲 network provider,並使用 Containered 做爲 container runtime。網絡

背景概念

容器網絡ide

同一主機上的容器學習

在同一主機上運行的容器經過 IP 地址相互通訊的方法之一是使用 Linux Bridge,即在 Kubernetes(和 Docker)世界中,建立 veth(虛擬以太網)設備。該 veth 設備的一端鏈接在容器網絡命名空間,另外一端鏈接到主機網絡上的 Linux Bridge。同一主機上的全部容器都將這 veth pair 的一端鏈接到 Linux Bridge,它們能夠經過 Bridge 使用 IP 地址相互通訊。Linux Bridge 也被分配了一個 IP 地址,它充當從目的地到不一樣節點的 Pod 流出流量的網關。插件

Kubernetes Pod 如何獲取 IP 地址

不一樣主機上的容器命令行

在不一樣主機上運行的容器能夠經過其 IP 地址相互通訊的方式之一是使用數據包封裝(packet encapsulation)。Flannel 經過 vxlan 使用該功能,vxlan 將原始數據包封裝在 UDP 數據包中並將其發送到目的地。代理

在 Kubernetes 集羣中,Flannel 會在每一個節點上建立一個 vxlan 設備和一些路由表。每一個發往不一樣主機上的容器的數據包都會經過 vxlan 設備,並封裝在 UDP 數據包中。在目標位置,它會提取封裝的數據包,而後將數據包路由到目的地 Pod。server

Kubernetes Pod 如何獲取 IP 地址

注意:這只是配置容器之間網絡的方法之一。blog

CRI

CRI(容器運行時接口)是一個插件接口,容許 kubelet 使用不一樣的 container runtimes。各類 container runtimes 都實現了 CRI API,這使用戶能夠在 Kubernetes 安裝中使用他們想要的 container runtimes。

CNI

CNI(容器網絡接口)項目包含一個爲 Linux 容器提供基於通用插件網絡解決方案的規則。它由各類插件組成,這些插件在配置 Pod 網絡時執行不一樣的功能。CNI 插件是遵循 CNI 規範的可執行文件。

爲節點子網分配 Pod IP 地址

若是要求全部 Pod 具備 IP 地址,那麼就要確保整個集羣中的全部 Pod 的 IP 地址是惟一的。這能夠經過爲每一個節點分配一個惟一的子網來實現,即從子網中爲 Pod 分配節點 IP 地址。

節點 IPAM 控制器

當 nodeipam 傳遞給 kube-controller-manager 的 --controllers 命令行標誌時,它將爲每一個節點分配來自集羣 CIDR(集羣網絡的 IP 範圍)的專用子網(podCIDR)。因爲這些 podCIDR 是不相交的子網,所以它能夠爲每一個 Pod 分配惟一的 IP 地址。

當 Kubernetes 節點首次在集羣上註冊時,會被分配一個 podCIDR。要更改分配給集羣中節點的 podCIDR,須要先註銷節點,而後使用應用於 Kubernetes 控制平面的任何配置更改來從新註冊節點。podCIDR 可使用如下命令列出節點的名稱:

Kubernetes Pod 如何獲取 IP 地址

Kubelet、Container Runtime 和 CNI 插件交互

當在節點上調度 Pod 時,一啓動 Pod 就會發生不少事情。這裏咱們僅關注與 Pod 配置網絡有關的動態。一旦在節點上調度了 Pod,將配置網絡並啓動應用程序容器。

Kubernetes Pod 如何獲取 IP 地址

參考:容器式 cri 插件架

Container Runtime 與 CNI 插件的交互

每一個 network provider 都有一個 CNI 插件,container runtime 會調用該插件,在 Pod 啓動時配置網絡。使用容器化做爲 container runtime,容器化 CRI 插件將調用 CNI 插件。每一個 network provider 都在每一個 Kubernetes 節點上安裝了一個代理,以配置 Pod 網絡。安裝 network provider agent 後,它會隨 CNI 一塊兒配置或者在節點上建立,CRI 插件會使用它來肯定要調用哪一個 CNI 插件。

CNI 配置文件的位置是可配置的,默認值爲 /etc/cni/net.d/\<config-file>。集羣管理員須要在每一個節點上交付 CNI 插件。CNI 插件的位置也是可配置的,默認值爲 /opt/cni/bin。

若是使用 containerd 做爲 container runtime,則能夠在 containerd config 部分下 [plugins."io.containerd.grpc.v1.cri".cni] 指定 CNI 配置和 CNI 插件的路徑。

本文中咱們將 Flannel 做爲 network provider,這裏簡單介紹一下 Flannel 的設置。Flanneld 是 Flannel 守護程序,一般 install-cni 做爲帶有初始化容器的守護程序安裝在 Kubernetes 集羣上。install-cni 容器建立 CNI 配置文件在每一個節點上 /etc/cni/net.d/10-flannel.conflist。Flanneld 建立一個 vxlan 設備,從 apiserver 獲取網絡元數據,並監控 Pod 上的更新。建立 Pod 時,它將在整個集羣中爲全部 Pod 分配路由,這些路由容許 Pod 經過 IP 地址相互鏈接。

Containerd CRI 插件和 CNI 插件之間的交互能夠以下所示:

Kubernetes Pod 如何獲取 IP 地址

如上所述,kubelet 調用 Containered CRI 插件建立容器,再調用 CNI 插件爲容器配置網絡。Network provider CNI 插件調用其餘基本 CNI 插件來配置網絡。CNI 插件之間的交互以下所述。

CNI 插件之間的交互

有多種 CNI 插件可幫助配置主機上容器之間的網絡,本文主要討論如下 3 個插件。

Flannel CNI 插件

當使用 Flannel 做爲 network provider 時,Containered CRI 插件使用 CNI 配置文件,調用 Flannel CNI 插件/etc/cni/net.d/10-flannel.conflist。

Kubernetes Pod 如何獲取 IP 地址

Fannel CNI 插件與 Flanneld 結合使用,當 Flanneld 啓動時,它將從 apiserver 中獲取 podCIDR 和其餘與網絡相關的詳細信息,並將它們存儲在文件中/run/flannel/subnet.env。

Kubernetes Pod 如何獲取 IP 地址

Flannel CNI 插件使用 /run/flannel/subnet.env 的信息來配置和調用 Bridge CNI 插件。

Bridge CNI 插件

Flannel CNI 插件使用如下配置調用 Bridge CNI 插件:

Kubernetes Pod 如何獲取 IP 地址

當 Bridge CNI 插件第一次調用時,它會建立一個 Linux Bridge "name": "cni0" 在配置文件中,而後爲每一個 Pod 建立 veth pair,其一端在容器的網絡命名空間中,另外一端鏈接到主機網絡上的 Linux Bridge。使用 Bridge CNI 插件,主機上的全部容器都鏈接到主機網絡上的 Linux Bridge。

配置完 veth pair 後,Bridge 插件將調用主機本地 IPAM CNI 插件。咱們能夠在 CNI config 中配置要使用的 IPAM 插件,CRI 插件用於調用 Flannel CNI插件。

主機本地 IPAM CNI 插件

Bridge CNI 插件使用如下配置調用主機本地 IPAM CNI 插件:

Kubernetes Pod 如何獲取 IP 地址

主機本地 IPAM(IP 地址管理)插件從中返回容器的 IP 地址,subnet將分配的 IP 本地存儲在主機下dataDir指定的目錄中/var/lib/cni/networks/\<network-name=cni0>/\<ip>。/var/lib/cni/networks/\<network-name=cni0>/\<ip>文件包含 IP 分配到的容器 ID。

調用時,主機本地 IPAM 插件返回如下有效負載:

Kubernetes Pod 如何獲取 IP 地址

總結

Kube-controller-manager 爲每一個節點分配一個 podCIDR。從 podCIDR 中的子網值爲節點上的 Pod 分配了 IP 地址。因爲全部節點上的 podCIDR 是不相交的子網,所以它容許爲每一個 pod 分配惟一的IP地址。

Kubernetes 集羣管理員可配置和安裝 kubelet、container runtime、network provider,並在每一個節點上分發 CNI 插件。Network provider agent 啓動時,將生成 CNI 配置。在節點上調度 Pod 後,kubelet 會調用 CRI 插件來建立 Pod。在容器狀況下,容器的 CRI 插件調用 CNI 配置中指定的 CNI 插件來配置 Pod 網絡。全部這些都會影響 Pod 獲取 IP地址。

相關文章
相關標籤/搜索