1、k8s组件

组件

k8s的组件分为两大部分:控制平面组件和节点组件。

控制平面组件包括:

  1. kube-apiserver:API server,可以水平扩展。
  2. etcd:后端存储。
  3. kube-scheduler:决策新创建的Pod在哪个Node上运行。
  4. kube-controller-manager:controller进程,观测Object的状态,current state -> desired state。

节点组件包括:

  1. kubelet:运行Pod。
  2. kube-proxy:网络代理, k8s中Service的部分实现,负责维护节点上的网络规则。
  3. Container runtime:Docker、containerd、CRI-O。

2、k8s网络需要解决的问题

k8s对任何CNI实现有如下规定:

  1. Pod与Pod之间的通信无须使用NAT
  2. 节点与Pod之间的通信无须使用NAT
  3. Pod与其他Pod看到自身的IP相同

k8s中的Service负责对内、对外暴露网络访问,想让应用能够在集群内外正常访问,需要解决下面的几个问题:

  1. 容器与容器的通信
  2. Pod与Pod的通信
  3. Pod与Service的通信
  4. Internet与Service的通信

3、容器与容器的通信

在Linux中,使用Namespace机制实现内核级别资源的隔离,目前提供六种Namespace:

  • Mount: 隔离文件系统挂载点
  • UTS: 隔离主机名和域名信息
  • IPC: 隔离进程间通信
  • PID: 隔离进程的ID
  • Network: 隔离网络资源
  • User: 隔离用户和用户组的ID

网络命名空间netns存在一个root network namespace,默认情况下,Linux将每个进程的netns设置为root,以提供网络访问。

对于Docker,Pod使用同一个网络命名空间,Pod之间通过Namespace隔离,Pod内的容器共享网络命名空间,Docker负责创建网络命名空间,应用容器使用-network加入该网络命名空间,容器之间通过localhost通信。

4、Pod与Pod的通信

k8s中,每个Pod拥有一个真实的IP,Pod之间通过IP通信。

(本节图片来源:Kevin Sookocheff Blog)

虚拟网桥

同节点Pod通信

跨节点Pod通信

5、Pod与Service的通信

Pod随着时间,可能消失、重启,那么直接使用Pod IP进行访问,在动态变化的环境中会存在网络问题。k8s中使用Service解决这个问题。(本节图片来源:Kevin Sookocheff Blog)

创建一个新的Service Object,实际上是创建了一个虚拟IP和一系列网络规则。

kube-proxy负责维护、更新、删除、添加网络规则,其支持的代理模式有:

  1. userspace
  2. iptables(默认)
  3. ipvs
  4. kernelspace (windows)

Pod到Service通信

Service到Pod通信

6、Internet与Service通信