我已经将我云原生的那个库删掉,并入了我的blog里。

云原生

我去年开始正式投入接触云原生的学习,到如今也接触了有一年的时间了。
以前不理解这玩意有什么特别的,尤其是之前没有接触过大企业中的软件。
自己的小软件,或者干脆就是跑几行代码,在bare metal上部署,性能、软硬件结合以及方便程度都要高于使用容器,甚至虚拟机都要更方便。
但现在看来它在大企业庞大的软件体系下确实很方便。
虽然到每个开发者手中依然不怎么直接使用云原生开发,或者说不是完全的云原生开发,但是云原生的工作流程了解一下还是好的。

我个人认为云原生基本跟运维是一个活。

什么是云原生

云原生计算基金会(CNCF)起初给出的定义:

· 应用容器化

· 面向微服务

· 应用支持容器的编排调度

重定义:TBD

Kubernetes

为什么Kubernetes叫K8S?

因为K与s中间有8个字母。

Kubernetes是什么?

他是一个容器编排系统,用于实现对容器调度。

Docker

Docker是容器,K8S是容器编排工具,containerd是K8S这个容器编排工具提供了CRI接口后从Docker中分离出来的runtime class,其他接入K8S CRI的还有cri-o等。

Docker没有使用K8S的CRI,准确说Docker先出的,K8S CRI后有的。所以K8S使用Docker是单独的接口,而不走CRI标准。这漂亮,所以后来就有了containerd。

K8S包含的资源

工作资源

工作资源为整个集群提供计算服务。

Node,一个Node一般是机柜上的一台机器,也可以是一台虚拟机,但是是一台完整的操作系统(区别于docker)。

工作资源的调度单位为Pod。一个Pod是一个或者多个容器的集合,一个Node上可以有多个Pod。

容器在Pod里,一个Pod内可以有一个或多个容器实例。一般会把功能结合比较紧密的容器放入同一个Pod,进而形成一个微服务,一个Pod只完成一个服务(功能)。

存储资源

为各个物理机上的硬盘存储。

Linux操作系统中的文件系统,持久性存储资源需要K8S进行分配,保存在host机上。

网络资源

物理机上的网卡,以及很多由硬件网卡实现的虚拟网络资源。

K8S内部的各个功能模块需要进行通信,k8s中的大多数操作都是通过网络通信来实现的。所以K8S中的每个Pod都要有其网络规划(在同一个Pod内的容器共享相同的网络资源)。管理K8S网络规划的(我要是没记错)默认是…(忘了),也可以换用其他插件(例如calico、cilium等)。

当然你也可以有额外的网络需求,自己搭建专用、独立的另一套网络,这时就需要使用到k8s的另外的一些插件了(例如multus等),Google也在做multi network,做好集成进K8S后就算官方支持了。

K8S架构

提到K8S架构,首先可以简单看看他的祖先Borg的架构。

picture

之后看看K8S官网的架构图:

picture

再展示一些网上的第三方绘图:

picture

首先来看看想要将一堆计算机变为一个可以被管理的集群的基本需求——k8s都有什么。

控制平面组件以及Node组件

控制平面组件

这部分官方文档讲的很好,我摘了一些过来。

kube-apiserver

API 服务器是 Kubernetes 控制平面的组件, 该组件负责公开了 Kubernetes API,负责处理接受请求的工作。 API 服务器是 Kubernetes 控制平面的前端。

我们从命令行发出的指令全都经过这里转给各个Node。

etcd

etcd 是兼顾一致性与高可用性的键值数据库,可以作为保存 Kubernetes 所有集群数据的后台数据库。

比如Node ungraceful重启时Node上的信息就保存在这里,在Node恢复的时候就可以使用这些信息来恢复原来的状态。

kube-scheduler

kube-scheduler 是控制平面的组件, 负责监视新创建的、未指定运行节点(node)的 Pods, 并选择节点来让 Pod 在上面运行。

kube-controller-manager

kube-controller-manager 是控制平面的组件, 负责运行控制器进程。

