☰
Kubernetes in Action实践:从Pod到Service的完整部署与排障指南
2026/10/12 14:50:19 网站建设 项目流程

简介:《Kubernetes in Action》英文原版 PDF,是一本面向云原生开发者、运维工程师和系统架构师的 Kubernetes 实战指南。书中从基础容器编排讲起,系统讲解基于容器的自动化部署、弹性伸缩与集群管理,涵盖集群级资源、命名空间、Pod、Deployment、Service、Ingress、ConfigMap、Secret、PersistentVolume 等核心对象;同时结合大量可操作示例,帮助读者理解从单机容器到多节点集群、从无状态应用到有状态工作负载的完整演进路径。该版本为单个 PDF 文件,压缩包约 11.1MB,便于离线阅读和按章节检索;书内附带的 Kubernetes 资源速查表能帮助读者快速理清各类 API 资源的用途与关联。目前已有 436 人学习浏览,适合有一定容器基础、希望深入掌握 Kubernetes 核心机制,或准备 CKA 等认证的读者。借助书中的实战示例与排错思路,读者不仅能掌握工作负载、服务发现和持久化存储的选择方法,也能在实际搭建集群时更有条理地落实生产级配置。

1. 为什么《Kubernetes in Action》是开发者绕不开的那本 Kubernetes 手册

如果你正在学 Kubernetes,十个运维里九个会推荐你先翻《Kubernetes in Action》英文原版。它不是一本讲理论的百科书,而是从一开始就把你按在电脑前、跟着命令和 YAML 把集群跑起来的那种“动手型”教材。英文原版 PDF 在社区里流传很广,很多开发者第一遍读的是中文翻译版,回头查细节时还是切回英文原文——因为 YAML 字段名、kubectl 输出、官方文档的表述都是以英文为基准的,直接读原版能少一层转译损耗。

这本书适合谁?刚接触容器编排的后端开发、准备把服务迁到 K8s 的运维、以及那些“看了很多概念但没真正部署过一个完整应用”的人。它最大的价值是把 Pod、Deployment、Service 这些抽象概念还原成一条能跟着跑的完整链路。这篇文章不讨论怎么找资源文件,而是把书里那条“从零到部署”的主线拆出来,让你即使没拿到书,也能跟着这套思路亲手搭一个可用的集群工作流。

2. 理解 Kubernetes 的核心模型:从 Pod 到 Service 的完整链路

2.1 为什么先理解 Pod,再谈容器编排

Kubernetes 不直接管容器,它的最小调度单位是 Pod。刚开始学的人最容易在这个概念上卡住:明明我已经会用 Docker 了,为什么还要多套一层 Pod?

一个 Pod 里可以跑一个容器,也可以跑多个容器。多容器共享同一个网络命名空间和存储卷,意味着它们可以用 localhost 互相访问。书中反复强调的一个典型场景是 sidecar 模式——主容器跑业务逻辑,sidecar 容器负责打日志、做代理或刷新配置。理解了这个模型,你才能明白为什么 Kubernetes 不直接以容器为调度单元:它需要把“一组进程”绑定在同一台机器上,共享生命周期和资源。

我一般会建议新手先做一个实验:创建一个同时跑 nginx 和 curl 的 Pod,进入容器后用curl http://localhost直接访问另一个容器。你会立刻体会到 Pod 内共享网络的便利,也就理解了为什么日志收集这类服务天然适合作为 sidecar 而不是独立 Pod。

2.2 Deployment 和 StatefulSet 的选型逻辑

书里讲了多种工作负载资源,但你日常用到最多的就是 Deployment 和 StatefulSet。Deployment 管理无状态应用,Pod 挂了就重新拉起一个,镜像更新时滚动替换。StatefulSet 则给每个 Pod 一个稳定的网络标识和持久化存储,适合数据库、消息队列这类有状态服务。

选型判断标准其实很简单:你的应用实例之间是否依赖“谁是谁”?比如 Redis 集群里的节点需要知道自己是 master 还是 slave,这是 StatefulSet 的领域;而一个无状态的 Web API,任意实例处理请求都一样,用 Deployment 就够了。

2.3 Service 如何把流量带到 Pod

Pod 的 IP 是临时的,重启就变。Service 的职责就是为这组不稳定的 Pod 提供一个稳定的访问入口。它通过标签选择器把你 Deployment 管理的 Pod 找出来,然后做一个虚拟 IP 的负载均衡。

