12. Kubernetes网络概念和策略控制

本文由 CNCF + Alibaba 云原生技术公开课 整理而来

Kubernetes 基本网络模型

Kubernetes 的容器网络模型,就是Kubernetes 对一个容器网络是否合格做出了限制。可以把它归结为约法三章和四大目标:

约法三章:在评价容器网络或者设计容器网络时,它的准入条件。它需要满足哪三个条件才能认为它是一个合格的网络方案

四大目标:在设计网络拓扑、设计网络的具体功能实现的时候,要去想清楚,能不能达成连通性等这几大指标
  • 约法三章:
第一条:任意两个 Pod 之间其实是可以直接通信的,无需经过显式地使用 NAT 来接收数据和地址的转换;

第二条:Node 与 Pod 之间是可以直接通信的,无需使用明显的地址转换;

第三条:Pod 看到自己的 IP 跟别人看见它所用的IP是一样的,中间不能经过转换。
  • 四大目标:

在设计一个 Kubernetes 的系统为外部提供服务的时候,要从网络的角度想清楚,外部如何一步一步连接到容器内部的应用?

外部和 Kubernetes 里面的 Service 之间是怎么通信的?外部用户怎么用到 Service?

Service 如何与它后端的 Pod 通讯?

Pod 和 Pod 之间调用是怎么做到通信的?

Pod 内部的容器与容器之间如何通信?

最终要达到目标,就是外部可以连接到最里面,对容器提供服务。

  • 基础约束:

对于基本约束,因为容器的网络发展复杂性就在于它其实是寄生在 Host 网络之上的。从这个角度讲,可以把容器网络方案大体分为 Underlay/Overlay 两大派别:

Underlay 的标准是它与 Host 网络是同层的,从外在可见的一个特征就是它是不是使用了 Host 网络同样的网段、输入输出基础设备、容器的 IP 地址是不是需要与 Host 网络取得协同(来自同一个中心分配或统一划分)。这就是 Underlay

Overlay 不一样的地方就在于它并不需要从 Host 网络的 IPM 的管理的组件去申请IP,一般来说,它只需要跟 Host 网络不冲突,这个 IP 可以自由分配的。

Pod 容器网络中的核心就是 IP,IP 就是每个 Pod 对外通讯的地址基础,必须内外一致,符合 Kubernetes 的模型特征。


Network Namespace

Network Namespace 是实现网络虚拟化的内核基础,创建了隔离的网络空间:

独立的附属网络设备

独立的协议栈,IP 地址和路由表

iptables 规则

ipvs 等

狭义上来说,runC 容器技术是不依赖于任何硬件的,它的执行基础就是它的内核里面,进程的内核代表就是 task,它如果不需要隔离,那么用的是主机的空间( namespace),并不需要特别设置的空间隔离数据结构( nsproxy-namespace proxy)。相反,如果一个独立的网络 proxy 或者 mount proxy,里面就要填上真正的私有数据。

一个隔离的网络空间,它会拥有自己的网卡或者网络设备。网卡可能是虚拟的,也可能是物理网卡,它会拥有自己的 IP 地址、IP 表和路由表、拥有自己的协议栈状态。这里面特指就是 TCP/IP 协议栈,它会有自己的 status,会有自己的 iptables、ipvs。

从整个感官上来讲,这就相当于拥有了一个完全独立的网络,它与主机网络是隔离的。当然协议栈的代码还是公用的,只是数据结构并不相同。

每个 Pod 都有着独立的网络空间,Pod Net Container 会共享这个网络空间。一般 Kubernetes 会推荐选用 Loopback 接口,在 Pod Net Container 之间进行通信,而所有的 Container 通过 Pod 的 IP 对外提供服务。另外对于宿主机上的 Root Network Namespace,可以把它看做一个特殊的网络空间,只不过它的 pid 是1。


主流网络方案

  • 容器网络实现方案:

