Kubernetes 架构入门

Kubernetes 架构入门

由于k8s涉及到的概念非常多,理解起来可能非常费劲,这里用一座城市的故事,类比讲解 K8s架构,通俗易懂 。

什么是 K8s?

Kubernetes 源自希腊语,意为「舵手」。名字中 K 和 s 之间有 8 个字母,所以简称 K8s。它是 Google 基于十多年大规模容器管理经验开源的项目,如今是云原生领域的事实标准。

为什么需要 Kubernetes?

想象你开了一家连锁奶茶店。

最开始只有一家门店,你亲自盯着就够了。但生意越来越好,你开了 10 家、50 家、100 家分店。这时候问题来了:哪家店缺人了?哪家店食材不够了?某家店突然停电了怎么办?你不可能一个人跑遍所有店。

你需要一个「总部管理系统」来帮你统一调度、监控、自动处理故障。

在软件世界里,这个「总部管理系统」就是 Kubernetes(简称 K8s)。它帮你管理成百上千个容器化应用,让它们稳定、高效、自动化地运行。

核心类比:K8s 就是一座智慧城市

在正式介绍各个组件之前,我们先建立一个贯穿全文的类比:把整个 K8s 集群想象成一座「智慧城市」

城市中的角色K8s 中的组件职责说明
市政府 / 市长办公室Control Plane(控制平面)发布政令、做决策、调配资源
各个街区 / 社区Worker Node(工作节点)实际住人、开店的地方
房屋 / 公寓Pod(容器组)应用程序实际运行的最小单元
城市档案馆etcd记录城市所有信息的中央数据库
城市规划局Scheduler(调度器)决定新居民住哪个街区
物业管理公司Kubelet在每个街区负责落地执行
公交系统 / 快递网络Service / Ingress让居民和外界顺畅通信

控制平面:城市的市政府

控制平面(Control Plane)是 K8s 的大脑,负责全局决策。它通常运行在专门的主节点(Master Node)上,由四个核心组件组成:

API Server — 市政府的前台接待大厅

API Server 是整个 K8s 集群的唯一入口,所有请求都必须经过它。就像你去市政府办事,不管是申请开店、查户口、还是投诉噪音,都要先到前台。前台会验证你的身份、检查你的申请材料,然后把请求转交给对应的部门。

在技术层面,API Server 负责接收 RESTful 请求(比如 kubectl 命令),进行认证(Authentication)、授权(Authorization)和准入控制(Admission Control),然后将数据写入 etcd。

etcd — 城市档案馆

etcd 是一个分布式键值存储数据库,存放着集群的所有状态信息:有多少个节点、运行着什么应用、网络怎么配置的、密码和证书放在哪里……一切尽在其中。

就像城市档案馆保存着每一栋建筑的图纸、每一位居民的户籍、每一条道路的规划。如果档案馆被烧毁,整座城市的管理就会陷入混乱。所以在生产环境中,etcd 通常会部署为高可用集群(至少 3 个节点),确保数据安全。

重要提示:etcd 是 K8s 中唯一存储状态的地方。备份 etcd 就是备份整个集群的「记忆」。

Scheduler — 城市规划局

当有新的 Pod 需要创建时,Scheduler 会像城市规划局一样思考:「这位新居民应该住到哪个街区?」它会综合考虑各街区的剩余资源(CPU、内存)、亲和性规则(有些应用要住在一起)、反亲和性(有些应用不能住一起)、以及各种约束条件,最终选出一个最合适的 Node。

Controller Manager — 城市的各职能部门

Controller Manager 其实是一组控制器的集合,每个控制器负责一项管理工作,它们不断地巡逻检查,确保城市的实际状态和期望状态一致。

  • Deployment Controller:像「城建部门」,确保每个应用按要求部署了足够的副本。你说要 3 家奶茶店,它就确保始终有 3 家在运营。
  • Node Controller:像「街道办」,监控各街区的健康状况。如果某个街区失联了,就标记它并迁移居民。
  • ReplicaSet Controller:像「人口管理局」,保证指定数量的 Pod 副本始终在运行。一家店倒了,立刻开一家新的补上。

核心理念:声明式管理 K8s 的精髓在于「声明式」思维。你不需要告诉它「先做 A,再做 B,再做 C」,而是告诉它「我要 3 个副本、用这个镜像、暴露 80 端口」。K8s 会自动想办法让现实达到你描述的理想状态。就像你告诉市长「我要一座花园」,而不是教他怎么种花。

工作节点:城市的各个街区