书里有一个比喻我印象很深:Service 像是藏在幕后的调度员,Pod 像舞台上的演员——观众只需要知道调度员的名字,不需要关心演员今天谁上场。理解 Service 的 selector 字段是你写好 YAML 的关键,selector 匹配不到任何 Pod,Service 就是个空壳。

3. 用 minikube 在本地跑通 Kubernetes:最小可行环境

3.1 本地环境安装与启动

读书不跟着敲命令等于白读。我建议用 minikube 做本地环境,它比 kind 更容易让新手建立“集群感”。安装完驱动后,启动一个单节点集群:

minikube start --driver=docker --cpus=2 --memory=2048 kubectl get nodes

第一行命令指定了使用 docker 驱动,并给虚拟机分配 2 核 CPU 和 2GB 内存。kubectl get nodes如果返回一个 Ready 状态的 node,说明集群已经正常运行。

参数说明:--cpus和--memory要根据你的电脑配置调整,低于 1.5GB 内存跑起来会非常卡。如果是在 Mac 上跑,建议用--driver=hyperkit而不是 docker,性能更好。

3.2 部署第一个应用:从镜像到 Pod

环境就绪后,试着手动创建一个 Pod,不要一上来就写 YAML,先感受一下资源模型:

kubectl run nginx-pod --image=nginx:1.25 --port=80 kubectl get pods -w

kubectl run会直接创建一个 Deployment(在新版本中),--image指定容器镜像,--port是声明容器监听的端口,方便后续 Service 关联。-w参数持续监听 Pod 状态变化,你会看到ContainerCreating到Running的完整过程。

熟练之后,你会明白所有kubectl run背后都是一份 YAML 清单。书里的练习也是这个顺序:先用命令快速验证,再回头看生成的 YAML 理解字段含义。运行kubectl get deployment nginx-pod -o yaml可以直接查看。你看到的 image、replicas、selector 这些字段,就是后面手动编排的核心。

3.3 三个必调的本地环境参数

本地跑 K8s 和云上不一样,有些参数不调会直接影响体验。kubectl的默认上下文要确认指向 minikube,否则命令会打到别的集群:

kubectl config current-context kubectl config use-context minikube

minikube 的资源配置如果不够,可以把 Docker 的cgroup驱动改成systemd,避免节点内置组件报错。第三个是默认命名空间的隔离习惯——我建议你新建一个自己名字的 namespace,练习时所有资源都放在里面,避免和系统组件混在一起:

kubectl create namespace k8s-practice kubectl config set-context --current --namespace=k8s-practice

4. 把应用真正跑进集群:YAML 编排与资源管理

4.1 编写 Deployment 的 YAML:核心字段拆解

你现在要做一个完整的 Deployment 实践:从一份 YAML 文件开始,把应用在集群中正式跑起来。下面是一份最小但完整的 Deployment 配置:

apiVersion: apps/v1 kind: Deployment metadata: name: demo-web labels: app: demo-web spec: replicas: 3 selector: matchLabels: app: demo-web template: metadata: labels: app: demo-web spec: containers: - name: demo-web image: nginx:1.25 ports: - containerPort: 80 resources: requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 256Mi readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10

这段 YAML 做四件事:定义了 3 个副本;用 selector 管理所有带app: demo-web标签的 Pod;给容器设置了资源配额;加了一个就绪探针。resources.requests是调度器分配节点的依据,limits是运行时允许使用的上限。探针在这里是暴露了最多问题的字段——如果你不加,滚动发布时流量会打到还没就绪的 Pod 上。

4.2 让应用对外可见:Service 与 Ingress 的选型

Deployment 跑起来了,但集群外访问不到。你需要一个 Service 把 Pod 的端口暴露出来。Service 的 type 不同,暴露方式不同:

apiVersion: v1 kind: Service metadata: name: demo-web-svc spec: selector: app: demo-web ports: - port: 80 targetPort: 80

在本地 minikube 环境里,用 NodePort 就够。生产环境则用 LoadBalancer 结合云厂商的负载均衡器。Ingress 是七层的路由层,适合按域名或路径分发流量——它需要先部署对应的 ingress-controller,否则既不报错也不生效,这点很容易踩坑。

4.3 灰度发布与回滚:应用更新的两个关键操作