容器网络方案可能是 Kubernetes 里最为百花齐放的一个领域,它有着各种各样的实现。容器网络的复杂性,其实在于它需要跟底层 Iass 层的网络做协调、需要在性能跟 IP 分配的灵活性上做一些选择,这个方案是多种多样的。

Flannel         最为普遍的实现,提供多种网络 backend 实现,覆盖多种场景

Calico          采用 BGP 提供网络直连,功能丰富,对底层网络有要求

Canal           Flannel for network + Calico for firewalling

Cilium          基于 eBPF 和 XDP 的高性能 Overlay 网络方案

Kube-router     采用 BGP 提供网络直连,集成基于 LVS 的负载均衡能力

Romana          采用 BGP 或 OSPF 提供网络直连

WeaveNet        采用 UDP 封装实现 L2 Overlay,支持用户态(慢、可加密)/内核态(快、不可加密)两种实现

Flannel 是一个比较大一统的方案,它提供了多种的网络 backend。不同的 backend 实现了不同的拓扑,它可以覆盖多种场景;

Calico 主要是采用了策略路由,节点之间采用 BGP 的协议,去进行路由的同步。它的特点是功能比较丰富,尤其是对 Network Point 支持比较好,Calico 对底层网络一般是要求 mac 地址能够直通,不能跨二层域;

最后是 WeaveNet,如果大家在使用中需要对数据做一些加密,可以选择用 WeaveNet,它的动态方案可以实现比较好的加密。

  • Flannel 方案:

Flannel 是目前使用最为普遍的方案,它首先要解决的是 Container 的包如何到达 Host,这里采用的是加一个 Bridge 的方式。数据包如何离开 Host,是采用那种封装方式,还是不需要封装,都是可以选择的。

通过将 backend 机制独立,它目前已经支持多种数据路径,也可以适用于 Underlay/Overlay 等多种场景,主要的 backend 有 3 种:

1. 用户态 udp(纯用户态实现)

2. 内核 Vxlan(性能好),需要内核支持 Vxlan 的特性功能

3. 如果集群规模不大且处于同一个二层域,也可以选择 host-gw 方式

NetworkPolicy

  • 基本概念:

NetworkPolicy 提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量。

它采用各种选择器(LabelNamespace),找到一组 Pod,或者找到相当于通讯的两端,然后通过流的特征描述来决定它们之间是不是可以连通,可以理解为一个白名单的机制。

在使用 NetworkPolicy 之前,需要注意:

ApiServer 开启 extensions/v1beta1/networkpolicies

网络插件要支持 Network Policy,如 Calico、Romana、Weave Net 和 trireme 等
  • 配置实例:

NetworkPolicy 的功能就是通过使用标签选择器(包括 namespaceSelectorpodSelector)来控制 Pod 之间的流量。

在设计一个 NetworkPolicy 时需要决定三件事:

控制对象:通过 spec 字段下 podSelector、namespaceSelector等条件筛选

流方向:Ingress(入 Pod 流量)+ from,Egress(出 Pod 流量)+ to

流特征:对端(podSelector、namespaceSelector),IP段(ipBlock),协议(protocol),端口(port)

test-network-policy NetworkPolicy yaml 文件示例:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchlabels:
      role: db
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchlabels:
          project: myproject
    - podSelector:
        matchlabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

文件解析:

apiVersion: networking.k8s.io/v1     表示 NetworkPolicy 当前所属的组是 networking.k8s.io,版本是 v1

kind        表示 Kubernetes 资源类型是 NetworkPolicy

metadata    表示 NetworkPolicy 的元数据,元数据通常包含 name、namespace、labels、annotations 等

spec    表示 NetworkPolicy 的期望状态,.spec.podSelector 表示 NetworkPolicy 期望匹配的 Pod;.spec.policyTypes 表示 NetworkPolicy 的策略类型;
        .spec.ingress 表示匹配 Pod 入流量;.spec.egress 表示 表示匹配 Pod 出流量

猜你喜欢

转载自blog.csdn.net/miss1181248983/article/details/112048204