Kubernetes 架构 Overview | Pure White

589 阅读5分钟

最近正在复习准备考试,于是一边复习一遍写成博客,印证自己所学。

从高层看,kubernetes 是由如下东西组成的:

  • 一个或多个 master node
  • 一个或多个 worker node
  • 一个分布式的 key-value 存储,比如 etcd

2FDF2789-F7EA-4EE6-8561-6FE7AD4A79D6

2FDF2789-F7EA-4EE6-8561-6FE7AD4A79D6

Master Node

Master node 是集群管理者,我们发出的所有请求都是到 master node 的 api server 上。

一个集群可以有多个 master node 做 HA,当有多个 master node 的时候,只有一个会提供服务,剩下的都是 follower。

集群的状态一般存储在 etcd 里面,所有的 master node 都会连接到 etcd。etcd 是一个分布式 k-v 存储。etcd 可以是 master 内部的,也可以是外部的。

Master node 的组件

master node 一般都有如下组件:

API Server

所有的操作都是通过 API Server 去完成的。每个用户 / 操作者通过发送 REST 请求到 api server,然后 api server 先验证然后执行这些操作。在执行完之后把集群的状态存到 etcd 里面。

Scheduler

顾名思义,Scheduler 的作用是调度,Scheduler 拥有所有 worker node 的资源使用情况,同时也知道用户设置的资源需求,比如说一个 disk=ssd 的 label。在调度之前,scheduler 还会考虑到 service requirements,data locality,affinity,anti-affinity 等。scheduler 负责的是 service 和 pod 的调度。

Controller Manager

简单来说,Controller Manager 是负责启动和关闭 pod 的。Controller Manager 的任务是让集群维持在期望的状态上。Controller Manager 知道每个 Pod 的状态应该是什么样,然后会不断检测是否有不达标的 pod。

Worker Node

Worker Node 就是一个被 master node 控制的机器,Pod 一般都是调度到 worker node 里面的。Worker node 会有一些可以运行以及连接容器的工具。Pod 是 kubernetes 里面的调度单元,是一个或多个容器组成的通常一起调度的逻辑上的集合。

D012D35E-5431-411E-AD4A-829A268E0875

D012D35E-5431-411E-AD4A-829A268E0875

Worker Node 组件

一个 worker node 一般会有以下组件:

Contrainer Runtime

不用多说了,运行容器必备的,默认用的是 Docker

kubelet

kubelet 是在每个 worker node 上都会运行的,用来和 master node 通信的。kubelet 从 master 接收 pod 的定义,然后启动里面的容器,并监控容器是否一直正常运行。

kube-proxy

kube-proxy 简单来说,就是对外提供代理服务的。换句话说,没有 kube-proxy,我们要访问其中的 application,就得直接访问到 worker node 上,这显然是不合理的。我们可以通过 kube-proxy 来做 load balancer 等。以前版本的 Service 也借助了 kube-proxy。

用 etcd 来管理状态

在 kubernetes 里面,都是用的 etcd 来管理所有的状态。除了集群的状态之外,还会用来存放一些信息,比如 configmap,secret。

网络需求

为了启动一个全功能的 kubernetes 集群,我们需要先确认以下信息:

  • 每个 Pod 有唯一一个独立的 IP
  • 每个 Pod 里面的容器可以互相沟通
  • Pod 之间可以互相沟通
  • 通过设置,在 Pod 里面的 application 可以被外部访问到

这些问题都是需要在部署之前被解决的。

我们一个个看:

给每个 Pod 分配一个独立的 IP

在 kubernetes 里面,每个 Pod 都要有一个独立的 IP。一般容器网络有两种规格:

  • Container Network Model (CNM)
  • Container Network Interface (CNI)

Kubernetes 用 CNI 来给 Pod 分配 IP

CA97E57F-D3C7-4BF0-BD0F-AB8E83838655

CA97E57F-D3C7-4BF0-BD0F-AB8E83838655

简单来说,容器运行时向 CNI 申请 IP,然后 CNI 通过其下面指定的 plugin 来获取到 IP,并且返回给容器运行时。

容器之间交流

一般基于底层操作系统的帮助,所有的容器运行时都会给每个容器创建一个独立的隔离的网络整体。在 Linux 上,这个整体被称为 Network Namespace,这些 Network Namespace 可以在容器之间共享。

在一个 Pod 里面,容器共享 Network Namespace,所以所有在同一个 Pod 里面的容器可以通过 localhost 来互相访问。

跨 Node 的 Pod 之间访问

在一个集群的环境下,每个 Pod 可以被调度到任何一个 Node 上,我们需要让在不同机器上的 Pod 也可以相互通信,并且任何 Node 都可以访问到任何 Pod。Kubernetes 设定了一个条件:不能有任何的 NAT 转换,我们可以通过以下方式来达成:

  • 可路由(Routable)的 Pod 和 Node,通过底层的服务,比如 GCE。
  • 通过一些软件定义的网络(Software Defined Networking),比如 flannel,weave,calico 等

更多的信息可以看看 kubernetes 的官方文档。

外网和集群之间的访问

我们可以通过 kube-proxy 来暴露我们的 service,然后就能从外面访问到我们集群里面的应用了。