先核对当前 kubecontext,只允许在 cloud-course-15 中创建课程对象。
外观
外观
约 3276 字大约 11 分钟
K3sk3dKubernetesPod
2026-07-30
[Windows PowerShell] wsl ~:打开本机默认的 WSL2 Ubuntu;本课使用准备好的本地隔离集群,不需要 SSH 登录 ECS。若个人电脑无法运行集群,使用教师提供的演示环境或实训数据。Compose 用一个文件描述多容器应用,Kubernetes 则进一步把“应用应该是什么样”交给控制面持续维护。本课先不追求复杂集群,只在准备好的本地隔离环境里发布一个 Nginx 站点,观察副本如何从 1 变成 3,以及 Service 怎样找到这些 Pod。
关键提醒
Kubernetes 的核心不是背命令,而是提交期望状态,再通过对象状态和实际请求,确认控制器是否把现实推进到了期望状态。
学完这一课,做到五件事:
describe、事件和探针状态排查常见启动问题。先创建本课使用的隔离集群(如尚未创建):
[WSL] k3d cluster create xpk-lesson15 --servers 1 --agents 0实训包清单文件位于 starter/manifests/(从智慧职教课程资源区下载 lab-15-starter.zip 解压到 ~/cloud-course/lab-15/)。
先确认集群上下文和命名空间,再提交工作负载清单。单副本站点可访问后,把副本数从 1 调到 3,并同时观察 Deployment、Pod 和 EndpointSlice。
如果页面打不开,不要只盯着 Pod 的 STATUS。标签、Service 选择器、端点、事件和探针分别回答不同问题,后面的案例会按这条顺序取证。
观看时留意:Kubernetes 接收期望状态后,为什么还要持续观察并调整实际状态?
与本课的关系:K3s 是轻量 Kubernetes 发行版,课程中的资源门禁和安装位置仍按正文决定。
根据 K3s 官方说明,Control Plane 节点至少需要 2 核 CPU 与 2 GB 内存,而且这还没算后续业务 Pod 的开销。在测试云主机 B 上,虽然配置有 4 核 CPU 与 3.7 GiB 内存,但预检发现此时可用内存仅剩 1.6 GiB 左右,且上面已运行了其他容器。
[ECS] nproc查逻辑 CPU 核心数。云主机 B 返回 4,满足最低需求。
[ECS] free -h看内存总量与剩余。评估能否部署集群要看 available,而不是只盯 free,更不能只拿总物理内存去硬套官方门槛。
[ECS] docker ps --format 'table {{.Names}}\t{{.Status}}\t{{.Ports}}'查看宿主机现有容器。发现已有业务在线时,本课会主动终止在远端 ECS 部署集群的计划,既不抢占已有资源,也不去强行停止未知服务。
安全边界
符合官方最低配置并不等于适合与既有业务混部。最低要求没算学生工作负载、镜像缓存和演练余量。资源预检不过时应当更换环境,而不是强行部署。
本课实操统一使用 OrbStack + k3d 隔离环境。k3d 可以在 Docker 容器里快速拉起轻量 K3s,适合随用随建、用完即清理。个人电脑无法稳定运行集群时,可以使用演示环境、实训数据或学校实验平台完成报告。
[WSL] kubectl config current-context查看 kubectl 当前连接的 Cluster Context。在敲任何变更命令前,先看清上下文,防止把测试清单误发到了其他集群中。
[WSL] kubectl get nodes -o wide查看节点状态、Kubernetes 版本、内部 IP 与容器运行时。节点显示 Ready 说明集群控制面正常,但应用启动还没做完。
先把各对象的关系与边界梳理清楚:
| 对象 | 本课实例名称 | 主要职责 | 常见的认识误区 |
|---|---|---|---|
| Node | k3d-xpk-lesson15-server-0 | 提供 CPU、内存与容器运行环境 | 节点 Ready,业务不一定能访问 |
| Pod | 自动生成的 lesson15-web-... | 运行具体的 Nginx 容器 | Pod IP 和名字随时会变,不能作稳定入口 |
| Deployment | lesson15-web | 维护指定的副本数与 Pod 模板 | 副本 3/3,Service 选择器可能没配上 |
| Service | lesson15-web | 提供固定虚拟 IP/DNS,把请求路由到对应 Pod | ClusterIP 默认只在集群内部可达 |
Pod 是 Kubernetes 调度的最小基本单位。在生产实践中,极少直接手动创建孤立 Pod,而是交由 Deployment 统一管控——因为手动建的 Pod 被杀掉后不会自动恢复。
Deployment 的关键字段结构:
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: lesson15-web
template:
metadata:
labels:
app.kubernetes.io/name: lesson15-webreplicas: 1 表示期望一个副本。selector.matchLabels 必须与 Pod 模板标签匹配,Deployment 才知道哪些 Pod 属于自己。
观看时留意:Deployment 怎样通过 ReplicaSet 维持指定数量的 Pod?
与本课的关系:看完后把视频中的对象关系对应到本课 deployment.yaml 和扩容结果。
Service 使用同一标签:
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: lesson15-web
ports:
- port: 80
targetPort: httpClusterIP 提供集群内部稳定入口。targetPort: http 指向容器中命名为 http 的端口;它比直接重复数字更容易阅读,也能减少改端口时的遗漏。
沿 Deployment、Pod、就绪探针、标签选择和 EndpointSlice 走一遍 Kubernetes 工作负载链路。
先核对当前 kubecontext,只允许在 cloud-course-15 中创建课程对象。
本课清单放在 starter/manifests/,包括 Namespace(命名空间)、ConfigMap(配置映射)、Deployment 和 Service。先只读预览:
[WSL] kubectl kustomize starter/manifests展开 kustomization.yaml 引用的全部资源,不提交到集群。检查命名空间是否为 cloud-course-15,镜像、标签、探针和资源限制是否符合本课要求。
[WSL] kubectl apply --dry-run=client -k starter/manifests在客户端检查对象能否生成。--dry-run=client 不创建资源,离服务端真正通过准入、拉镜像、启动运行还有距离。
[WSL] kubectl apply -k starter/manifests把期望状态提交给当前集群。apply 会显示哪些对象被创建或更新。
[WSL] kubectl rollout status deployment/lesson15-web -n cloud-course-15 --timeout=120s等待 Deployment 达到可用状态,最多 120 秒。出现 successfully rolled out 后再继续,不要用连续重复 apply 掩盖启动问题。
[WSL] kubectl get nodes -o wide确认节点 Ready 和实际 K3s 版本。
[WSL] kubectl get pod,service -n cloud-course-15 -o wide同时查看 Pod 与 Service。单副本基线应包含一个 1/1 Running 的 Pod;Service 类型应为 ClusterIP,并显示标签选择器。
2026-07-28 在本地隔离 k3d 集群中的真实结果:
教师机本地 k3d 隔离集群 · K3s v1.35.5+k3s1 · 2026-07-28 真实运行
teacher@local:lab-15$ kubectl get nodes -o wideNAME STATUS ROLES VERSIONk3d-xpk-lesson15-server-0 Ready control-plane v1.35.5+k3s1INTERNAL-IP OS-IMAGE CONTAINER-RUNTIME192.168.107.2 K3s v1.35.5+k3s1 containerd://2.2.3-k3s1这条命令读取 Kubernetes 资源状态。READY、AVAILABLE、STATUS 和镜像字段描述工作负载,不能与 kubectl 自身的退出状态混为一谈。
这一步是“本地隔离节点 Ready,一个 Pod 为 1/1 Running,Service 为 ClusterIP 且选择器正确”证据链中的一环。
不能证明云主机 B 安装了 K3s、HTTP 页面正确或集群长期稳定

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
Service 不根据 Pod 名称找后端,而是根据标签选择器持续选择 Pod。Kubernetes 会把结果写入 EndpointSlice(端点切片——记录当前就绪后端地址的对象)。
[WSL] kubectl get endpointslice -n cloud-course-15 \
-l kubernetes.io/service-name=lesson15-web -o wide只查看属于 lesson15-web Service 的 EndpointSlice。单副本时预期有一个就绪端点地址。
[WSL] kubectl exec -n cloud-course-15 deploy/lesson15-web -- \
wget -q -O - http://lesson15-web在工作负载 Pod 内访问 Service DNS 名称。预期页面包含 K3s service ready。这条路径证明集群 DNS、Service、端点和 Nginx 返回内容能够串起来,但它仍然只是集群内部访问。
cloud-course-15 命名空间 · 2026-07-28 真实运行
...$ kubectl exec -n cloud-course-15 deploy/lesson15-web -- \
wget -q -O - http://lesson15-web<!doctype html><html lang="zh-CN"> <head><meta charset="utf-8"><title>K3s Lesson 15</title></head> <body> <h1>K3s service ready</h1> <p>deployment=lesson15-web</p> </body></html>这条命令沿实际访问路径发起请求。状态码、响应头或正文是本步的判断依据;只看到一次响应,还不能说明服务长期稳定。
这一步是“Pod 内能通过 Service DNS 获得预期 HTML,捕获时 EndpointSlice 包含一个后端地址”证据链中的一环。
只证明集群内部路径,不证明 Windows 浏览器、公网入口或长期可用

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
关键提醒
Service 的稳定性来自名称、虚拟地址和标签选择,不来自某个固定 Pod。应用扩容或 Pod 重建后,Service 名称不需要改变。
观看时留意:Service 怎样用标签选择器找到会变化的 Pod,并提供稳定入口?
与本课的关系:Service 是否有端点要用 selector、Pod 标签和 EndpointSlice 一起验证。
[WSL] kubectl scale deployment/lesson15-web -n cloud-course-15 --replicas=3把 Deployment 的期望副本数改为 3。命令返回 scaled 只说明修改请求被接受,还没有证明三个副本都可用。
[WSL] kubectl rollout status deployment/lesson15-web \
-n cloud-course-15 --timeout=120s等待控制器创建新 Pod,并让副本通过就绪探针。
[WSL] kubectl get deployment,pods -n cloud-course-15 -o wide检查 Deployment 是否为 3/3,以及三个 Pod 是否都为 1/1 Running。Pod IP 不同是正常现象。
[WSL] kubectl get endpointslice -n cloud-course-15 \
-l kubernetes.io/service-name=lesson15-web -o wide检查 Service 后端是否从一个增加到三个。若 Deployment 已经 3/3 但端点数为 0,优先检查 Service 选择器与 Pod 标签是否匹配。
本地 k3d/K3s 隔离集群 · 2026-07-28 真实扩容
...$ kubectl scale deployment/lesson15-web -n cloud-course-15 --replicas=3deployment.apps/lesson15-web scaled“调整工作负载副本”保留了完整命令和与它相邻的输出。判断时应直接引用输出中的字段或状态,不要把步骤名称当成结论。
这一步是“Deployment 达到 3/3,三个 Pod 均就绪,EndpointSlice 收录三个地址”证据链中的一环。
不证明流量绝对均匀,也不代表跨节点高可用或生产容量