Worker Node 是真正干活的地方,你的应用程序就运行在这里。每个 Node 上都有几个关键组件:

Kubelet — 街区物业经理

Kubelet 运行在每个 Node 上,它是市政府在各街区的「驻地代表」。它负责接收来自 API Server 的指令(比如「在这个街区启动一家奶茶店」),然后调用容器运行时(如 containerd)去实际启动容器。同时,它会定期向市政府汇报:「街区一切正常,3 家店都在营业。」

Kube-proxy — 街区交通指挥员

Kube-proxy 负责节点上的网络代理和负载均衡。当一个请求进来说「我要喝奶茶」,交通指挥员会把你引导到最近的、可用的奶茶店,而不是让你满大街找。它通过维护 iptables 或 IPVS 规则来实现流量的转发与分配。

Container Runtime — 街区施工队

容器运行时(如 containerd、CRI-O)是真正把容器「建」起来的人。Kubelet 拿到图纸(Pod 规格),交给施工队去盖房子(启动容器)。K8s 本身并不直接操作容器,而是通过容器运行时接口(CRI)与之交互,实现了松耦合。

核心概念详解

Pod — 城市里的房屋

Pod 是 K8s 中最小的调度单位,但它并不等于一个容器。一个 Pod 可以包含一个或多个紧密相关的容器,它们共享网络和存储,就像一栋房子里的几个房间——它们共用一个地址、共享水电。

举个例子:一个 Web 应用容器和一个日志采集容器可以放在同一个 Pod 里,Web 应用往本地磁盘写日志,日志采集容器从同一个磁盘读取并上传——它们是天然的室友。

Service — 城市的公交线路

Pod 的 IP 地址是不稳定的,随时可能因为重建而改变。如果你直接用 Pod IP 访问服务,就像跟朋友说「我在东三环第 5 棵树旁边等你」,第二天那棵树可能就不在了。

Service 提供了一个稳定的访问入口(固定 IP 或 DNS 名称),不管背后的 Pod 怎么变化,地址始终不变。就像公交站牌,不管哪辆公交车来,「人民广场站」永远在那里。Service 还会自动做负载均衡,把请求分发到健康的 Pod 上。

Deployment — 城市的连锁加盟管理总部

Deployment 定义了应用应该以什么样的姿态运行:用什么镜像、跑几个副本、怎么更新。它支持滚动更新(Rolling Update)——就像连锁店逐家翻新装修,不是一口气全关掉,而是先新开一家新版本的店,确认没问题后再关掉一家旧店,逐步替换。如果新版本出了问题,还能一键回滚。

Namespace — 城市的行政区划

Namespace 把集群划分为多个虚拟空间,就像城市被分为不同的行政区。开发团队用 dev 区,测试团队用 test 区,线上环境用 production 区。各区之间互不干扰,还可以单独设定资源配额,防止某个区把整座城市的资源都吃光。

网络与通信:城市的交通系统

Ingress — 城市的高速公路入口

如果 Service 是城市内部的公交系统,那 Ingress 就是连接外部世界的高速公路入口。外部用户的 HTTP/HTTPS 请求先到达 Ingress,由它根据域名和路径规则分发到不同的 Service。比如 api.example.com 转到后端 API 服务,www.example.com 转到前端页面——一个入口,智能分流。

DNS — 城市的门牌号系统

K8s 内部有自己的 DNS 服务(CoreDNS),让 Pod 之间可以通过名字互相找到对方,而不是记 IP 地址。比如你的前端应用可以直接用 backend-service.default.svc.cluster.local 来访问后端,就像直接说「帮我找市中心的那家书店」一样方便。

存储:城市的仓库系统

容器默认是「无状态」的,重启后数据全部丢失,就像住在酒店——退房后房间就清空了。但很多应用需要持久保存数据,比如数据库。K8s 用 Volume(存储卷)和 PersistentVolume(持久卷)来解决这个问题。

  • PersistentVolume(PV):城市的公共仓库资源池,由管理员提前准备好。
  • PersistentVolumeClaim(PVC):居民的「仓库租赁申请」,写明需要多大的空间、什么类型。系统自动匹配合适的仓库分配给你。

配置与安全:城市的规章制度

  • ConfigMap:像城市公开张贴的「营业规范」,存储非敏感配置信息(数据库地址、功能开关等),应用启动时读取。
  • Secret:像存放在保险柜里的「机密文件」,用于存储密码、令牌、证书等敏感数据。虽然默认只是做了 Base64 编码(并非加密),但可以配合外部密钥管理系统加强安全。

权限管理:城市的出入证制度(RBAC)

