- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
导读
本篇基于 90DaysOfDevOps 学习路线中第 49 天(2022/vi/Days/day49.md)的内容,系统讲解 Kubernetes 的"全景图":为什么单靠容器不足以支撑规模化,容器编排(Container Orchestration)解决了什么问题,Kubernetes 六大核心能力是什么,以及一个集群由哪些节点、组件和对象构成。读完本文,你将掌握 Kubernetes 从概念到架构的完整认知框架,并能结合仓库内附的 Vagrant 多节点集群脚本与实际 YAML 清单,理解控制平面、工作节点、Pod、Deployment、StatefulSet、Service 之间的协作关系,为后续深入学习 kubectl、YAML、Ingress 与持久化存储打下基础。
为什么容器之后还需要 Kubernetes
上一阶段我们学习了容器(Containers)。容器的确改变了云原生系统的构建与分发方式,但当谈到**规模化(scaling)与编排(orchestration)**时,仅靠容器本身是不够的——最乐观的情况下,我们只能用 docker-compose 把多个容器一起拉起。docker-compose 适合单机多容器的开发编排,却无法自动应对流量变化、节点故障、跨主机的服务发现等问题。
Kubernetes 正是一个Container Orchestrator(容器编排器),它带来的是以自动化方式、或依据应用与服务的负载动态进行扩缩容(scale up/down)的能力。原文档特别强调了一个 DevOps 视角的重要观点:Kubernetes 只是运行应用的另一个选项,与裸金属(bare metal)、虚拟化(virtualisation)以及云服务并列,是工程师需要具备基础认知的一类平台,而非唯一答案。
容器编排是什么
需要区分两个概念:
- Kubernetes:一项具体的开源技术;
- 容器编排(Container Orchestration):技术背后的概念与流程。
容器编排并非 Kubernetes 独占,生态中还有 Docker Swarm、HashiCorp Nomad 等平台。原文档指出,Kubernetes 正"从强到更强(going from strength to strength)",因此本系列选择它作为主线索,但同时提醒读者它并非唯一选择。
容器编排负责管理容器的部署、放置与生命周期,具体职责包括:
- 集群管理(Cluster management):将多台主机融合为一个统一的管理目标;
- 调度管理(Schedule management):通过调度器(scheduler)把容器分布到各节点(nodes);
- 服务发现(Service discovery):知道容器位于哪些节点,并把客户端请求分发给它们;
- 复制(Replication):确保为请求的工作负载保留足够数量的节点与容器;
- 健康管理(Health management):检测并替换不健康的容器与节点。
Kubernetes 是什么:六大核心能力
官方定义这样描述 Kubernetes:
Kubernetes 是一个可移植、可扩展的开源平台,用于管理容器化的工作负载与服务,支持声明式配置与自动化。它拥有庞大且快速增长的生态系统,其服务、支持与工具广泛可用。
值得注意的历史背景:Kubernetes 起源于 Google,被捐赠给Cloud Native Computing Foundation(CNCF),此后由开源社区与大型企业厂商共同推动演进。
容器本身并不能直接给你生产环境所需的体验,Kubernetes 则提供了以下六项能力:
| 能力 | 说明 |
|---|---|
| 服务发现与负载均衡(Service discovery and load balancing) | 可以用 DNS 名称或 IP 地址暴露容器;当容器流量较高时,Kubernetes 自动负载均衡并分发网络流量,保证部署稳定。 |
| 存储编排(Storage orchestration) | 自动挂载你选择的存储系统,如本地存储、公有云存储等。 |
| 自动化上线与回滚(Automated rollouts and rollbacks) | 声明期望状态,Kubernetes 以受控速率把实际状态收敛到期望状态;例如自动创建新容器、移除旧容器并回收其资源。 |
| 自动装箱(Automatic bin packing) | 提供节点集群后,你只需告诉 Kubernetes 每个容器所需的 CPU 与内存(RAM),它会自动把容器"塞进"合适的节点,最大化资源利用率。 |
| 自愈(Self-healing) | 重启失败的容器、替换容器、杀掉不响应自定义健康检查的容器,并且在这些容器未就绪前不把流量导向它们。 |
| 密钥与配置管理(Secret and configuration management) | 存储并管理密码、OAuth token、SSH key 等敏感信息,可在不重建镜像、不把密钥暴露在堆栈配置中的前提下完成部署与更新。 |
仓库中的 pacman-stateful-demo.yaml 就是对上述能力的落地印证:其中定义了mongodb-users-secret(Secret 管理)、readinessProbe与livenessProbe(自愈所依赖的健康检查)、PersistentVolumeClaim(存储编排)等资源,后面我们会展开分析。
声明式模型:Kubernetes 的关键范式
Kubernetes 的关键范式(key paradigm)是声明式模型(declarative model):你只需提供"想要的最终状态",Kubernetes 负责把现实收敛到该状态。
- 如果你需要五个实例,你不需要自己逐个启动五个实例;
- 只需告诉 Kubernetes"我需要五个实例",它会自动**对账(reconcile)**状态;
- 当其中一个实例故障,Kubernetes 仍记得你的期望状态,会在可用节点上重新创建实例。
这也解释了为何 Kubernetes 常被称为"操作系统级的控制循环":它不是一次性命令式执行,而是持续比较"期望状态"与"实际状态"并不断纠正。
节点(Node)与集群(Cluster)的基本单元
一个 Kubernetes集群(Cluster)是节点的集合,每个节点可以是物理机(bare metal)或虚拟机(VM)。每个节点上都运行着容器运行时与 kubelet 服务,并通过 kube-proxy 把 Pod 与外部组件(如 Service)连接起来。
控制平面(Control Plane)节点
每个 Kubernetes 集群都需要一个Control Plane 节点。控制平面的组件负责对集群做出全局决策(例如调度),并检测与响应集群事件。在生产环境中,控制平面可以做成**高可用(HA)**部署,与工作节点承担不同的角色。
工作节点(Worker Node)
工作节点是运行 Kubernetes 工作负载的机器,可以是物理机或 VM。每个节点可以承载一个或多个 Pod,节点由控制平面管理。
kubelet
kubelet是运行在每个节点上的代理(agent),确保容器运行在 Pod 中。它通过多种机制接收一组 PodSpec,并确保这些 PodSpec 描述的容器处于运行且健康的状态。kubelet 不管理非 Kubernetes 创建的容器。
kube-proxy
kube-proxy是运行在每个节点上的网络代理,实现 Kubernetes Service 概念的一部分。它维护节点上的网络规则,允许集群内外的网络会话与你的 Pod 通信;如果操作系统提供可用的包过滤层(packet filtering layer),kube-proxy 会优先使用它,否则由 kube-proxy 自行转发流量。
容器运行时(Container runtime)
容器运行时是负责真正运行容器的软件。Kubernetes 支持多种运行时:Docker、containerd、CRI-O,以及任何符合 Kubernetes CRI(Container Runtime Interface)的实现。
仓库中的部署脚本与这一节直接呼应:2022/Days/Kubernetes/scripts/common.sh 先卸载旧版运行时,再安装docker-ce docker-ce-cli containerd.io,随后执行containerd config default生成/etc/containerd/config.toml并重启 containerd,最终输出"ContainerD Runtime Configured Successfully"——即该脚本以containerd 作为实际容器运行时来满足 CRI 要求。
控制平面的四个核心组件
原文档详细介绍了控制平面内四个关键组件,它们通过 API Server 共享集群状态并协作:
kube API Server
kube API Server对包括 Pods、Services、Replication Controllers 等 API 对象的数据进行验证与配置。它提供 REST 操作,是整个集群共享状态的前端,所有其他组件都通过它交互。从仓库脚本看,kubeadm 初始化时正是通过--apiserver-advertise-address与--apiserver-cert-extra-sans指定 API Server 的对外地址与证书 SAN,见 2022/Days/Kubernetes/scripts/master.sh。
Scheduler(调度器)
Scheduler是控制平面进程,负责把 Pod 分配到 Node。它依据约束条件与可用资源,判断调度队列中的每个 Pod 哪些节点是合法放置位置,再对每个合法节点排序,最终把 Pod 绑定到合适的节点。
Controller Manager(控制器管理器)
Controller Manager是一个守护进程,内嵌 Kubernetes 自带的核心控制循环(core control loops)。在机器人或自动化领域,控制循环是一个永不停歇、持续调节系统状态的循环;在 Kubernetes 中,控制器通过 API Server 监视集群共享状态,并做出变更把当前状态推向期望状态。
etcd
etcd是一致且高可用(consistent and highly-available)的键值存储,作为 Kubernetes 全部集群数据的后端存储,保存整个集群的配置与状态。它是集群状态的"事实来源",也是理解"共享状态 + 控制循环"这一架构的关键。
kubectl:与集群对话的 CLI
kubectl是 Kubernetes 的命令行工具,它直接与 API Server 交互。你可以用它部署应用、检查与管理集群资源、查看日志。在仓库脚本中,kubectl 的典型使用方式包括:
kubectl apply -f calico.yaml安装 Calico 网络插件;kubectl apply -f ...components.yaml安装 Metrics Server,并用kubectl patch deployment为其增加--kubelet-insecure-tls参数;- 通过
kubectl -n kubernetes-dashboard get secret ...提取 Dashboard 管理员 token,见 2022/Days/Kubernetes/scripts/master.sh。
这些命令展示了 kubectl 在真实集群初始化中的三个典型职责:应用清单、修补运行中的资源、查询集群状态。
核心工作负载对象:从 Pod 到 Service
理解了节点与组件之后,接下来是 Kubernetes 的"积木块"——工作负载对象。原文档用一套简洁笔记勾勒出它们的分工。
Pods:最小的部署单元
Pod是一组容器构成的逻辑应用。例如一个 Web 应用同时运行 NodeJS 容器与 MySQL 容器,两者可以放在同一个 Pod 中。Pod 可以共享数据卷(volumes),并共享同一个网络命名空间(networking namespace)。
关键特性:
- Pod 为容器处理 Volumes、Secrets 与配置;
- Pod 是**临时性(ephemeral)**的,故障后会被自动重启;
- 应用横向扩缩容时,Pod 由 ReplicaSet 复制,每个 Pod 运行相同容器代码;
- Pod 运行在工作节点上;
- Kubernetes 通过Labels(键值对标签)这种简单而高效的方式标识 Pod。
Deployments:让 Pod 持续运行
- 直接运行 Pod 的话,Pod 死了就是死了;
- Deployment让 Pod 持续运行;
- Deployment 允许无停机(without downtime)更新正在运行的应用;
- Deployment 还定义了 Pod 死亡时的重启策略(restart strategy)。
仓库中的 nginx-stateless-demo.yaml 给出了一个完整的 Deployment 示例:声明replicas: 1、selector.matchLabels.app: nginx、容器镜像nginx并暴露containerPort: 80,配合同文件中的 Service 形成"Deployment + Service"的无状态应用范式。
ReplicaSets:保证期望副本数
- Deployment 可以创建 ReplicaSet;
- ReplicaSet确保你的应用拥有期望数量的 Pod;
- ReplicaSet 基于 Deployment 创建并扩缩容 Pod 组;
- Deployment、ReplicaSet、Pod 之间并非互斥关系,而是层层管理的关系(Deployment 管理 ReplicaSet,ReplicaSet 管理 Pod)。
StatefulSets:有状态应用的唯一身份
- 你的应用是否需要保存状态信息?数据库就需要状态;
- StatefulSet的 Pod不可互换(not interchangeable);
- 每个 Pod 拥有唯一、持久的标识符(unique, persistent identifier),控制器会在任何重新调度(rescheduling)中维持该标识。
仓库中的 pacman-stateful-demo.yaml 是 StatefulSet 的完整实战:kind: StatefulSet、serviceName: mongo、通过persistentVolumeClaim: mongo-storage挂载持久卷、初始化容器修正/bitnami/mongodb目录权限(fsGroup: 1001),并使用bitnami/mongodb:4.4.8镜像。它还示范了 Secret 的消费方式——通过secretKeyRef从mongodb-users-secret注入MONGODB_ROOT_PASSWORD、MONGODB_DATABASE等环境变量,正是前文"密钥与配置管理"能力的直接体现。
DaemonSets:每个节点一个 Pod
- DaemonSet面向持续进程(continuous process);
- 它在每个节点上运行一个 Pod;
- 集群每新增一个节点,DaemonSet 就会在该节点启动一个新 Pod;
- 非常适合监控、日志采集等后台任务;
- 每个 Pod 拥有唯一、持久的标识符,由控制器在重新调度中维持。
Services:访问 Pod 的统一入口
- Service是访问 Pod 的单一端点(single endpoint);
- 它提供统一的方式把流量路由到集群、最终路由到一组 Pod;
- 借助 Service,Pod 可以被拉起或销毁而不影响任何调用方。
在 nginx-stateless-demo.yaml 中,nginx-service通过selector.app选择后端 Pod,并将port: 80映射到容器的targetPort: 80;而在 pacman-stateful-demo.yaml 中,mongoService 采用ClusterIP供集群内部访问(pacman 前端通过MONGO_SERVICE_HOST: mongo连接),pacman Service 则采用LoadBalancer对外暴露。两者恰好对应原文档所述"Service 统一路由流量"的两种典型场景。
仓库实战:一条龙搭建多节点集群
原文档是概念性"全景图",而仓库的 Kubernetes 目录提供了与之配套的可运行的多节点集群搭建资源,可作为理解上述架构的直接佐证:
- Vagrantfile:定义 1 个 master 节点 + 2 个 worker 节点的拓扑,使用
bento/ubuntu-21.10镜像,master 分配 4GB 内存/2 核,worker 各 2GB/1 核,并写入/etc/hosts主机名映射(master-node、worker-node01、worker-node02)。 - scripts/common.sh:所有节点共用的初始化——关闭 swap、加载
br_netfilter与overlay内核模块、配置 sysctl(net.bridge.bridge-nf-call-iptables、net.ipv4.ip_forward等)、安装 Docker Engine 与 containerd 并生成 containerd 默认配置、最后安装并apt-mark hold固定kubelet kubeadm kubectl(版本1.23.3-00)。 - scripts/master.sh:在 master 上执行
kubeadm init(参数--apiserver-advertise-address=10.0.0.10、--pod-network-cidr=192.168.0.0/16、--ignore-preflight-errors Swap),复制 kubeconfig,把 join 命令写入/vagrant/configs/join.sh,随后部署 Calico 网络插件、Metrics Server 与 Kubernetes Dashboard,并创建admin-user的ServiceAccount+ClusterRoleBinding。 - scripts/node.sh:worker 节点执行
/vagrant/configs/join.sh -v加入集群,并打上node-role.kubernetes.io/worker标签。 - configs/join.sh:由 master 脚本生成的真实 join 命令示例,格式为
kubeadm join <API地址>:6443 --token ... --discovery-token-ca-cert-hash sha256:...,直观展示工作节点如何通过 API Server 令牌与证书哈希加入集群。
这套脚本与本文的架构描述一一对应:master-node对应控制平面节点(承载 API Server、Scheduler、Controller Manager、etcd),worker-node01/02对应工作节点(承载 kubelet、kube-proxy、容器运行时与 Pod)。需要说明的是,原文档写作时以 Docker 作为运行时示例,而仓库脚本实际落地为 containerd 运行时 + Docker 工具链,这恰好印证了"Kubernetes 支持多种 CRI 运行时"的论断。
本系列后续将覆盖的主题
原文档在结尾给出了 Kubernetes 系列的路线图,本文只是全景开篇,后续将继续深入:
- Kubernetes 架构(Architecture)
- kubectl 命令(Kubectl Commands)
- Kubernetes YAML
- Kubernetes Ingress
- Kubernetes Services
- Helm 包管理器(Helm Package Manager)
- 持久化存储(Persistent Storage)
- 有状态应用(Stateful Apps)
下一站是 Day 50:在哪里运行 Kubernetes 集群,将聚焦集群部署位置的选择与存储细节。
参考资料
- 官方 Kubernetes 文档(概念总览"什么是 Kubernetes"一节,原文档推荐的新手首选)
- TechWorld with Nana 的 Kubernetes 入门教程(4 小时完整课程)
- TechWorld with Nana 的 Kubernetes 零基础速成课
- Kunal Kushwaha 的 Kubernetes 入门与架构简化讲解
说明:以上外部学习资源来自原文档的参考文献列表,本文仅作指引性描述,正文的全部技术结论均以本仓库文档与源码为准。
- 文档/教程
【免费下载链接】90DaysOfDevOps
This repository started out as a learning in public project for myself and has now become a structured learning map for many in the community. We have 3 years under our belt covering all things DevOps, including Principles, Processes, Tooling and Use Cases surrounding this vast topic.
相关推荐
90DaysOfDevOps 第49天:Kubernetes 全景图——从容器编排概念到集群核心组件
90DaysOfDevOps 第49天:Kubernetes 全景图——从容器编排概念到集群核心组件 导读 本文是 90DaysOfDevOps 学习系列中 K
文档/教程90DaysOfDevOps 之 Kubernetes 全景入门:从容器编排到核心组件架构
90DaysOfDevOps 之 Kubernetes 全景入门:从容器编排到核心组件架构 导读 本文源自 90DaysOfDevOps https://lin
文档/教程90DaysOfDevOps Day 49:Kubernetes 全景入门——从容器编排概念到核心组件与工作负载原语
90DaysOfDevOps Day 49:Kubernetes 全景入门——从容器编排概念到核心组件与工作负载原语 Kubernetes 是当前云原生基础设施
文档/教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考