从逻辑上讲, 每个控制器都是一个单独的进程, 但是为了降低复杂性,它们都被编译到同一个可执行文件,并在同一个进程中运行。

这些控制器包括:

节点控制器(Node Controller):负责在节点出现故障时进行通知和响应

任务控制器(Job Controller):监测代表一次性任务的 Job 对象,然后创建 Pods 来运行这些任务直至完成

端点控制器(Endpoints Controller):填充端点(Endpoints)对象(即加入 Service 与 Pod)

服务帐户和令牌控制器(Service Account & Token Controllers):为新的命名空间创建默认帐户和 API 访问令牌

cloud-controller-manager

一个 Kubernetes 控制平面组件, 嵌入了特定于云平台的控制逻辑。 云控制器管理器(Cloud Controller Manager)允许你将你的集群连接到云提供商的 API 之上, 并将与该云平台交互的组件同与你的集群交互的组件分离开来。

cloud-controller-manager 仅运行特定于云平台的控制器。 因此如果你在自己的环境中运行 Kubernetes,或者在本地计算机中运行学习环境, 所部署的集群不需要有云控制器管理器。

节点组件会在每个节点上运行,负责维护运行的 Pod 并提供 Kubernetes 运行环境。

Node组件

kubelet

kubelet 会在集群中每个节点(node)上运行。 它保证容器(containers)都运行在 Pod 中。

kubelet 接收一组通过各类机制提供给它的 PodSpecs, 确保这些 PodSpecs 中描述的容器处于运行状态且健康。 kubelet 不会管理不是由 Kubernetes 创建的容器。

kube-proxy

kube-proxy 是集群中每个节点(node)所上运行的网络代理, 实现 Kubernetes 服务(Service) 概念的一部分。

容器运行时(Container Runtime)

容器运行环境是负责运行容器的软件。

Kubernetes 支持许多容器运行环境,例如 containerd、 CRI-O 以及 Kubernetes CRI (容器运行环境接口) 的其他任何实现。

这些我理解可以认为是计算资源上以及存储资源上的架构,接下来看一张接口上的架构:

picture

CNI(容器网络接口)

在K8S中,各个Pod之间是需要网络连接的。为此K8S给出了一套为Pod提供网络连接的标准化接口,第三方软件可以通过对接口的调用使Pod使用自己的网络实现。

常见使用CNI的网络插件有calico、cilium等。

CRI(容器运行时接口):

cri-o

containerd

docker

随笔

Pod Disruption Budget

会对drain node有影响。

1
2
3
kubectl get pdb


Volume Attributes Classes

可以限制PVC的IO访问速度。

Volume Attributes Classes

在 Linux 上重启 Kubernetes

要在主节点或工作节点上重新启动 kubelet 服务,请使用以下 systemctl 命令: $ sudo systemctl restart kubelet 然后,检查 kubelet 服务的当前状态: $ sudo systemctl status kubelet

How do you enable Feature Gates in K8s?

How do you enable Feature Gates in K8s?

使用 kubeconfig 文件组织集群访问

要查看配置,输入以下命令: kubectl config view

使用 kubeconfig 文件组织集群访问

Pod Disruption Budget (PDB)

Pod Disruption Budget(Pod 中断预算)是 Kubernetes 中的一个资源,它用于定义在进行节点维护或故障转移时,允许同时终止的 Pod 数量的限制。Pod Disruption Budget 通过控制 Pod 的中断数量,可以帮助确保集群中的服务在节点维护或故障转移时仍然能够保持高可用性。

Pod Disruption Budget 资源定义了一个或多个故障域(例如节点、区域、机架),并指定了在该故障域中能够同时终止的 Pod 的最大数量。这有助于避免在维护节点或进行故障转移时,过多的 Pod 被同时终止,从而导致服务的可用性下降。

Pod Disruption Budget 可以通过 Kubernetes 的 API 来定义和管理。在定义 Pod Disruption Budget 时,您可以指定以下信息:

  1. selector:用于选择受 Pod Disruption Budget 约束的 Pod 的标签选择器。
  2. minAvailable:指定在维护期间必须保持可用的最小 Pod 数量。
  3. maxUnavailable:指定在维护期间可以不可用的最大 Pod 数量。

