ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Kubernetes架构深度解析:从核心组件到云原生操作系统

Kubernetes架构深度解析:从核心组件到云原生操作系统 1. 从“容器编排”到“云原生操作系统”Kubernetes的定位与价值如果你在运维或者开发领域待过几年一定听过“Kubernetes”这个名字它几乎成了现代云原生应用部署的代名词。但很多人对它的理解可能还停留在“一个很火的容器编排工具”这个层面。今天我想从一个更底层的视角和你聊聊Kubernetes到底是什么以及它的架构设计是如何支撑起“云原生操作系统”这个宏大定位的。简单来说Kubernetes不仅仅是一个调度器它是一个意图驱动的、声明式的分布式系统平台。你告诉它你想要的应用状态比如“运行3个Nginx实例每个实例分配1个CPU核心并且通过负载均衡器对外暴露”它会自动、持续地工作确保现实世界中的集群状态与你的声明保持一致。这种从“如何做”到“要什么”的转变是它最核心的哲学也是其复杂架构存在的根本原因。理解Kubernetes的架构对于任何想要在生产环境中驾驭它的人来说都是至关重要的第一步。这不仅能帮助你在集群出问题时快速定位是kube-apiserver挂了还是etcd数据不一致更能让你在设计应用部署方案时做出更合理、更高效的选择。无论是选择Deployment还是StatefulSet是使用NodePort还是Ingress背后都是对Kubernetes组件职责和交互逻辑的理解。接下来我们就一层层剥开它的外壳看看这个强大的系统内部究竟是如何协同工作的。2. Kubernetes集群的宏观视图Master与Node的职责分离一个标准的Kubernetes集群在逻辑上被清晰地划分为两个部分控制平面Control Plane通常被称为Master节点和工作节点Worker Nodes。这种主从分离的架构是分布式系统的经典设计旨在实现关注点分离和高可用性。控制平面Master是集群的大脑和决策中心。它负责管理集群的全局状态做出所有调度决策并响应集群的事件。你可以把它想象成公司的管理层不直接参与一线生产但制定所有生产计划、规章制度并监控整个公司的运行状况。为了保证高可用生产环境中的控制平面通常由多个节点组成避免单点故障。工作节点Node则是集群的肌肉和骨骼是实际运行容器化工作负载的地方。每个节点都是一台物理机或虚拟机它提供CPU、内存、存储和网络等计算资源。节点就像生产线上的工人接收来自管理层的指令调度结果并忠实地执行具体的生产任务运行容器。一个集群中可以有成百上千个这样的工作节点。这种架构带来的核心好处是弹性与可扩展性。当你的应用负载增加时你只需要向集群中添加更多的工作节点控制平面会自动将新的容器实例调度到这些新增的资源上。反之当负载降低时也可以安全地移除节点。控制平面和工作节点之间通过标准的API进行通信这种松耦合的设计使得集群的扩缩容变得非常灵活。注意在云服务商提供的托管Kubernetes服务如GKE EKS AKS中控制平面通常由云厂商托管和维护用户无需关心其部署和高可用细节只需专注于管理工作节点。而在自建集群如使用kubeadm时搭建和维护一个高可用的控制平面则是首要且复杂的任务。3. 控制平面核心组件深度拆解控制平面由一系列精密协作的组件构成每个组件都有其不可替代的职责。理解它们是理解Kubernetes如何工作的关键。3.1 kube-apiserver集群唯一的通信枢纽kube-apiserver是Kubernetes所有组件交互的中枢也是用户与集群交互的唯一入口。它暴露了Kubernetes REST API所有对集群的操作无论是通过kubectl命令行工具、客户端库还是其他控制平面组件内部的通信都必须经过API Server。它的核心工作模式是无状态和可水平扩展。这意味着你可以运行多个kube-apiserver实例来分担负载和提高可用性因为它们本身不存储数据所有状态都保存在后端的etcd中。当一个请求到达时API Server会依次执行一系列操作认证Authentication验证请求者的身份如客户端证书、Bearer Token等。鉴权Authorization判断该身份是否有权限执行请求的操作如RBAC。准入控制Admission Control在对象被持久化之前或之后对其进行修改或验证例如自动注入Sidecar容器、验证资源配额。Schema验证验证请求的API对象如Pod、Deployment是否符合预定义的格式。只有通过了所有这些关卡请求才会被处理并持久化到etcd。这种设计使得kube-apiserver成为了一个高度可定制和可扩展的网关。3.2 etcd集群状态的一致性与持久化存储etcd是一个分布式、高可用的键值存储数据库是Kubernetes集群的“唯一真相源”。所有集群的配置数据、状态信息如Pod、Service、Deployment的定义和当前状态都存储在etcd中。etcd基于Raft一致性算法确保在多个节点间数据的一致性和高可用性。对于Kubernetes来说etcd的数据是至关重要的一旦损坏或丢失整个集群将无法正常工作。因此对etcd的备份和恢复策略是生产环境运维的重中之重。实操心得etcd对磁盘I/O性能极其敏感。慢速磁盘会导致etcd心跳超时进而引发主节点选举导致集群短暂不可用。务必为etcd节点配备高性能的SSD并确保网络低延迟、高带宽。定期使用etcdctl snapshot save命令进行快照备份是必须养成的习惯。3.3 kube-scheduler为Pod寻找最佳归宿的调度器当用户创建一个PodKubernetes中最小的调度单元时这个Pod最初只是etcd中的一条记录处于“Pending”状态。kube-scheduler的任务就是为这个还没有被分配的Pod选择一个合适的工作节点来运行。调度决策是一个复杂的过程主要分为两个阶段过滤Filtering也称为“预选”。调度器会检查所有节点过滤掉那些不满足Pod硬性要求的节点。例如Pod请求了4GB内存而某个节点只剩2GB可用内存那么这个节点就会被过滤掉。其他过滤条件还包括节点选择器nodeSelector、污点与容忍度Taints and Tolerations、节点亲和性Node Affinity等。打分Scoring也称为“优选”。在通过过滤的节点列表中调度器会为每个节点计算一个分数。分数基于多种策略例如LeastRequestedPriority优先选择资源请求量少的节点平衡负载。BalancedResourceAllocation优先选择CPU和内存使用率更均衡的节点。ImageLocalityPriority优先选择已经存在所需容器镜像的节点加快启动速度。 最终调度器选择分数最高的节点作为调度结果。调度器本身是无状态的它通过监听kube-apiserver来获取待调度的Pod和集群节点的资源信息。你可以编写自定义的调度器来实现特殊的调度策略与默认调度器并存。3.4 kube-controller-manager确保期望状态与实际状态一致的守护者kube-controller-manager是一个运行着多种控制器Controller的守护进程。在Kubernetes中控制器是一个控制循环它持续地观察集群中某一类资源如Pod、副本集的当前状态并将其与用户声明的期望状态进行比较。如果发现不一致控制器就会采取行动驱动当前状态向期望状态收敛。kube-controller-manager集成了许多核心控制器例如节点控制器Node Controller负责监控节点的健康状况。当节点不可达时它会给节点打上NotReady污点并驱逐该节点上的Pod。副本控制器Replication Controller确保Pod副本的数量始终与用户定义的期望值一致。如果少了就创建新的Pod多了就删除多余的Pod。注通常我们使用更高级的Deployment来管理ReplicaSet而ReplicaSet则继承了副本控制器的逻辑。端点控制器Endpoints Controller将Service一种抽象定义了一组Pod的访问策略与实际的Pod IP地址关联起来填充Endpoints对象。服务账户和令牌控制器Service Account Token Controllers为新的命名空间创建默认的服务账户和API访问令牌。所有这些控制器都遵循着相同的“观察-对比-行动”的调和Reconciliation循环模式这是Kubernetes实现声明式API和自愈能力的基石。3.5 cloud-controller-manager连接云平台的桥梁cloud-controller-manager是一个可选但非常重要的组件特别是在公有云环境中。它允许Kubernetes与底层云提供商如AWS、Azure、GCP的API进行交互将集群中与云基础设施相关的部分抽象出来。它包含的控制器有节点控制器Node Controller用于在云平台上检查节点是否已被删除。例如在AWS上如果一个EC2实例被终止这个控制器会知道并从Kubernetes中移除对应的Node对象。路由控制器Route Controller在云平台上配置路由以便Pod跨子网通信。服务控制器Service Controller负责创建、更新和删除云提供商提供的负载均衡器如AWS的ELB、GCP的Load Balancer。卷控制器Volume Controller与云存储交互创建、挂载和卸载持久卷Persistent Volumes。通过cloud-controller-managerKubernetes实现了与底层基础设施的解耦。当你需要将集群从一个云平台迁移到另一个云平台或者迁移到本地数据中心时只需替换或禁用这个组件而无需修改你的应用定义。4. 工作节点核心组件运行机制工作节点是工作负载的最终承载者。每个节点上都必须运行着三个关键组件它们共同协作确保Pod能够被正确地启动、运行和连接。4.1 kubelet节点上的“Pod管家”kubelet是运行在每个工作节点上的主要代理。它就像一个驻守在节点上的忠诚管家负责与kube-apiserver通信并管理本节点上Pod的生命周期。它的核心职责包括Pod生命周期管理kubelet通过kube-apiserver监听分配给本节点的Pod清单PodSpec。它负责按照清单描述调用容器运行时如Docker、containerd来拉取镜像、启动和停止容器。同时它还会执行Pod中定义的存活探针Liveness Probe和就绪探针Readiness Probe。节点状态上报kubelet定期向kube-apiserver上报本节点的状态信息包括节点的资源容量CPU、内存、分配情况、运行中的Pod列表以及节点自身的健康状况通过NodeStatus。容器健康检查除了执行Pod中定义的探针kubelet还会通过容器运行时接口CRI获取容器的基础运行状态。挂载存储卷根据Pod定义kubelet负责挂载所需的存储卷如hostPathemptyDir 网络存储等到容器中。kubelet不管理非Kubernetes创建的容器。它只关心由Kubernetes控制平面指派给它的Pod。4.2 kube-proxy集群服务的网络魔术师kube-proxy是运行在每个节点上的网络代理组件它实现了Kubernetes Service的概念。Service是一种抽象为一组功能相同的Pod通常由同一个Deployment或ReplicaSet管理提供一个稳定的虚拟IPClusterIP和DNS名称。kube-proxy的核心工作是维护节点上的网络规则使得发往Service虚拟IP的流量能够被正确地转发到后端的一个健康Pod上。它支持三种代理模式每种模式实现原理不同代理模式工作原理优点缺点userspace已弃用流量在用户空间被kube-proxy进程接管并转发。实现简单。性能差频繁在用户态和内核态切换。iptables默认使用Linux内核的iptables规则链进行流量转发。性能好规则在内核态处理。规则数量随Service和Pod数量线性增长大规模集群下管理和查询效率低不支持更复杂的负载均衡策略如会话保持。IPVS使用Linux内核的IPVSIP Virtual Server模块基于内核的哈希表实现负载均衡。性能最优支持多种负载均衡算法rr, lc, dh, sh等支持会话保持规则规模大时效率远高于iptables。需要节点内核支持并加载IPVS模块。目前对于生产环境尤其是Service数量较多的集群IPVS模式是推荐的选择。kube-proxy会监听Service和Endpoint的变化并实时更新节点上的转发规则确保流量路由的正确性。4.3 容器运行时Container RuntimePod的“分娩”工具容器运行时是真正负责运行容器的软件。Kubernetes通过容器运行时接口CRI与运行时进行交互这是一个插件接口使得Kubernetes可以支持多种不同的运行时。常见的容器运行时包括containerd目前的事实标准。它是一个工业级标准的容器运行时强调简单性、健壮性和可移植性。Docker本身也使用containerd作为其底层运行时。CRI-O一个由Kubernetes社区驱动的、专为Kubernetes设计的轻量级容器运行时。它实现了CRI接口并且只运行符合OCI开放容器倡议标准的容器镜像去除了Docker守护进程的许多非必需功能更精简、更安全。Docker通过dockershim 已弃用在Kubernetes早期Docker是唯一选择。但Docker本身不直接实现CRI因此Kubernetes曾维护一个叫dockershim的适配器。从Kubernetes 1.20开始dockershim被标记为弃用并在1.24版本中彻底移除。现在Docker可以通过cri-dockerd这个适配器来继续支持Kubernetes。kubelet通过CRI gRPC接口向容器运行时发送指令如“运行这个容器镜像”、“停止这个容器”、“列出所有容器”等。容器运行时则负责拉取镜像、创建容器命名空间、挂载文件系统、设置cgroups限制等底层操作。5. 附加组件与生态系统扩展集群能力除了核心组件一个功能完整的生产级Kubernetes集群通常还需要部署一系列附加组件它们提供了网络、DNS、可视化、日志、监控等关键能力。5.1 Pod网络与CNI插件Kubernetes要求每个Pod都必须拥有一个唯一的、集群内可路由的IP地址并且所有Pod之间可以直接通信无需网络地址转换NAT。这个要求由容器网络接口CNI插件来实现。CNI是一个标准规范定义了一系列插件二进制文件应该如何被调用来为容器配置网络。当kubelet需要为一个Pod创建网络时它会调用配置好的CNI插件。常见的CNI插件有Calico基于BGP协议实现高性能的网络和网络策略支持复杂的网络拓扑和策略控制。Flannel一个简单易用的覆盖网络Overlay Network方案为每个节点分配一个子网Pod IP在虚拟的覆盖网络中路由。Cilium基于eBPF技术的新一代CNI插件除了提供网络连接还能提供强大的API感知的网络和安全策略性能优异。Weave Net提供简单的网络模型支持加密通信。选择CNI插件时需要综合考虑性能、功能如网络策略支持、运维复杂度和与云平台的兼容性。5.2 CoreDNS集群的服务发现“电话簿”在Kubernetes集群内部Pod的IP地址是不固定的Pod可能被重建或调度到其他节点。Service提供了稳定的访问端点但如何通过一个固定的名字找到Service呢这就是CoreDNS的工作。CoreDNS是集群内部的DNS服务器。它为Kubernetes Service和Pod提供DNS记录。例如对于一个名为my-service的Service在命名空间my-ns中CoreDNS会提供以下记录my-service.my-ns.svc.cluster.local解析到该Service的ClusterIP。pod-ip-address.my-ns.pod.cluster.localPod的A记录需要显式启用。这使得集群内的应用可以使用简单、稳定的域名如my-service.my-ns来相互访问而无需关心后端Pod的具体IP地址实现了服务发现。5.3 Dashboard与监控体系虽然kubectl命令行功能强大但一个可视化的管理界面对于日常运维和问题排查非常有帮助。Kubernetes Dashboard是一个官方的Web UI允许用户查看和管理集群中的资源如节点、Pod、Deployment、查看日志、执行命令等。然而对于生产环境仅有Dashboard是远远不够的。一个完整的可观测性体系至关重要通常包括资源监控使用Metrics Server收集集群核心资源Node/Pod的CPU、内存的使用量为HPAHorizontal Pod Autoscaler和Dashboard提供数据。更全面的监控则依赖Prometheus它可以抓取并存储几乎所有的集群和应用指标。日志收集容器的日志是标准输出和标准错误流需要集中收集。通常采用EFKElasticsearch, Fluentd, Kibana或Loki技术栈。每个节点上运行一个日志收集代理如Fluentd的DaemonSet将容器日志收集并发送到中心存储。链路追踪对于微服务应用使用如Jaeger或Zipkin来追踪一个请求在多个服务间的调用路径和性能瓶颈。部署和管理这些附加组件本身也常常通过Kubernetes的声明式API来完成例如使用Helm Chart或Operator这体现了Kubernetes“吃自己的狗粮”的理念。6. 组件间通信与数据流向全景图理解了单个组件后我们还需要将它们串联起来看看一个典型的用户请求例如通过kubectl create -f deployment.yaml创建一个应用是如何在集群中流转并最终实现的。用户提交期望状态用户使用kubectl向kube-apiserver发送一个创建Deployment的YAML文件。kubectl会将YAML转换为JSON并通过HTTPS POST请求发送给API Server。API Server处理与存储kube-apiserver对请求进行认证、鉴权、准入控制等一系列操作后将合法的Deployment对象持久化存储到etcd中。控制器感知与行动kube-controller-manager中的Deployment控制器一直在通过kube-apiserver监听Deployment对象的变化。它发现了一个新的Deployment被创建于是根据其定义如副本数为3创建对应的ReplicaSet对象并再次通过API Server写入etcd。接着ReplicaSet控制器监听到了新的ReplicaSet它发现当前Pod数量为0与期望的3不符于是创建3个Pod定义并通过API Server写入etcd。调度器介入此时这3个Pod对象被创建但spec.nodeName字段为空处于“Pending”状态。kube-scheduler监听到了这些未调度的Pod。它执行过滤和打分算法为每个Pod选择一个最优的工作节点然后将调度结果将Pod绑定到某个Node通过kube-apiserver写回etcd。kubelet执行目标节点上的kubelet通过kube-apiserver监听到了有Pod被调度到本节点。它获取Pod的定义PodSpec然后调用本地的容器运行时如containerd拉取镜像、创建容器、挂载存储卷并启动容器。同时kubelet开始定期执行Pod中定义的探针并将Pod状态通过kube-apiserver报告回etcd。服务发现与负载均衡当Pod启动后kube-controller-manager中的端点控制器会更新与Pod关联的Service的Endpoints对象。同时每个节点上的kube-proxy监听到Service或Endpoints的变化更新本机的iptables或IPVS规则。现在集群内其他Pod通过Service名称发起的请求就会被kube-proxy的规则正确地负载均衡到这3个新创建的Pod上。整个流程完全由事件驱动各个组件各司其职通过kube-apiserver这个中央枢纽和etcd这个状态存储协同将用户的声明一步步变为现实。这种基于调和循环的架构赋予了Kubernetes强大的自愈能力和最终一致性。7. 从架构理解到高效运维关键实践与避坑指南掌握了Kubernetes的架构就能更好地指导我们的运维和开发实践。这里分享几个基于组件特性的关键点1. 高可用部署的核心在于控制平面自建集群时必须实现控制平面的高可用。这通常意味着kube-apiserver部署多个实例前置一个负载均衡器如HAProxy keepalived。etcd部署奇数个节点357并跨故障域分布。定期备份快照。kube-controller-manager和kube-scheduler它们本身可以通过--leader-elect参数启用领导者选举同时运行多个实例但只有一个是活跃的。2. 资源请求与限制Requests/Limits直接影响调度与稳定性在Pod定义中为容器设置resources.requests和resources.limits不是可选项而是必选项。requests是kube-scheduler进行节点过滤Filtering的依据。如果一个Pod请求了2个CPU那么调度器只会考虑至少有2个可用CPU的节点。limits是kubelet通过cgroups限制容器资源使用的上限。超过内存限制的容器会被OOM Killer终止。 不设置或设置不当会导致调度失衡Pod堆积在某些节点、节点资源耗尽引发系统级OOM等问题。3. 理解就绪探针Readiness Probe与存活探针Liveness Probe的区别这两个探针都由kubelet执行但目的截然不同存活探针用于判断容器是否“活着”。如果失败kubelet会杀死容器并根据重启策略重启它。不要轻易使用存活探针除非你确信在应用卡死时重启能解决问题。一个配置不当的存活探针如检查过于敏感会导致频繁重启形成“重启循环”。就绪探针用于判断容器是否“准备好”接收流量。如果失败kube-proxy会将该Pod从Service的负载均衡池中移除。对于所有需要接收流量的Pod都应该配置就绪探针确保流量只被发送到真正准备好的实例。4. 监控组件健康状态集群的健康不等于应用的健康。你需要监控核心组件kube-apiserver监控其可用性和延迟。它是所有操作的瓶颈。etcd监控其领导者状态、写入延迟和数据库大小。延迟飙升是严重警告。kubelet监控节点上的kubelet服务状态。kubelet故障意味着该节点上的Pod将无法被管理。 使用kubectl get componentstatuses已弃用或更推荐地通过Metrics Server和自定义监控来获取组件健康度。5. 网络策略NetworkPolicy是安全的关键一环默认情况下Kubernetes集群内的所有Pod网络是互通的。在生产环境中这存在安全风险。你应该使用NetworkPolicy需要CNI插件支持如Calico Cilium来实施最小权限网络原则例如只允许前端Pod访问特定的后端服务Pod禁止其他不必要的网络访问。网络策略的配置类似于防火墙规则是构建安全零信任网络的基础。Kubernetes的架构虽然复杂但其模块化、声明式和调和循环的设计理念使得它在管理大规模、动态变化的容器化应用时展现出了无与伦比的优势。从理解这些核心组件开始你才能不仅仅是一个Kubernetes的使用者更能成为一个真正的问题解决者和架构设计者。当你下次在命令行中敲下kubectl apply时脑海中能清晰地浮现出这条指令所触发的、在整个集群中流淌的数据流和组件间的精妙协作这才是真正掌握了这个云原生操作系统的精髓。
返回列表