【K8s】Kubernetes网络完全指南和CNI讲解
@TOC
推荐超级课程:
作为Kubernetes专家,Kubernetes定义了一个网络模型,以帮助在各种网络环境和网络实现中提供简单性和一致性。Kubernetes网络模型为理解Kubernetes中容器、Pod和服务之间的通信提供了基础。本指南解释了关键概念以及它们如何结合在一起。
Kubernetes网络模型
Kubernetes网络模型规定:
- 每个Pod都有自己的IP地址
- Pod内的容器共享Pod IP地址,并可以自由通信
- Pod可以使用Pod IP地址与集群中的所有其他Pod进行通信(无需网络地址转换(NAT) )
- 使用网络策略定义隔离(限制每个Pod可以进行通信的内容)
因此,Pod可以像虚拟机或主机一样处理(它们都有唯一的IP地址),Pod内的容器可以像在虚拟机或主机中运行的进程一样处理(它们在相同的网络命名空间中运行并共享一个IP地址)。这种模型使得将应用程序从虚拟机和主机迁移到由Kubernetes管理的Pod变得更加容易。此外,由于隔离是使用网络策略而不是网络结构来定义的,因此网络仍然简单易懂。这种网络风格有时被称为“扁平网络”。
请注意,尽管极少情况下需要,但Kubernetes也支持将主机端口映射到Pod,或者直接在主机网络命名空间中运行Pod,共享主机的IP地址。
Kubernetes网络实现
Kubernetes的内置网络支持kubenet可以提供一些基本的网络连接。然而,更常见的是使用第三方网络实现,通过CNI(容器网络接口)API插入到Kubernetes中。
有许多不同类型的CNI插件,但主要的两种是:
- 网络插件,负责将Pod连接到网络
- IPAM(IP地址管理)插件,负责分配Pod IP地址
Calico提供了网络和IPAM插件,但也可以与一些其他CNI插件(包括AWS、Azure和Google网络CNI插件以及本地IPAM插件)集成并无缝工作。这种灵活性允许您为您的特定需求和部署环境选择最佳的网络选项。
Kubernetes服务
Kubernetes 服务 提供了一种将一组Pod抽象为网络服务的方法。这组Pod通常使用标签选择器 来定义。在集群内,网络服务通常表示为虚拟IP地址,kube-proxy会将连接负载均衡到支持服务的一组Pod。
虚拟IP地址可以通过Kubernetes DNS发现。DNS名称和虚拟IP地址在服务的整个生命周期中保持不变,即使支持服务的Pod可能会创建或销毁,并且支持服务的Pod数量可能随时间变化。
Kubernetes服务还可以定义如何从集群外访问服务,使用以下之一:
- 节点端口,可以通过每个节点上的特定端口访问服务
- 负载均衡器,其中网络负载均衡器提供一个虚拟IP地址,可以从集群外访问服务
请注意,在本地部署中使用Calico时,您还可以广播服务IP地址 ,允许方便地访问服务,而不需要通过节点端口或负载均衡器。
Kubernetes DNS
每个Kubernetes集群都提供一个DNS服务。每个Pod和每个服务都可以通过Kubernetes DNS服务发现。
例如:
- 服务:
my-svc.my-namespace.svc.cluster-domain.example
- Pod:
pod-ip-address.my-namespace.pod.cluster-domain.example
- 作为服务暴露的部署创建的Pod:
pod-ip-address.deployment-name.my-namespace.svc.cluster-domain.example
DNS服务实现为一个Kubernetes服务,映射到一个或多个DNS服务器Pod(通常是CoreDNS),它们像任何其他Pod一样被调度。集群中的Pod被配置为使用DNS服务,其中DNS搜索列表包括Pod自己的命名空间和集群的默认域。
这意味着如果在Kubernetes命名空间bar
中有一个名为foo
的服务,那么相同命名空间中的Pod可以作为foo
访问该服务,而其他命名空间中的Pod可以作为foo.bar
访问该服务。
Kubernetes支持一系列丰富的选项来控制不同场景中的DNS。您可以在Kubernetes指南DNS for services and pods 中了解更多信息。
出站NAT
Kubernetes网络模型规定,Pod必须能够直接使用Pod IP地址相互通信。但是它没有规定Pod IP地址是否可以在集群边界之外路由。许多Kubernetes网络实现使用覆盖网络。通常,在这些部署中,当Pod向集群之外的IP地址发起连接时,托管该Pod的节点将使用SNAT(源网络地址转换)将数据包的源地址从Pod IP映射到节点IP。这样可使连接在网络的其余部分路由到目的地(因为节点IP是可路由的)。连接上的返回数据包将由节点自动映射回去,将节点IP替换为Pod IP,然后将数据包转发到Pod。
双栈
如果您想同时使用IPv4和IPv6,可以启用Kubernetes的双栈 模式。启用后,所有Pod将被分配IPv4和IPv6地址,并且Kubernetes服务可以指定它们应该以IPv4还是IPv6地址公开。
CNI
它的正式名称是Container Network Interface,即容器网络的API接口。 它是K8s中标准实现的网络接口。Kubelet使用这个标准API来调用各种网络插件,并实现各种网络配置方法。实现这个接口的是实现一组CNI API接口的CNI插件。常见的CNI插件包括Calico、flannel、Terway、Weave Net和Contiv。
使用 Kubernetes 部署 CNI 的方法
K8s 通过 CNI 配置文件确定要使用的 CNI。基本使用方法如下:
- 首先,在每个节点上配置 CNI 配置文件(/etc/cni/net.d/xxnet.conf)。这里,xxnet.conf 是特定网络配置文件的名称。
- 将对应的二进制插件安装到 CNI 配置文件中。
- 在该节点上创建 Pod 后,Kubelet 将根据 CNI 配置文件运行在前两个步骤中安装的 CNI 插件。
- 完成上述步骤后,Pod 的网络配置完成。
下面的图展示了具体过程。
当在集群中创建 Pod 时,Pod 配置首先通过 apiserver 写入。 一些管理组件(如调度器等)被调度到特定的节点上。 在监视创建该 Pod 之后,Kubelet 在本地执行一些创建操作。 执行网络创建步骤时,首先读取存储在前述配置目录中的配置文件。 配置文件声明要使用的插件,并执行特定 CNI 插件的二进制文件。 然后,CNI 插件进入 Pod 网络命名空间,并配置 Pod 网络。 完成配置后,Kuberlet 完成整个 Pod 创建过程,Pod 将上线。