整页截图与上方分步卡片来自同一条记录;敏感字段已经遮盖,较长命令可能经过换行排版。
| 现象 | 第一条检查 | 重点字段 | 下一步 |
|---|---|---|---|
| Pod 为 Pending(调度等待) | kubectl describe pod | Events、调度原因、资源请求 | 检查节点资源和调度约束 |
| Pod 为 ImagePullBackOff(镜像拉取失败) | kubectl describe pod | 镜像名、拉取错误 | 核对镜像和网络,不上传凭据截图 |
| Pod 为 Running 但 0/1 | kubectl describe pod | Readiness、探针事件 | 检查路径、端口和启动时间 |
| Service 无端点 | kubectl get svc,pod --show-labels | selector 与 labels | 修正不匹配的一侧并回归 |
| Service 有端点但请求失败 | kubectl exec ... wget | DNS、HTTP、应用响应 | 再看日志和容器监听 |
[WSL] kubectl describe deployment lesson15-web -n cloud-course-15查看 Deployment 条件、滚动过程和近期事件。输出较长,报告只截取与当前结论有关的部分。
[WSL] kubectl get events -n cloud-course-15 \
--sort-by=.metadata.creationTimestamp按时间查看本命名空间事件。事件会被轮转,适合定位近期问题,不是永久审计记录。
[WSL] kubectl logs -n cloud-course-15 deploy/lesson15-web --tail=30查看一个工作负载 Pod 的最近 30 行日志。多个副本出现问题时,应先用 kubectl get pods 找到具体 Pod,再逐个比较。
输入脱敏后的对象状态、标签、事件或请求结果,让助教区分期望状态、就绪、服务发现和用户路径。
本实验的原始聊天仅保存在当前标签页,不会写入全局课程助教上下文。
本课只修改课程命名空间中的 Service 选择器,并先保存原值:
[WSL] kubectl get service lesson15-web -n cloud-course-15 -o yaml \
> lesson15-service.before.yaml保存故障前的 Service 清单,作为恢复依据。文件不含密钥,但报告只需记录保存动作,不上传整个集群配置。
[WSL] kubectl patch service lesson15-web -n cloud-course-15 \
--type=merge -p '{"spec":{"selector":{"app.kubernetes.io/name":"wrong-label"}}}'把选择器改成不存在的标签。Service 对象仍然存在,三个 Pod 也仍是 Running,但 EndpointSlice 会变成没有后端。
[WSL] kubectl get service,pods,endpointslice -n cloud-course-15 --show-labels并排检查选择器、Pod 标签与端点。原始现象应保留在报告中,再执行修复。
[WSL] kubectl apply -f starter/manifests/service.yaml用版本控制中的原始清单恢复 Service。kubectl get -o yaml 保存的文件包含 resourceVersion 等服务端字段,适合取证;未经清理时不应直接把它当恢复清单,否则可能因资源已经变化而冲突。
[WSL] bash verify.sh重新检查上下文、命名空间、Deployment、就绪 Pod、Service 选择器、端点数量和页面内容。恢复后必须沿原来的 Service 请求路径回归。
安全边界
不要删除其他命名空间,不要修改集群系统组件,也不要用 kubectl delete all --all -A 之类的全局清理命令。
[WSL] kubectl delete namespace cloud-course-15 --wait=true只删除本课命名空间,等待其中资源完成清理。演示集群按课程环境统一保留或删除,不要操作未知集群。
[WSL] kubectl get namespace cloud-course-15预期返回 NotFound。这是本课资源已经离开当前集群的证据。
完整步骤见实训 15:K3s 工作负载、Service 与扩缩容。
提交文件名:
班级_学号_姓名_第15次课_K3s入门报告.docx只提交一个 Word 到智慧职教“第15次课”。截图要包含命令、关键结果、环境和证明范围;不要提交 kubeconfig、令牌、证书、完整集群配置或其他命名空间数据。
检查环境门禁、对象关系、扩容证据、故障恢复、清理和集群凭据边界。
用 6 道题检查资源门禁、对象职责、标签选择、扩容、故障证据和清理。
下一次课将在新的隔离集群中完成 Kubernetes 滚动发布、错误版本诊断与回滚。
以下资料在 2026-07-28 核对:
助教会读取当前课程页面和结构化学习记录,但不会读取正文实验框里的原始聊天。