第1章:Kubernetes简介(Introduction to Kubernetes)
一、导读
1.1 本章学习目标
第1章是整本《Kubernetes实战》的开篇之作,它将带你走进 Kubernetes 的世界,理解这个现代云计算领域最重要的技术之一。在深入具体的技术细节之前,你需要先建立对 Kubernetes 的全局认知:它从何而来、解决了什么问题、核心设计理念是什么、集群由哪些组件构成。这种全局视角对于后续章节深入学习每个子系统至关重要——在了解每个零件之前,你需要先知道整台机器的蓝图。
本章的核心学习目标包括:
- 理解 Kubernetes 的起源和演进:从 Google Borg 到 Kubernetes,再到 CNCF 生态,了解 K8s 的设计哲学从何而来。
- 掌握集群架构的核心组件:Control Plane(API Server、etcd、Scheduler、Controller Manager)和 Worker 节点(kubelet、kube-proxy、Container Runtime)各自承担什么职责?
- 理解声明式 API 模型:Kubernetes 如何通过"期望状态"和"实际状态"的调谐循环来管理集群?
- 认识核心抽象对象:Pod、Service、Deployment、Namespace 等核心资源之间的关系是什么?
- 了解 K8s 的设计哲学:自动化、可扩展、声明式、自愈等核心原则如何影响系统设计?
- 搭建本地开发环境:使用 Minikube 或 Kind 搭建本地 K8s 集群,完成第一次 kubectl 操作。
1.2 为什么第一章如此重要
很多初学者急于学习 Pod、Deployment 等具体资源的操作,觉得第一章"太概念化"或"太泛"。这种想法是极其危险的。Kubernetes 是一个复杂的分布式系统,拥有数百个 API 资源和数千个配置选项。没有全局观,后续学习就容易陷入"只见树木,不见森林"的困境——你会机械地复制 YAML 配置,却不理解背后的设计意图。
Kubernetes 的设计深受 Google 内部系统 Borg 和 Omega 的影响。理解这段历史,你就能理解为什么 K8s 采用声明式 API、为什么控制器模式如此核心、为什么 etcd 是集群的"唯一真相来源"。这些设计决策不是偶然的,而是 Google 十多年大规模集群运营经验的结晶。
更重要的是,Kubernetes 的核心抽象之间存在精密的层级关系。Pod 是调度的最小单元,Deployment 管理 Pod 的副本和更新,Service 为 Pod 提供稳定的网络入口——不理解这些关系,你就无法设计出健壮的应用架构。第一章正是帮助你建立这种关系图谱的起点。
1.3 核心问题引导
在阅读本章时,请带着以下问题思考:
Kubernetes 和 Docker 的关系是什么?K8s 只是"Docker 的升级版"吗?
为什么 Kubernetes 选择声明式 API 而不是命令式 API?声明式有什么优势?
etcd 为什么如此重要?如果 etcd 数据丢失会发生什么?
Pod 和容器的区别是什么?为什么不直接调度容器,而要引入 Pod 这个抽象?
Controller Manager 中的各个控制器是如何协同工作的?
当你执行 kubectl apply -f deployment.yaml 时,K8s 内部发生了什么?
二、核心概念详解
2.1 Kubernetes 的起源与演进
2.1.1 Google Borg 时代
Kubernetes 的故事要从 2003 年说起。那一年,Google 内部启动了一个名为 Borg 的项目——一个大规模集群管理系统,用于运行 Google 搜索、Gmail、YouTube 等核心服务。Borg 在 Google 内部运行了十多年,管理着数以百万计的容器,积累了大量宝贵的经验和教训。
Borg 的核心设计理念包括:
- 声明式管理:用户提交作业的期望规格(desired specification),Borg 负责确保实际状态与期望一致
- 自动化运维:自动故障恢复、自动扩缩容、自动滚动更新
- 高利用率:通过混合部署批处理作业和在线服务,最大化集群资源利用率
- 可扩展性:通过分层架构支持超大规模集群
Borg 的经验催生了两个重要项目:Omega(Borg 的下一代,引入了共享状态和并行控制)和 Kubernetes(Borg 的开源版本,将 Google 的容器编排经验带给全世界)。
2.1.2 Kubernetes 的诞生
2014 年,Google 的 Joe Beda、Brendan Burns 和 Craig McLuckie 开始设计 Kubernetes。他们借鉴了 Borg 和 Omega 的设计,同时吸收了开源社区的反馈。2015 年,Kubernetes 正式开源,同年 Google 联合 Pivotal、Red Hat、IBM 等公司成立了 Cloud Native Computing Foundation(CNCF),将 Kubernetes 捐赠给 CNCF 管理。
Kubernetes 的名字来源于希腊语,意为"舵手"或"飞行员",缩写 K8s(K 和 s 之间的 8 个字母)已经成为社区的标准简称。
2.1.3 CNCF 生态的发展
CNCF 的成立标志着 Kubernetes 进入了一个全新的阶段。在 CNCF 的治理下,Kubernetes 生态蓬勃发展:
- 2015-2016:Kubernetes 1.0-1.5,核心 API 逐步稳定,社区快速成长
- 2017-2018:Kubernetes 1.6-1.12,RBAC、Custom Resources、Service Mesh 等特性成熟
- 2019-2020:Kubernetes 1.13-1.20,Windows 容器支持、IPv6、GA 特性增多
- 2021-至今:Kubernetes 1.21+,Gateway API、Sidecar Containers、更好的多集群支持
截至 2024 年,CNCF 已经拥有超过 150 个项目,包括 Prometheus、Envoy、containerd、Helm、Argo 等,形成了一个完整的云原生技术生态。
2.2 集群架构
Kubernetes 集群由两类节点组成:Control Plane(控制平面,也称 Master 节点)和 Worker 节点(工作节点)。这种分离设计使得控制逻辑和计算负载互不干扰。
2.2.1 Control Plane 组件
Control Plane 是 Kubernetes 的"大脑",负责维护集群的期望状态并驱动实际状态向期望状态收敛。
kube-apiserver
API Server 是所有集群操作的唯一入口。它提供 RESTful API,接收来自 kubectl、控制器、kubelet 等客户端的请求。API Server 的设计遵循以下原则:
- 简单性:所有操作都是对资源的 CRUD(创建、读取、更新、删除)
- 一致性:所有状态存储在 etcd 中,保证强一致性
- 可扩展性:通过 Custom Resource Definition(CRD)支持自定义资源
# 查看 API Server 支持的资源类型
kubectl api-resources
# 查看 API Server 版本
kubectl version --short
# 直接调用 API Server
kubectl get --raw /api/v1/namespaces
kubectl get --raw /apis/apps/v1/deploymentsAPI Server 还负责认证(Authentication)、授权(Authorization)和准入控制(Admission Control)。每个请求都必须通过这三层检查才能被处理。
etcd
etcd 是一个高可用的分布式键值存储,用于保存 Kubernetes 集群的所有状态数据。它是集群的"唯一真相来源"(Single Source of Truth)。etcd 使用 Raft 共识算法保证数据一致性。
etcd 存储的数据包括:
- 所有 Kubernetes 资源(Pod、Service、Deployment 等)的配置和状态
- 集群的配置信息
- Secret 数据(加密存储)
# 查看 etcd 中的数据(需要 etcdctl 工具)
etcdctl get /registry/pods/default/my-pod --prefix
# etcd 的备份
etcdctl snapshot save /backup/etcd-snapshot.db
# etcd 的恢复
etcdctl snapshot restore /backup/etcd-snapshot.db --data-dir=/var/lib/etcd-restoredkube-scheduler
Scheduler 负责决定新创建的 Pod 应该运行在哪个 Worker 节点上。调度过程分为两个阶段:
过滤(Filtering/Predicates):排除不满足 Pod 需求的节点(如资源不足、节点选择器不匹配)
打分(Scoring/Priorities):对剩余节点评分,选择得分最高的节点
# 调度策略配置示例
apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
profiles:
- schedulerName: default-scheduler
plugins:
score:
enabled:
- name: NodeResourcesBalancedAllocation
weight: 1
- name: ImageLocality
weight: 1kube-controller-manager
Controller Manager 运行着多个控制器进程,每个控制器负责一种资源的调谐。控制器的核心逻辑是"观察-对比-行动"循环:
观察资源的当前状态
与期望状态对比
执行操作使当前状态向期望状态收敛
主要的控制器包括:
- ReplicaSet Controller:维持指定数量的 Pod 副本
- Deployment Controller:管理 ReplicaSet,实现滚动更新
- Node Controller:监控节点状态
- Job Controller:管理一次性任务
- Endpoint Controller:维护 Service 和 Pod 的关联
- ServiceAccount Controller:为新 Namespace 创建默认 ServiceAccount
2.2.2 Worker 节点组件
每个 Worker 节点运行着三个关键组件:
kubelet
kubelet 是节点上的"代理人",它接收来自 API Server 的 Pod 规格,确保容器按照规格运行。kubelet 的主要职责:
- 管理 Pod 生命周期:创建、启动、停止、删除容器
- 监控容器状态:通过 Liveness/Readiness Probe 检测容器健康
- 报告节点状态:定期向 API Server 汇报节点资源使用情况
- 管理 Volume:挂载和卸载存储卷
# 查看 kubelet 状态
systemctl status kubelet
# 查看 kubelet 日志
journalctl -u kubelet -f
# 查看节点上的 Pod 信息
kubectl get pods --field-selector spec.nodeName=node-1kube-proxy
kube-proxy 在每个节点上维护网络规则,实现 Service 的负载均衡。它有三种工作模式:
- userspace 模式(已过时):通过用户空间代理转发流量
- iptables 模式(默认):使用 iptables 规则实现负载均衡
- IPVS 模式:使用 Linux IPVS(IP Virtual Server)实现更高效的负载均衡
# 查看 iptables 规则(iptables 模式)
iptables -t nat -L KUBE-SERVICES -n
# 查看 IPVS 规则(IPVS 模式)
ipvsadm -LnContainer Runtime
容器运行时负责实际创建和运行容器。Kubernetes 通过 Container Runtime Interface(CRI)与容器运行时交互。常见的运行时:
- containerd:从 Docker 中剥离出的轻量级运行时,CNCF 毕业项目
- CRI-O:专为 Kubernetes 设计的轻量级运行时
- Docker:通过 dockershim 支持(K8s 1.24+ 已移除内置支持)
2.3 声明式 API 模型
Kubernetes 最核心的设计理念是声明式 API:你告诉系统"我想要什么状态",Kubernetes 负责将实际状态收敛到期望状态。这与传统的命令式 API("执行这个操作")形成鲜明对比。
2.3.1 声明式 vs 命令式
# 命令式:告诉 K8s "做什么"
kubectl create deployment nginx --image=nginx
kubectl scale deployment nginx --replicas=3
kubectl set image deployment/nginx nginx=nginx:1.25
# 声明式:告诉 K8s "要什么"
kubectl apply -f deployment.yaml
# deployment.yaml 中定义了期望状态:3个副本、nginx:1.25 镜像
# K8s 自动完成从当前状态到期望状态的转换声明式的优势:
- 幂等性:多次 apply 同一个文件,结果一致
- 版本控制:YAML 文件可以存储在 Git 中,实现 GitOps
- 自动化:控制器自动处理故障恢复和状态收敛
- 可审计:期望状态和实际状态的差异可以被检测和告警
2.3.2 调谐循环(Reconciliation Loop)
每个控制器都运行着一个调谐循环:
while true:
current_state = get_current_state(resource)
desired_state = get_desired_state(resource)
if current_state != desired_state:
take_action(desired_state)
sleep(interval)例如,Deployment 控制器发现当前只有 2 个 Pod 副本,但期望是 3 个,它就会创建 1 个新的 Pod。如果某个 Pod 异常退出,控制器会检测到并创建替代 Pod。这就是 Kubernetes 的"自愈"能力。
2.4 核心抽象对象
2.4.1 Pod
Pod 是 Kubernetes 的最小调度单元。一个 Pod 包含一个或多个容器,这些容器共享网络命名空间(相同的 IP 地址和端口空间)和存储卷。
为什么需要 Pod?为什么不直接调度容器?因为有些应用需要紧密耦合的容器组合:
- Sidecar 模式:主容器 + 日志收集容器,共享日志目录
- Ambassador 模式:主容器 + 代理容器,代理外部访问
- Adapter 模式:主容器 + 标准化容器,统一监控接口
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080
volumeMounts:
- name: shared-data
mountPath: /data
- name: sidecar
image: fluentd:latest
volumeMounts:
- name: shared-data
mountPath: /var/log
volumes:
- name: shared-data
emptyDir: {}2.4.2 Service
Service 为一组 Pod 提供稳定的网络入口(IP 地址和 DNS 名称)。Pod 的 IP 是动态的——Pod 重启后 IP 会变化,但 Service 的 IP 和 DNS 名称是稳定的。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
type: ClusterIPService 类型:
- ClusterIP:集群内部访问(默认)
- NodePort:通过节点端口暴露
- LoadBalancer:通过云厂商负载均衡器暴露
- ExternalName:映射到外部 DNS 名称
2.4.3 Deployment
Deployment 管理 Pod 的副本数、滚动更新和回滚。它是生产环境中管理无状态应用的标准方式。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80Deployment → ReplicaSet → Pod 的层级关系是 Kubernetes 的核心设计模式。Deployment 管理 ReplicaSet 的版本,ReplicaSet 管理 Pod 的副本数。
2.4.4 Namespace
Namespace 提供逻辑隔离,用于在多租户环境中区分不同的项目、团队或环境。
kubectl create namespace development
kubectl create namespace production
kubectl get pods -n development
kubectl get pods --all-namespaces2.5 Kubernetes 的设计哲学
2.5.1 自动化
Kubernetes 的设计目标是最大限度地减少人工干预。一旦定义了期望状态,系统会自动处理:
- 故障恢复:Pod 异常退出时自动重建
- 滚动更新:自动按比例替换旧版本 Pod
- 扩缩容:根据 CPU/内存使用率自动调整副本数
- 调度:自动选择最优节点运行 Pod
2.5.2 可扩展性
Kubernetes 通过以下机制实现可扩展性:
- Custom Resource Definition(CRD):定义自定义资源
- Operator 模式:通过控制器扩展 K8s 的能力
- API 聚合:将自定义 API 集成到 API Server
- 插件机制:网络插件(CNI)、存储插件(CSI)、设备插件
2.5.3 声明式
如前所述,声明式 API 是 Kubernetes 的核心理念。用户定义"期望状态",系统负责"实际状态"的收敛。这种模式简化了运维操作,使得系统可以自动化处理各种场景。
2.5.4 自愈
Kubernetes 的自愈能力体现在多个层面:
- 容器级别:Liveness Probe 失败时重启容器
- Pod 级别:Pod 异常退出时由控制器重建
- 节点级别:节点不可用时将 Pod 迁移到其他节点
- 服务级别:Service 自动移除不健康的 Pod
三、实战案例
3.1 搭建本地 Kubernetes 集群
使用 Minikube
# 安装 Minikube(Linux)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动集群
minikube start --driver=docker --cpus=4 --memory=4096
# 验证集群
kubectl cluster-info
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# minikube Ready control-plane 1m v1.28.0
# 启用 Dashboard
minikube dashboard使用 Kind(Kubernetes in Docker)
# 安装 Kind
go install sigs.k8s.io/kind@latest
# 创建集群
kind create cluster --name my-cluster --config kind-config.yaml
# kind-config.yaml
# kind: Cluster
# apiVersion: kind.x-k8s.io/v1alpha4
# nodes:
# - role: control-plane
# - role: worker
# - role: worker
# 验证
kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# my-cluster-control-plane Ready control-plane 1m v1.28.0
# my-cluster-worker Ready <none> 1m v1.28.0
# my-cluster-worker2 Ready <none> 1m v1.28.03.2 第一次部署应用
# 创建 Deployment
kubectl create deployment hello --image=nginx:1.25 --replicas=3
# 查看 Deployment
kubectl get deployments
# NAME READY UP-TO-DATE AVAILABLE AGE
# hello 3/3 3 3 30s
# 查看 Pod
kubectl get pods -o wide
# NAME READY STATUS NODE
# hello-abc12-xyz1 1/1 Running minikube
# hello-abc12-xyz2 1/1 Running minikube
# hello-abc12-xyz3 1/1 Running minikube
# 创建 Service
kubectl expose deployment hello --type=NodePort --port=80
# 访问应用
minikube service hello --url
# http://192.168.49.2:31234
# 扩缩容
kubectl scale deployment hello --replicas=5
kubectl get pods
# 滚动更新
kubectl set image deployment/hello hello=nginx:1.26
kubectl rollout status deployment/hello
# 回滚
kubectl rollout undo deployment/hello3.3 使用 YAML 声明式部署
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.25-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 200m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: web-app
spec:
selector:
app: web-app
ports:
- port: 80
targetPort: 80
type: LoadBalancer# 声明式部署
kubectl apply -f deployment.yaml
# 修改副本数后再次 apply
kubectl apply -f deployment.yaml
# 查看事件
kubectl describe deployment web-app
kubectl get events --sort-by='.lastTimestamp'四、本章小结
第1章通过 Kubernetes 的起源、集群架构、声明式 API、核心抽象和设计哲学,为你建立了 Kubernetes 的全局视图。核心知识点包括:
Kubernetes 源自 Google Borg,继承了十多年大规模集群管理的经验,是云原生时代的操作系统。
集群由 Control Plane 和 Worker 节点组成:API Server 是统一入口,etcd 是状态存储,Scheduler 负责调度,Controller Manager 维护期望状态,kubelet 管理节点上的 Pod。
声明式 API 是核心理念:你定义"期望状态",Kubernetes 通过调谐循环自动将"实际状态"收敛到"期望状态"。
Pod 是最小调度单元,Service 提供稳定网络入口,Deployment 管理 Pod 副本和更新,Namespace 提供逻辑隔离。
设计哲学:自动化、可扩展、声明式、自愈——这些原则贯穿 Kubernetes 的每个设计决策。
后续章节将深入每个核心资源:第2章夯实容器基础,第3章实战应用部署,第4-5章深入 Pod 机制,第6章讲解控制器,第7章讨论配置管理,第8章探索持久化存储。
五、思考与练习
思考题
为什么 Kubernetes 选择 etcd 作为状态存储,而不是 MySQL 或 Redis?etcd 的 Raft 共识算法如何保证数据一致性?
声明式 API 和命令式 API 各有什么优缺点?在什么场景下你会选择命令式操作?
如果 API Server 宕机,已经运行的 Pod 会受到影响吗?为什么?
Pod 和容器的区别是什么?为什么 Kubernetes 不直接管理容器,而要引入 Pod 抽象?
Controller Manager 中的多个控制器如何避免冲突?例如,Deployment Controller 和 ReplicaSet Controller 如何协作?
练习题
使用 Minikube 或 Kind 搭建本地 K8s 集群,部署一个 Nginx 应用,并通过 Service 暴露服务。
手动删除一个 Pod,观察 ReplicaSet 的行为。解释发生了什么以及为什么。
使用 kubectl get pods -o yaml 查看 Pod 的完整 YAML,找出其中由系统自动生成的字段。
创建一个3副本的 Deployment,执行滚动更新(修改镜像版本),然后回滚到上一版本。使用 kubectl rollout history 查看更新历史。