光有规章制度还不够,你还需要知道谁有权做什么

想象一下,进入市政大厅的人形形色色:有市长、有承包商、有普通市民、也有只负责某个街区巡逻的保安。他们能查阅的档案、能审批的事项、能进入的区域各不相同。如果所有人都有同等权限,那城市管理就会乱成一锅粥。

K8s 用 RBAC(Role-Based Access Control,基于角色的访问控制) 来解决这个问题。它的核心思想是:把权限授予角色,再把角色分配给人,而不是直接给每个人单独授权。

四个核心概念

Role / ClusterRole — 岗位职责说明书

Role 就像一份「岗位说明书」,定义了某个角色能做哪些事情。比如:

  • pod-reader 角色:只能查看(get/list/watch)Pod,不能修改或删除。
  • deployment-manager 角色:可以创建、更新、删除 Deployment。

Role 作用于单个 Namespace(某个街区内有效);ClusterRole 则作用于整个集群(全市通行证)。

ServiceAccount — 应用程序的工作证

不只是人类用户需要权限,运行在集群里的应用程序本身也需要与 API Server 打交道。ServiceAccount 就是应用程序的「工作证」,让程序可以合法地调用 K8s API。每个 Pod 默认都会挂载一个 ServiceAccount。

RoleBinding / ClusterRoleBinding — 颁发证件

光定义了岗位还不够,还要把岗位分配给具体的人。RoleBinding 就是「颁发证件」的动作,把一个 Role 绑定到某个用户(User)、用户组(Group)或 ServiceAccount 上。

比如:「把 pod-reader 角色绑定给 alice」,alice 从此就可以在对应 Namespace 里查看 Pod 了。

一个完整的例子

假设你的监控系统需要定期读取集群中所有 Pod 的状态,但绝对不能修改任何资源:

# 第一步:定义角色(它能做什么)
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]   # 只读,不能删除或修改

---
# 第二步:绑定角色(谁来扮演这个角色)
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: read-pods-binding
  namespace: production
subjects:
- kind: ServiceAccount
  name: monitoring-agent           # 监控程序的工作证
roleRef:
  kind: Role
  name: pod-reader                 # 绑定上面定义的角色
  apiGroup: rbac.authorization.k8s.io

这样,monitoring-agent 只能「看」Pod,想删一个都做不到——最小权限原则在这里得到了完美体现。

市政府(API Server)在收到任何请求时,都会先核验:你是谁(认证 Authentication)→ 你有没有权限做这件事(授权 Authorization / RBAC)→ 你的申请材料合不合规(准入控制 Admission Control),三关都过了才会放行。RBAC 负责的正是第二关。

最佳实践:遵循「最小权限原则」,只给每个角色完成工作所需的最低权限,避免任何账号拥有不必要的超级权限。这就像保安只需要巡逻权,不需要市长签署文件的印章。

一次请求的完整过程

让我们用一个故事把所有组件串起来,看看当你执行 kubectl apply -f deployment.yaml 时,到底发生了什么:

  1. 你(开发者)拿着申请书来到市政府前台(API Server),说:「我要开 3 家奶茶店。」
  2. 前台验证了你的身份和权限,把申请登记到档案馆(etcd)。
  3. 城建部门(Deployment Controller)看到新的建设任务,开始制定计划。
  4. 规划局(Scheduler)分析各街区的空间和条件,决定 3 家店分别开在哪个街区。
  5. 各街区的物业经理(Kubelet)收到通知,调用施工队(Container Runtime)把奶茶店建起来。
  6. 交通指挥员(Kube-proxy)更新路线,让顾客能找到新开的店。
  7. 公交线路(Service)挂好站牌,不管哪家店在哪个街区,顾客只要到「奶茶站」就能喝到奶茶。
  8. 如果某家店突然倒闭了,Controller 发现实际只剩 2 家,不满足 3 家的要求,于是自动再开一家新店补上。

这就是声明式的力量 你只需要说「我要 3 家店」,K8s 会始终确保有 3 家在运营。不管是店铺意外倒闭、街区停电、还是节假日扩容,K8s 都会自动调整到你声明的状态。

总结

Kubernetes 的架构初看起来组件众多、概念繁杂,但当你用「智慧城市」的视角重新审视,会发现一切都是自然而然的分工协作:市政府负责决策,街区负责执行,物业经理负责落地,交通系统负责通信,档案馆负责记忆。

赞赏

微信赞赏支付宝赞赏

Zgao

愿有一日,安全圈的师傅们都能用上Zgao写的工具。

发表评论