Deployment 的价值体现在更新应用时。你改一下镜像版本,kubectl apply之后,Kubernetes 会自动执行滚动更新:

kubectl set image deployment/demo-web demo-web=nginx:1.26 kubectl rollout status deployment/demo-web kubectl rollout undo deployment/demo-web

set image把容器镜像从 1.25 改成 1.26;rollout status跟踪滚动进度;如果发现问题,rollout undo一条命令就能回滚到上一个版本。这是书里强调最多的操作——生产环境里,回滚能力比部署能力更保命。

5. Kubernetes 日常避坑:3 个最容易翻车的场景及排查

5.1 坑一:镜像拉取失败(ImagePullBackOff)

现象:Pod 状态一直停在ImagePullBackOff,kubectl describe pod里能看到Failed to pull image的报错。

原因:镜像名称拼写错误、镜像不存在、私有仓库没有配置拉取凭据、或者本地没有该仓库的登录记录。

解决:先用docker pull单独验证镜像是否可以拉取。如果是私有仓库,在 Deployment 的 template 里加上imagePullSecrets,并通过以下命令生成并绑定密钥:

kubectl create secret docker-registry my-registry \ --docker-server=registry.example.com \ --docker-username=user \ --docker-password=pass

注意,密钥也只是 Kubernetes 里的普通资源,要和 Deployment 放在同一个 namespace 才生效。这是每次排查都要确认的第一件事——问题往往不是密钥不存在,而是命名空间配错了。

5.2 坑二:Pod 一直 Pending 或 CrashLoopBackOff

现象:kubectl get pods显示 Pod 一直Pending,或者不断重启(CrashLoopBackOff)。

原因:Pending 通常是资源不足——requests 比节点可分配的量还大,调度器找不到合适的节点。CrashLoopBackOff 则是因为启动后崩溃,可能是启动命令不对、配置缺失或探针失败。

解决:先kubectl describe pod看调度失败的具体原因和节点资源事件。再看日志确认进程为什么退出:

kubectl logs <pod-name> --previous

--previous很关键。CrashLoop 的 Pod 里,当前容器已经挂了,不加--previous可能拿不到上次崩溃的日志。有时候你会发现探针的initialDelaySeconds写得太短,应用启动时间本来就长,探针先判定失败,然后强行终止容器——这类问题多看describe里的事件就会恍然大悟。

5.3 坑三:Service 不通、DNS 解析失败

现象:Service 创建了,但 curl Service IP 没有响应,或 Pod 里解析不了 Service 名称。

原因:最常见的是 selector 写错了——Pod 标签拼写和 Service 的 selector 不一致,endpoints 列表为空。其次是集群 DNS 服务故障,导致域名解析失败。

解决:先确认有没有 endpoints:

kubectl get endpoints demo-web-svc

如果列表为空,检查 selector。如果 endpoints 存在但访问还是失败,再看 kube-proxy。进入 Pod 里用nslookup测一下 DNS 是否正常:没有部署 DNS 插件这种基础错误也时有发生,dnsPolicy写成了Default就会绕过集群 DNS。

6. 进阶验证技巧:用临时 Pod 做集群排障

读《Kubernetes in Action》到后面,你会发现除了写 YAML 之外,真正拉开你和新手差距的是排障思路。我常用的一个技巧很简单:跑一个临时 Pod,把需要验证的工具全装在里面,用完就删——这个思路在考察命令时尤其突出。比如,你需要验证 Service 连通性,直接在集群内部发起请求比从外部绕更直接:

kubectl run debug-pod --rm -it --image=nicolaka/netshoot -- /bin/bash curl http://demo-web-svc:80

--rm退出时自动删除 Pod,netshoot镜像里预装了 curl、dig、tcpdump 等排障工具。这套做法在生产环境和本地都通用,不用在业务容器里装额外的调试工具。

书里最后几章还会涉及 Ingress、持久化卷和监控,但核心是你亲手做完一次完整部署之后再追这些概念,理解会快得多。当你完成一个 Deployment 加 Service 的完整部署,再用kubectl get all看到自己的应用都在运行,那种打通链路的感觉非常值得。我现在的习惯是:看完每一章,都会自己写一遍命令,再刻意删掉重来——删掉再部署的过程往往就是查缺补漏的过程。希望这个思路能帮到你,少走一点我当年对着黑匣子发愁的弯路。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询