一、前言
Kubernetes(通常简称为 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序,它提供了丰富的功能使得用户能够轻松地管理大规模的容器集群,包括自动化部署和扩展、服务发现和负载均衡、存储编排、自我修复、密钥管理和安全、水平扩展和滚动更新,以下就来简单的介绍一下k8s的组件和功能
二、组件
etcd:用于存储Kubernetes集群的配置数据、状态和元数据。etcd是Kubernetes的后端数据库,负责保存整个集群的状态信息
kube-apiserver:k8s集群的管理接口,所有对k8s集群的操作都通过API服务器进行处理,包括创建、更新和删除资源对象的请求
kube-controller-manage:k8s集群的控制器,集成了多个控制器,根据所需的状态进行调节,确保集群的期望状态与实际状态一致,其中包含Replication Controller、node Controller、Service Controller、Endpoint Controller、Namespace Controller、Service Account & Token Controller
kube-schduler:k8s集群的调度器,负责将新创建的Pod分配到集群中的节点上。它考虑诸如资源需求、硬件约束、数据本地性等因素,以确保最佳的Pod调度决策,其中的策略有优选策略、预选策略
kubelet:工作节点的监控器,负责管理该节点上的容器和Pod。它与API服务器通信,确保节点上的Pod按照规范运行,并向API服务器报告节点和Pod的状态
kube-proxy:工作节点的负载均衡器,负责在集群内部进行网络代理和负载均衡。它维护网络规则,允许Pod之间和外部网络之间的通信,并确保服务的可访问性,当节点网络发生变更时,负责更改iptables规则
三、工作流程
在了解工作流程前先来提前了解一下k8s的watch机制,watch机制是什么呢,watch"机制是指通过API Server监视资源对象的变化,这种机制对于实时了解集群中资源的状态变化非常有用,在Kubernetes中,每个组件都可以通过API Server上的restful API订阅资源对象的变更。这些组件可以通过HTTP长连接来监听资源对象的变更,一旦资源对象发生变化,API Server会向订阅者发送通知。这种方式可以用来实现各种功能,比如实时监控、自动伸缩、事件驱动等
创建pod
1.客户端使用kubectl调用kube-apiserver集群管理接口创建pod
2.kube-apiserver将资源变更信息写入etcd中存储
3.apiserver接收etcd的回调事件
4.apiserver将事件推送给订阅者kube-schduler
5.kube-schduler根据预选策略或者优选策略将pod调度到相应node节点的事件发送给apiserver
6.kube-apiserver将资源变更信息写入etcd中
7.apiserver接收etcd的回调事件
8.apiserver将事件推送给订阅者kubelet
9.kubelet调用cri启动相应的容器
10.kubele将pod状态通过kube-apiserver写入到etcd中
创建replicaset
1.客户端使用kubectl调用kube-apiserver集群管理接口创建replicaset控制器
2.kube-apiserver将信息写入etcd中存储
3.apiserver接收etcd的回调事件
4.apiserver将事件推送给订阅者kubeletkube-contorller-manage
5.kube-contorller-manage根据定义的信息通过replication controller创建rs,然后根据rs中的期望pod副本数量发送给apiserver创建pod的事件
6.kube-apiserver将资源变更信息写入etcd中
7.apiserver接收etcd的回调事件
8.apiserver将事件推送给订阅者kube-schduler
9.kube-schduler根据预选策略或者优选策略将pod调度到相应node节点的事件发送给apiserver
10.kube-apiserver将资源变更信息写入etcd中
11.apiserver将事件推送给订阅者kubelet
12.kubelet调用cri启动相应的容器
13.kubele将pod状态通过kube-apiserver写入到etcd中
四、资源隔离
namespace
Kubernetes中的命名空间(Namespace)是一种逻辑隔离机制,用于将集群中的资源划分为不同的虚拟群组,以实现多租户、多环境或多项目的资源隔离和管理,不同命名空间中的资源对象彼此之间相互隔离,互不影响。例如,Pod、Service、Deployment等资源对象都可以属于特定的命名空间,这样它们之间的名称可以相同,但彼此不会相互冲突,但某些资源对象是全局的,不属于任何特定的命名空间,例如节点(Node)、存储类(StorageClass)、持久卷(PersistentVolume)等。这些资源对象可以被所有命名空间中的资源对象共享和使用
Linux命名空间,Kubernetes利用Linux命名空间来实现容器之间的隔离,每个容器都运行在独立的命名空间中,包括PID(进程ID)、网络、文件系统、用户等。这意味着每个容器拥有自己的进程树、网络栈、文件系统视图和用户空间,从而避免了容器之间的干扰和资源冲突,但是内核还是共用的宿主机内核
linux命名空间解析:容器的创建是通过linux命名空间实现的,容器,其实是一种特殊的进程,在使用容器的时候,实际上还是在当前主机上创建一个应用进程,只不过在创建这些进程时,Docker 为它们加上了各种各样的 Namespace 参数,从而使得在同一系统上运行的进程之间能够拥有各自独立的视图和隔离的环境,因为是宿主机上的进程,所以多个容器之间使用的还是同一个宿主机的内核。Linux Namespace 主要用于以下几个方面的资源隔离
PID 命名空间(PID Namespace):PID 命名空间使得每个命名空间内的进程拥有独立的进程树。一个进程在其所属的命名空间内看到的进程编号(PID)与其他命名空间内的进程编号是不同的,这样就实现了进程隔离
网络命名空间(Network Namespace):网络命名空间提供了一套独立的网络栈,使得每个命名空间内的进程拥有自己独立的网络接口、IP 地址、路由表和防火墙规则等。这种隔离机制使得不同网络命名空间内的进程可以拥有独立的网络环境,从而实现了网络隔离
挂载命名空间(Mount Namespace):挂载命名空间为每个命名空间提供了独立的文件系统挂载点,使得在不同命名空间内的进程能够拥有不同的文件系统视图。这种隔离机制使得每个命名空间内的进程可以拥有独立的文件系统环境,从而实现了文件系统隔离
UTS 命名空间(UTS Namespace):UTS 命名空间提供了独立的主机名和域名标识符,使得在不同命名空间内的进程拥有独立的主机名和域名标识符。这种隔离机制使得每个命名空间内的进程可以拥有独立的系统标识符,从而实现了系统标识符隔离
IPC 命名空间(IPC Namespace):IPC 命名空间提供了独立的进程间通信(IPC)资源,包括消息队列、信号量和共享内存等,使得在不同命名空间内的进程之间的 IPC 资源不会相互干扰,从而实现了进程间通信资源的隔离
cgroup
控制组(Cgroups)是Linux内核提供的一种资源管理机制,用于限制和管理进程组的资源消耗。Kubernetes利用Cgroups来限制容器对CPU、内存、磁盘等资源的使用。通过为容器设置资源配额和限制,可以确保集群中的容器在资源利用方面得到合理的调度和管理
Kubernetes中的Resource Quota资源配额机制允许集群管理员为命名空间设置资源使用的上限。资源配额可以限制CPU、内存、存储等资源的使用量,确保各个命名空间内的资源消耗得到合理控制,防止某个应用程序占用过多资源而影响其他应用程序的正常运行,实际上还是通过resource quota的配置参数转化底层cgroup的配置去实现资源的限制
五、iptables与ipvs
iptables 在 Kubernetes 集群中扮演了重要角色,用于实现服务发现、负载均衡、网络策略、服务代理等功能。通过使用 iptables,Kubernetes 可以灵活地管理和控制集群中的网络流量,从而保障集群的安全性、稳定性和可靠性
服务发现和负载均衡:Kubernetes 中的 Service 对象提供了一种抽象,用于将一组具有相同标签的 Pod 组合成一个逻辑服务。为了实现服务的访问和负载均衡,Kubernetes 通过 iptables 规则将请求转发到 Service 对应的 Pod 上,从而实现服务发现和负载均衡的功能
网络策略:Kubernetes 中的 NetworkPolicy 对象用于定义 Pod 之间和 Pod 与外部网络之间的网络访问策略。为了实现这些策略,Kubernetes 使用 iptables 来过滤和控制流量,根据网络策略规则来允许或阻止流量的传输
服务代理:Kubernetes 中的代理组件,比如 kube-proxy,负责将服务的请求转发到后端的 Pod 上。这些代理组件通常使用 iptables 来设置转发规则,从而实现服务代理的功能
Pod 网络:Kubernetes 中的容器网络插件(CNI)负责为 Pod 分配 IP 地址,并实现 Pod 之间的通信。一些 CNI 插件使用 iptables 来实现网络地址转换(NAT)等功能,以确保 Pod 可以正常访问外部网络
iptables和ipvs都可以作为k8s的负载均衡组件,但是在大规模集群中使用ipvs会比使用iptables性能更好,因为iptables是防火墙,在大规模集群中,iptables的规则量会很大,iptables又是使用链表的方式匹配,所以使用iptables作为负载均衡组件的话,需要匹配大量的规则,这会导致性能大量的消耗,而ipvs作为专门的负载均衡组件,支持多种负载均衡调度算法,如轮询(RR)、加权轮询(WRR)、最小连接数(LC)等。这些调度算法能够更加智能地分配流量到后端服务器,从而提高了整体的负载均衡性能,还有一点就是 IPVS 是基于内核的实现,可以利用 Linux 内核提供的各种优化和功能来提高性能和可扩展性。而 iptables 是基于用户空间的实现,性能和可扩展性相对较低