Pod Disruption Budget 通常与控制器(如 Deployment、StatefulSet)结合使用,以确保在维护时 Pod 的中断数量受到控制。通过使用 Pod Disruption Budget,您可以在进行节点维护或故障转移时,对 Pod 的中断数量进行限制,从而确保服务的高可用性。

总之,Pod Disruption Budget 是 Kubernetes 中用于控制 Pod 中断数量的一种资源,它有助于确保在节点维护或故障转移时,服务依然能够保持高可用性。

Ingress and Ingress controller

在给应用提供服务的时候,我们知道流量会从客户端访问服务器端。
服务器端为了给大量用户提供服务可能会使用多台物理机来处理服务信息。
这样我们就需要了Ingress Controller了。常见的Ingress Controller有Nginx等。

K8S在Primary Network上可以自己管理Ingress策略,我们只需要安装一个符合K8S要求的Ingress Controller,
就可以通过配置HttpProxy这个资源来控制Ingress的网络设置。
当然我们也要遵循Ingress的设计原理,只将Ingress的IP暴露给客户端访问。

高性能网络

K8S中每个Pod都有一个网络设备用来访问K8S集群网络,如果K8S集群网络还直连了互联网甚至可以直接访问互联网。

但是这个网络设备是虚拟的,性能一般,而且还与K8S中的控制面网络公用一个网络设备。
对于网络性能要求不高的服务还能勉强使用,对于对网络有高要求的服务就不尽如人意了。

所以就出现了高性能网络的需求和配置。

高性能网络的配置一般考虑创建一个secondary network,与K8S默认的Primary Network分开。

通过使用Multus网络插件,可以为Pod引入Secondary Network。
所谓引入Secondary Network就是为Pod引入一个新的网络设备。
让对网络性能有高要求的服务走这个新的网络设备。

虽然Pod不是一个虚拟机,但是新的网络设备的引入也是和虚拟化技术相关的。

比较出名的高性能网络设备驱动是DPDK。
其余还可以通过普通的网络设备的Kernel Driver驱动。

比较出名的高性能网络设备虚拟化为SRIOV。
其余还有Macvlan、OVS等虚拟化网络设备的方法。

在以上组合中属SRIOV加DPDK的组合性能最好。

Multus

Multus是一个为Pod引入多个网络接口的meta-plugin。
(为什么叫meta-plugin?)
与Multus类似的插件还有DANM。

Multus是CNI的插件,有了Multus就可以创建一个multi-homed pod(为什么叫这个名字?)

Multus创建了一个CRD(Custom Resource Definations)叫NetworkAttachmentDefinition。
NAD用来定义新加入的网络设备。

在NAD中要根据CNI写好对网络设备的配置。

MLX网卡是需要通过Multus和NAD来配置的。
NAD中可以在type中选择使用SRIOV插件还是host-device插件。

Intel网卡,忘了,TBD

SR-IOV Network Device Plugin

The SR-IOV Network Device Plugin is Kubernetes device plugin for discovering and advertising networking resources in the form of:

SR-IOV virtual functions (VFs)

PCI physical functions (PFs)

Auxiliary network devices, in particular Subfunctions (SFs)

which are available on a Kubernetes host

PF和VF我清楚,最后那个SF是什么不太理解。

我理解,SRIOV插件可以识别到使用UIO或者VFIO驱动的网络设备。
Pod想使用UIO驱动的网络设备,需要开启特权模式。
使用VFIO驱动的设备则不需要。

SR-IOV Network Device Plugin要好用呢,需要两件东西。
一个是Multus或者类似的CNI meta plugin,一个是能消费申请给Pod的网络设备的CNI。

能消费申请给Pod的网络设备的CNI,有两个。
一个是SR-IOV CNI,一个是Host device CNI。

UIO and VFIO

说到SR-IOV就不得不提到UIO和VFIO。
这些都是虚拟化相关的技术,了解起来也是够麻烦的了。