
简介Kubernetes in Action是Marko Lukša所著的Kubernetes经典英文原版指南面向容器运维、后端开发与平台工程人员帮助读者从零理解到熟练运维Kubernetes集群。全书以实践为导向从Namespace、Pod等基础对象讲起逐章覆盖ReplicaSet、DaemonSet、StatefulSet、Deployment、Job/CronJob等控制器深入Service、Ingress的网络暴露方式以及ConfigMap、Secret配置管理、PV/PVC/StorageClass存储机制并包含安全上下文、RBAC等安全内容。书中配有大量可直接运行的示例和架构图解适合一边阅读一边在集群中验证。资源为单个PDF文件压缩包大小11.1MB轻量便于离线阅读。目前已有436人学习/浏览是快速掌握Kubernetes体系的高性价比选择。读者既能从中获得完整知识图谱也能在排障时查阅资源对象定义与最佳实践适合新手入门和进阶巩固。1. 为什么一本老书还能当Kubernetes入门首选先弄清这本英文原版PDF到底值不值得啃最近有位同事跑来问我手头有一份《Kubernetes in Action》的英文原版PDF听说这本书出了好几年Kubernetes都更新几代了现在拿它入门会不会过时我的回答是值得读但别照着抄得开着集群读。这本英文原版PDF最大的价值不是命令列表而是把“为什么这样设计”讲出来——Pod为什么成为调度的最小单元Service为什么要有一层抽象控制器模式和运维操作之间的关系是什么。新手看官方文档容易一头扎进细节看这本书能把骨架搭起来。如果你已经熟悉Docker想系统学Kubernetes或者准备考相关认证这本书是一份很稳的入门索引。但你也要做好心理准备书里的部分YAML和命令在今天的集群里已经跑不通了需要边读边用当前版本验证。2. 按目录拆解学习路线从Pod到Operator哪些章节值得精读《Kubernetes in Action》章节安排整体遵循“基础概念→核心负载→存储与安全→扩展模式”这条路径。我一般不建议从头到尾线性读而是按自己的目标切块。如果你只是日常使用Deployment和Service前八章就能覆盖大部分工作如果你想做平台开发或Operator后面的StatefulSet、RBAC和自定义资源才是重头戏。下面把我认为值得精读的部分拆开讲。2.1 第13章容器与集群基础别跳过的三个理由第一章介绍Docker和容器基础第二章讲Kubernetes整体架构第三章进入YAML语法。很多有Docker经验的人觉得第一章可以快速带过我建议还是翻一翻有三个理由。第一个理由是书里用了大量类比解释“Pod为什么是原子调度的单位”。它举了一个两个容器共享网络栈的例子一个容器做代理一个容器做业务进程它们必须同生共死因此被放进同一个Pod。这个理念比单纯记“Pod是最小调度单元”要扎实得多。为了验证这一点你可以在本地创建一个多容器Pod看看共享网络的效果apiVersion: v1 kind: Pod metadata: name: multi-container spec: containers: - name: proxy image: envoyproxy/envoy:v1.27.0 - name: app image: nginx:1.25这里两个容器共用一个Pod IPapp容器的端口对proxy来说就是localhost。书里对这类设计动机的解释是其他文档里很少见的。第二个理由是第二章讲解的集群组件图谱到现在也没有变。书里会带你初始化集群然后观察kube-apiserver、kube-scheduler、kube-controller-manager和kubelet各自负责什么。现在安装方式变了但控制面的角色划分完全一致。你要是跳过后面排查节点问题时会分不清是etcd、kubelet还是网络插件的原因。第三个理由是第三章的YAML讲解非常细。它从apiVersion、kind、metadata、spec讲到status并专门强调desired state与actual state的差异。这也是理解Kubernetes声明式模型的关键。哪怕你现在用helm或Kustomize最终解析出来的还是这些基础字段。学习这章时可以配合一条命令加深印象kubectl explain pod.spec.containers这条命令会输出容器字段的完整说明比PDF里更贴近当前版本。把书里的概念和kubectl explain的实时内容对照是我读这本书时最常用的一招。2.2 第48章核心负载与网络调度至少要亲手敲一遍这部分从第四章的Pod和ReplicaSet起步经过Deployment、Service、Ingress再到滚动更新、ConfigMap、Secret和存储卷是全书实战密度最高的地方。每一章都适合单独建一个临时集群去验证。以Deployment为例书里会从ReplicaSet讲起说明为什么需要更高一层的Deployment来管理发布历史。现在你仍然可以用kubectl create deployment快速创建一个但更规范的做法是写好YAML再applyapiVersion: apps/v1 kind: Deployment metadata: name: demo spec: replicas: 3 selector: matchLabels: app: demo template: metadata: labels: app: demo spec: containers: - name: demo image: nginx:1.25 ports: - containerPort: 80这段配置有两个易错点一是matchLabels必须和template.metadata.labels一致否则控制器无法圈定Pod二是ports只是声明信息真正能否访问还取决于Service选择器。书里对这两点的强调我在生产环境评审他人YAML时依然在用。第五、六章讲Service和滚动更新这是日常使用频率最高的功能。书里解释了三种Service类型的差别ClusterIP只能在集群内访问NodePort把端口暴露到宿主机LoadBalancer依赖云平台。你可以用一个命令感受一下kubectl create deployment demo --imagenginx:1.25 --replicas2 kubectl set image deployment/demo demonginx:1.26 kubectl rollout status deployment/demokubectl set image用于修改镜像rollout status会阻塞到更新完成。注意在旧版本里--record常用来记录变更原因现在这个参数已标记为弃用建议把变更记录释放到提交信息或说明文档里而不是依赖kubectl命令历史。第七、八章讲ConfigMap和Secret。书里会说不要把密码写进镜像要挂载到环境变量或文件。这里有个原则值得记牢ConfigMap按明文保存Secret虽然Base64编码但并不是加密它只是降低了误读概率。你可以在集群里这样验证kubectl create secret generic mypass --from-literalpasswordabc123 kubectl get secret mypass -o yaml输出里能看到password字段是Base64编码后的内容。如果你对安全性要求高还需要配合KMS或外部密钥管理工具做真正的加密。书里对这一点的边界讲得比较早今天的观点没有变。2.3 第9章之后无状态到有状态、存储、安全与扩展按需选读第九章开始讲StatefulSet和持久化存储这章和当前生产实践的连接更强。StatefulSet解决的问题是“每个Pod需要稳定网络标识和独立存储”典型场景是数据库、ZooKeeper这类有状态服务。书里会展示如何创建PVC然后让每个副本绑定一个Volume。现在你仍然可以照着写但要注意apiVersion已经统一为apps/v1而不是书里的apps/v1beta1。随后是Ingress。书里例子用的是extensions/v1beta1这种老版本在今天的新集群里已经不存在了。你需要把apiVersion改成networking.k8s.io/v1同时把backend.serviceName语法改成backend.service.name。这也是读者踩坑最多的地方我在下一章专门展开。第十章以后涉及认证授权、自定义资源、Operator模式等。这部分我认为可以先建立概念不必第一遍就啃完。RBAC的Role与ClusterRole、RoleBinding与ClusterRoleBinding的权限范围区别书里讲得很清楚而且现在也没有变。你可以通过一个只读权限的例子理解apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: namespace: default name: pod-reader rules: - apiGroups: [] resources: [pods] verbs: [get, list, watch]再绑定给某个ServiceAccount。这种配置用来限制应用读取Pod状态很常见。书里在讲解时常用“最小权限”作为引子这个思路到今天依然是安全基线的核心。所以总的读法是前八章精读第九章选读最后几章先索引等真正需要时再折回来。3. 跟着书里的案例在本地复现最小集群部署与命令对照书里给的实验大多假设你已经有一个集群。我推荐用kind在本地临时拉起一个多节点集群跑完直接销毁不污染本机环境。下面是我复现书里案例的标准操作。3.1 准备一个可用的本地集群安装与配置选择kind运行在Docker之上适合已有Docker的开发机。minikube则更适合没有Docker也想模拟完整虚拟机体验的场景。我的习惯是只验证Pod、Deployment、Service用kind单控制面节点就够若想观察调度器如何分配Pod到不同工作节点就配置两个worker节点。下面是一个典型的kind配置kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker保存为kind-config.yaml后执行kind create cluster --config kind-config.yaml创建完成后用kubectl cluster-info确认连接。这里有个小坑apiVersion: kind.x-k8s.io/v1alpha4会随kind版本变化如果你装了更新的kind可能要求写v1alpha4或更高碰到校验报错就去查当前版本支持哪种写法。书里这时的章节还在用minikube start --vm-driver现在minikube的驱动方式也变了所以不建议再照抄。3.2 复现第一个Pod和部署常用命令与yaml参数书里第一个例子通常是创建一个Pod并观察生命周期。你可以用命令快速完成kubectl run nginx --imagenginx:1.25 --restartNever --port80 kubectl get pods -o wide kubectl describe pod nginx--restartNever表示创建一个独立Pod而不是Deployment这是旧版kubectl和新版行为差异最大的地方。在新版kubectl中不带--restartNever的kubectl run可能会提示你创建Deployment语义已经发生变化。describe命令会展示事件列表比如镜像拉取进度、容器启动失败原因是排查问题第一入口。接着复现Deployment的扩缩容和滚动更新kubectl create deployment demo --imagenginx:1.25 --replicas3 kubectl scale deployment/demo --replicas5 kubectl rollout status deployment/demoscale用于调整副本数rollout status用于等待发布完成。但你需要注意kubectl create deployment自动生成的selector可能不是你手写YAML时预期的那组label。为了后续维护我建议直接使用kubectl apply -f deployment.yaml这样选择器和标签都由你控制也更贴近生产环境。3.3 书中的kubectl命令与当前版本差异对照我把读者常照抄的命令在现在的kubectl中会遇到的差异整理成一张对照表。这张表不覆盖所有命令只列最容易翻车的地方。书里常见写法当前推荐做法变化点kubectl run nginx --imagenginxkubectl run nginx --imagenginx --restartNever旧版默认生成Deployment新版必须显式指定控制器类型kubectl expose deployment demo --typeNodePort同左命令仍可用实际暴露端口范围为30000-32767kubectl set image deployment/demo demonginx:1.26 --record去掉--record修订原因写进提交信息--record已弃用kubectl get all同左默认返回的资源种类有增加注意结果变长kubectl delete pod --all同左不变但只删除Pod不影响Deployment重建这张表不是让你死记而是提醒你执行任何书里的命令前先看当前kubectl是否输出warning。凡是出现“deprecated”或“unknown field”都要停下来查一查而不是继续往下走。4. 阅读与实践中的避坑手册版本、网络插件和英文原版阅读障碍这章我集中写几条高频踩坑记录都是看这本英文原版PDF时容易绊倒人的地方。每条按“现象—原因—解决”的方式展开。4.1 现象书里的apiVersion是v1beta1当前集群不认账有人照着抄Ingress或StatefulSet文件执行kubectl apply时报错说“no matches for kind”。原因是Kubernetes在升级过程中把一批资源从v1beta1转移到稳定版并且移除了旧版本。Ingress就是一个典型例子。解决思路是先问集群支持什么版本。用kubectl api-resources | grep ingress能看到当前Ingress的API组和版本。比如我的集群里是networking.k8s.io/v1那就把文件头改成这个版本同时更新字段结构。书里的serviceName要改成service.nameservicePort改成service.port.number。更稳妥的做法是把书里的旧YAML当成“设计草图”然后用kubectl create --dry-runclient -o yaml生成当前版本的正确骨架再填自己的值。4.2 现象kubectl apply 提示字段已废弃但没报错另一种情况更隐蔽应用YAML时出现warning: unknown field或deprecated但资源还是创建了。这是因为kubectl做了向后兼容某些字段被忽略但不影响整体提交。比如给Service指定spec.loadBalancerIP当前版本可能接受这个字面量但底层实现已经不是当初那样IP未必会生效。我的习惯是把警告当作硬错误。提交前先执行kubectl diff -f deployment.yamldiff会对比当前集群状态和目标文件输出差异和警告。再配合kubectl explain查看字段定义比如kubectl explain service.spec如果某个字段显示Deprecated或DoNotUse那就要去官方文档找替代字段。这一步能帮你避开很多“状态看着正常实际行为不符合预期”的问题。4.3 现象DNS服务名和书里不一样Service网络不通在Pod内用curl my-service访问同Namespace的Service书里说默认就可以但实际操作时curl卡住或解析失败。大部分原因是CoreDNS没正常解析而不是Service没建好。可以通过以下步骤定位kubectl get pods -n kube-system -l k8s-appkube-dns kubectl run dns-test --imagebusybox --restartNever --command -- sleep 3600 kubectl exec dns-test -- nslookup my-service.default.svc.cluster.local如果解析失败先检查kube-system下CoreDNS的Pod是否Running再检查Service的clusterIP是否被分配比如kubectl get svc。还有一种常见情况是Pod里的/etc/resolv.conf指向的nameserver不是预期地址。你可以kubectl exec进去查看kubectl exec dns-test -- cat /etc/resolv.conf正常情况下nameserver是CoreDNS的ClusterIP。如果不对说明Pod创建时DNS配置坏了要查kubelet的--cluster-dns参数或网络插件配置。4.4 现象英文原版阅读速度慢重点抓哪些部分很多读者看到大段英文就头疼一页读二十分钟很快放弃。我的经验是不要逐词读。第一遍先看每章开头的小故事、中间的表格和最后的代码块。Kubernetes的核心术语反复出现Pod、Service、Deployment这些词通过目录和小标题就能建立索引。遇到不理解的英文叙述先找出对应的YAML和命令在集群里跑一遍远比你抱着字典读长句有效。我自己的做法是每读一章把该章出现的YAML片段集中收集到本地文件夹然后在集群里按顺序执行。英文文本只看它引出的结论和注意事项。如果某个概念实在搞不清就用中文搜索该概念的科普文章再回到原版PDF对照术语。这本书的英文其实并不算难难的是对分布式概念的陌生多读几遍后会发现高频词汇就那么二十来个。4.5 现象Pod一直ImagePullBackOff镜像拉不下来书里例子常常直接使用nginx或busybox镜像但你可能在受限网络环境或内网集群中操作拉取外部镜像超时Pod事件会出现Failed to pull image。解决思路有三种一是配置可用的镜像仓库或镜像加速器二是把镜像提前导入集群比如kind load docker-image myginx三是换成本地已有的私有镜像名称。这里的判断顺序是先用kubectl describe pod看事件里的错误码和URL确认是网络拒绝还是HTTP 401再决定换源还是登认证。5. 验证是否真的学会了用书末的示例项目做一次“独立部署考核”书看完了、命令敲完了但合上PDF你还能不能独立部署一套完整服务我建议做一个“一句话留言板”的小项目来考核自己前端Nginx后端Go服务数据用Redis或SQLite要求至少包含Deployment、Service、ConfigMap、Secret和PVC。这基本覆盖了书里最核心的编排对象做完之后你会对资源配置有整体把握。5.1 自己动手把书里的示例应用跑成一个完整服务下面是一个后端Deployment骨架可以替换成你自己的镜像来跑apiVersion: apps/v1 kind: Deployment metadata: name: board spec: replicas: 2 selector: matchLabels: app: board template: metadata: labels: app: board spec: containers: - name: board image: your-registry/board:latest envFrom: - configMapRef: name: board-config ports: - containerPort: 8080这里用envFrom把ConfigMap里的所有键值对注入为环境变量省去逐个声明env的麻烦。注意容器的启动命令和监听端口必须和这个端口对得上否则Service探活会失败。再额外创建一个ConfigMap和Service把Service设为NodePort本地就能用http://localhost:30250访问。如果还想验证持久化给Pod挂一个PVC写入数据后删除Pod再重建数据还在那就说明存储链路通。5.2 通过几个问题自查理解深度完成部署后你可以问自己四个问题为什么StatefulSet要求每个Pod有独立存储和稳定网络标识如果你的Pod一直处于CrashLoopBackOff你会怎么排查集群内部访问Service偶尔超时为什么可能和CoreDNS无关而是网络策略问题Secret和ConfigMap应用到Pod后为什么更新Secret不一定立即生效能答清楚这四点说明你已经不是照抄命令而是理解了Kubernetes的运行机制。最后说个我自己带新人的习惯每读一本经典技术书都做一份“版本迁移笔记”把旧写法抄在左边用当前集群验证后的新写法抄在右边踩过的坑写在下面。这个习惯让我后来升级集群时少慌了很多次。希望帮到你。本文还有配套的精品资源点击获取