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地址。

相关文章
相关标签/搜索