外观
第一节 个人电脑上的本地模拟工具链
约 6063 字大约 20 分钟
KubernetesDockerkindkubectl
2026-07-27
本课目标
理解 Kubernetes 解决的问题、核心工作方式、采用收益与边界;完成 Docker、kind、kubectl 与 Helm 的环境检查或安装,确认个人电脑可以进入下一步 kind 集群实验。最终只提交两张终端截图,不需要另外编写安装报告。
1.1 先认识项目:云帆商城是什么
云帆商城是贯穿本课程 13 次课的虚构电商业务,用来提供一条稳定的 Kubernetes 运维主线。它不是需要从零开发的完整商城,也不对应真实生产系统;本课程关注的是“怎样为一个包含 Web 与数据库的应用建设可重复、可验证的运行平台”。
课程把它抽象为四部分:
| 组成 | 在业务中的职责 | 后续对应的 Kubernetes 内容 |
|---|---|---|
| 商城 Web 服务 | 展示商品页面并接收访问请求,使用 Nginx 容器代表无状态业务 | Pod、Deployment、滚动更新、健康探测、HPA |
| MariaDB 数据服务 | 保存商品、订单等需要持久化的数据,代表有状态业务 | StatefulSet、PV/PVC、ConfigMap、Secret、Helm |
| 运行配置 | 保存环境参数和数据库连接信息 | ConfigMap 与 Secret |
| 访问入口 | 为变化中的 Web 副本提供稳定地址和流量分发 | Service、DNS、NodePort 或端口转发 |
课程不会实现购物车、支付或订单业务代码。只要 Web 容器能稳定发布、访问和扩缩,MariaDB 能正确使用配置与存储,就足以承载后续运维任务。
当前运行方式
在课程开始时,先假设云帆商城运行在一台服务器上:一个 Nginx Web 容器提供页面,一个 MariaDB 实例保存数据,启动、更新和故障恢复主要依赖手工操作。
这个初始架构并不“错误”。当访问量较小、只有一个运行实例时,它比 Kubernetes 更简单,也更容易维护。
当前方式在规模扩大后会遇到什么问题
这套方式成立的前提是“服务少、实例少、单机资源足够、短暂中断可以接受”。当这些条件开始变化时,下面的问题才会逐渐出现:
| 现状 | 人工处理方式 | 规模扩大后的问题 |
|---|---|---|
| 一个 Web 容器停止 | 登录服务器并重新启动 | 故障发现和恢复依赖人工值守 |
| 访问量突然增加 | 手工启动更多容器 | 副本分散在哪些机器、流量怎样分配都要单独处理 |
| 发布新版本 | 停止旧容器,再启动新容器 | 容易产生中断,失败后的回退步骤不统一 |
| 服务数量增加 | 手工维护端口和地址 | 容器重建后地址可能变化,服务之间难以稳定发现 |
| 多台机器共同运行 | 逐台登录和执行命令 | 环境、参数和操作结果容易不一致 |
这些问题的共同点不是“不会启动容器”,而是:容器数量增加后,怎样持续保持整个应用系统处于预期状态。
所以需要一种怎样的管理工具
仅仅增加更多启动脚本还不够。云帆商城需要的管理工具至少应该具备以下能力:
- 接收“Web 服务应该始终有几个副本”这样的目标,而不是只执行一次启动命令。
- 持续观察容器和节点状态,发现偏差后主动恢复。
- 把工作负载安排到合适的机器,不再逐台登录操作。
- 在容器地址变化后,仍然提供稳定的服务入口。
- 按可控节奏发布新版本,并在失败时回退。
- 使用可以保存、审查和重复应用的配置描述整个系统。
这些需求共同指向一种“面向期望状态、能够持续协调多个容器和节点”的管理平台,Kubernetes 就是为这类问题设计的。
Kubernetes 是什么
Kubernetes,简称 K8s,是一个用于管理容器化工作负载和服务的开源平台。它把多台机器组织成一个集群,并通过统一 API 管理应用的部署、调度、扩缩容、网络入口、配置和故障恢复。
可以把两种管理方式理解为:
- 使用 Docker 时,常见操作是“现在启动这个容器”。
- 使用 Kubernetes 时,常见操作是“我希望这个应用始终有 3 个可用副本,并通过一个稳定入口提供服务”。
后一种描述叫作期望状态。Kubernetes 会不断观察实际状态,并通过控制器把实际状态拉回期望状态。
这个过程不是只执行一次的安装脚本,而是持续运行的控制循环。例如某个副本异常退出后,控制器会发现“实际 2 个、期望 3 个”的差异,并请求创建替代副本。
一句话理解
Kubernetes 不负责把源代码变成应用;它负责让已经容器化的应用按照声明的状态持续运行。
Kubernetes 具体能做什么
| 能力 | 解决的问题 | 云帆商城中的例子 |
|---|---|---|
| 调度 | 应该把工作负载放到哪台节点 | 根据资源情况为 Web Pod 选择节点 |
| 自愈 | 容器或 Pod 失败后怎样恢复 | 自动创建替代副本 |
| 服务发现与负载均衡 | 地址变化后怎样稳定访问 | 使用 Service 为多个 Web Pod 提供统一入口 |
| 滚动更新与回滚 | 怎样减少发布中断 | 逐步替换 Web 版本,异常时回退 |
| 水平扩缩容 | 访问量变化时怎样调整副本 | 根据指标增加或减少 Web Pod |
| 配置与密钥载体 | 怎样把运行配置与镜像分开 | 使用 ConfigMap 与 Secret 注入配置 |
| 存储编排 | 容器重建后怎样继续使用数据 | 为有状态服务绑定持久卷 |
这些能力带来的主要收益是:
- 自动化:把反复登录机器执行的操作转成 API 对象和控制循环。
- 一致性:同一份声明式配置可以重复应用和审查。
- 可恢复性:控制器能持续发现并修正部分运行偏差。
- 可扩展性:应用副本可以在多节点间调度和扩缩。
- 可观察性基础:资源状态、事件和变更记录形成统一排错入口。
回到最初的问题:云帆商城需要 Kubernetes 吗
现在才能作出判断。云帆商城不是因为“用了 Docker 就必须迁移”,而是因为本课程假设它已经出现以下需求:
- Web 服务需要多个副本,单个实例故障不能让入口完全中断。
- 发布过程需要逐步替换和回滚,不能每次都整体停机。
- Web、数据库、配置和网络入口需要统一描述与验证。
- 后续还要练习服务发现、健康探测、持久化、调度和自动扩缩容。
这些需求与 Kubernetes 的调度、自愈、服务发现、滚动更新和声明式管理能力相匹配,因此本课程选择 Kubernetes 作为统一管理层,再使用 kind 在个人电脑上建立低成本的模拟集群。
迁移并不总是收益更大
Kubernetes 会增加集群组件、网络、存储、权限、监控和排错复杂度。只有一个访问量稳定的小应用时,单机 Docker Compose 或托管应用平台可能更简单。Kubernetes 也不会自动修复程序逻辑错误、设计数据库备份、构建镜像或替代完整的监控告警系统。
迁移不是把所有内容一次性搬进去
更稳妥的顺序是先迁移无状态 Web 服务,再逐步处理配置、访问入口和自动扩缩容。有状态数据库需要单独验证持久化、备份、恢复、性能和故障切换;如果已有成熟的托管数据库,也可以继续让数据库运行在集群外。
看完后回答
- Kubernetes 管理的是源代码,还是已经容器化的工作负载?
- 为什么“期望状态”比逐台机器执行命令更适合管理多个副本?
- 哪一种小型应用场景可能暂时不需要 Kubernetes?
本课为什么先准备工具链
理解采用理由后,再准备本地实验所需的四个工具:
直接创建集群之前,先确认三个条件:
- Docker Engine 能正常运行容器。
- kind、kubectl 与 Helm 命令可以执行。
- CPU、内存、磁盘和虚拟化能力足以运行本地节点。
先分清镜像、容器与虚拟机
Docker 不是虚拟机管理器,容器也不是一台缩小的虚拟机。三者的边界如下:
| 概念 | 它是什么 | 本课中的例子 |
|---|---|---|
| 镜像 Image | 只读模板,包含程序和运行所需文件 | hello-world 镜像 |
| 容器 Container | 镜像启动后的运行实例,本质上仍是受隔离和限制的进程 | docker run 启动的测试容器 |
| 虚拟机 VM | 拥有独立客户操作系统的虚拟计算机 | macOS/Windows 上 Docker Desktop 使用的 Linux 运行环境 |
| kind 节点 | 用容器模拟的一台 Kubernetes 节点 | control-plane 或 worker 节点容器 |
在 Linux 上,Docker Engine 可以直接使用内核提供的 Namespace 和 cgroup 隔离进程。macOS 与 Windows 不能直接运行 Linux 容器,因此 Docker Desktop 会先准备一个轻量 Linux 环境,再在其中运行 Docker Engine。后续命令虽然一致,底层路径并不完全相同。
选看视频:Docker 概述与核心概念
看完后回答
- 镜像与容器分别对应“模板”还是“运行实例”?
- 为什么删除一个容器不会自动删除它使用的镜像?
docker run至少需要经过哪些环节才能看到程序输出?
kind 解决的不是“安装 Docker”
kind 的全称是 Kubernetes IN Docker。它不会替代 Docker,而是调用 Docker 创建一个或多个节点容器,再在这些节点中启动 Kubernetes 组件。它适合在个人电脑上反复创建、删除和重建实验环境。
这里存在三层容易混淆的运行关系:
Docker 负责运行 kind 节点容器;节点内部的容器运行时再负责运行 Pod 中的业务容器。因此,“kind 节点容器”和“Pod 业务容器”不在同一层。
| 对比维度 | kind 本地模拟 | 生产集群 |
|---|---|---|
| 运行位置 | 一台个人电脑中的容器 | 多台服务器或云主机 |
| 创建与重建 | 分钟级,可频繁重建 | 需要网络、证书、高可用和变更计划 |
| 主要用途 | 学习、测试和可重复实验 | 承载真实业务 |
| 数据边界 | 受本机和节点容器生命周期影响 | 依赖生产级存储、备份与容灾 |
使用边界
kind 可以模拟 Kubernetes 的控制与工作负载机制,但不能代替生产环境。不要把本机端口映射、节点容器存储或单控制平面结果直接当作生产方案。
观察下面的架构动画,辨认宿主机、节点容器与 Kubernetes 组件之间的边界。
Kubernetes 集群架构与 kind 模拟方式
观察 kind 如何在 Docker 容器中构建一套完整的 Kubernetes 集群
1 / 6
你的电脑(Docker 宿主机)
步骤 1:Docker 宿主机
Docker Engine 运行在你的电脑上,提供容器运行时。kind 将在 Docker 中创建"节点容器"来模拟 Kubernetes 节点。
1.2 预检:用检查结果判断资源档位
标准实验集群使用 1 个控制平面节点和 2 个工作节点;资源接近最低要求时,可以改用 1 个控制平面节点和 1 个工作节点。
先执行与你当前系统对应的命令。
macOS
# CPU 逻辑核心数
sysctl -n hw.ncpu
# 物理内存,换算为 GB
sysctl -n hw.memsize | awk '{printf "%.0f GB\n", $1/1024/1024/1024}'
# 根分区可用磁盘
df -h /
# Apple Hypervisor Framework:1 表示可用
sysctl -n kern.hv_supportWindows
# CPU 逻辑核心数
(Get-CimInstance Win32_ComputerSystem).NumberOfLogicalProcessors
# 物理内存,换算为 GB
[math]::Round(
(Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory / 1GB,
1
)
# C 盘可用磁盘,换算为 GB
[math]::Round((Get-PSDrive C).Free / 1GB, 1)
# 查看系统与虚拟化要求
systeminfoLinux
# CPU 逻辑核心数
nproc
# 内存
free -h
# 根分区可用磁盘
df -h /
# KVM 设备存在且可读写时,输出 kvm-ready
test -r /dev/kvm -a -w /dev/kvm && echo kvm-ready || echo check-kvm把命令结果填入下面的问题,点击按钮得到资源档位建议。这里的答案只用于当前页面判断,不作为最终提交内容。
根据刚才的命令输出作答
填写实际数值,不需要估算或填写推荐值。
不要忽略资源不足
Docker 被系统强制回收、磁盘写满或虚拟化不可用时,后续现象可能表现为节点失联、镜像拉取失败或 Pod 随机重启。反复删除集群不能解决这些根因。
提前排除常用端口冲突
后续实验可能把节点端口映射到本机。下面的通用检查命令可以保留到后续课次使用;当前端口被占用并不影响本课工具安装。
macOS
lsof -nP -iTCP:80 -sTCP:LISTEN
lsof -nP -iTCP:443 -sTCP:LISTENWindows
Get-NetTCPConnection -State Listen |
Where-Object LocalPort -In 80, 443 |
Select-Object LocalAddress, LocalPort, OwningProcessLinux
ss -lntp '( sport = :80 or sport = :443 )'没有输出表示对应端口当前没有监听进程;有输出时先确认进程用途,不要直接结束未知进程。
1.3 实施:按当前系统准备 Docker
统一实验环境已经预装 Docker Desktop。若 docker info 能正常返回服务端信息,可以直接进入下一节;若命令不存在或 Docker Engine 没有启动,再参考对应系统的安装方式。
macOS 和 Windows 使用完整产品 Docker Desktop,Linux 可以安装 Docker Engine。
Docker Client 与 Docker Engine
在终端输入的 docker 是客户端。它把请求发送给 Docker daemon,再由 daemon 管理镜像、网络、存储和容器。
这也解释了两种常见现象:
docker --version成功,只能证明客户端命令存在。docker info同时返回 Client 与 Server 信息,才能证明客户端已经连接到 Docker Engine。
macOS
使用 Homebrew 安装:
brew install --cask docker也可以从 Docker 官网下载安装包。安装后启动 Docker Desktop,等待 Docker Engine 进入运行状态。
docker info
docker versionWindows
使用 WinGet 安装:
winget install --id Docker.DockerDesktop安装后启动 Docker Desktop,并确认 WSL 2 后端可以正常工作。
wsl --version
docker info
docker versionLinux
以下命令适用于 Ubuntu;其他发行版应使用 Docker 官方对应发行版的安装说明。
sudo apt update
sudo apt install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
-o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
. /etc/os-release
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu ${UBUNTU_CODENAME:-$VERSION_CODENAME} stable" |
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"退出当前登录会话并重新登录,再执行:
docker info
docker versionDocker 权限边界
Linux 的 docker 组可以控制 Docker daemon,通常等同于获得主机高权限。只给确实需要操作 Docker 的账号授予该权限。
仅看到 Docker 图标不能证明容器运行能力。Docker 官方提供了名为 hello-world 的最小测试镜像,用它可以同时检查镜像拉取和容器启动链路。阅读 docker info 输出后,回答问题并完成验证。
看到 Hello from Docker! 表示 Docker 客户端、Docker Engine、镜像拉取与容器启动链路均可工作。
1.4 实施:安装 kind、kubectl 与 Helm
三个命令行工具都保留 macOS、Windows 与 Linux 的通用安装方式。包管理器默认安装当前可用版本,本课不要求指定或冻结版本。
三个命令都不是 Kubernetes 集群
| 工具 | 主要输入 | 主要输出 | 是否负责长期运行工作负载 |
|---|---|---|---|
| kind | 节点数量、角色和端口等集群配置 | 一套本地节点容器与 kubeconfig | 否,负责创建和删除本地集群 |
| kubectl | 命令、资源名称或 YAML | Kubernetes API 的查询或变更结果 | 否,它是 API 客户端 |
| Helm | Chart、values 和 release 操作 | 渲染后的 Kubernetes 资源与 release 记录 | 否,它通过 Kubernetes API 交付资源 |
kubectl 连接集群时会读取 kubeconfig。kubeconfig 主要回答三个问题:
- cluster:API Server 在哪里,以及如何验证它的证书。
- user:用什么凭据发起请求。
- context:当前把哪个 user 与哪个 cluster 组合起来,并默认使用哪个 namespace。
当前还没有创建集群,所以本课只能验证 kubectl 客户端。下一课由 kind 生成 kubeconfig 后,kubectl 才能真正向 API Server 发起请求。
macOS
brew install kind kubectl helmWindows
winget install --id Kubernetes.kind
winget install --id Kubernetes.kubectl
winget install --id Helm.HelmLinux
安装 kind:
KIND_ARCH="$(uname -m)"
case "$KIND_ARCH" in
x86_64) KIND_ARCH=amd64 ;;
aarch64|arm64) KIND_ARCH=arm64 ;;
*) echo "Unsupported architecture: $KIND_ARCH"; exit 1 ;;
esac
curl -Lo kind "https://github.com/kubernetes-sigs/kind/releases/latest/download/kind-linux-${KIND_ARCH}"
chmod +x kind
sudo mv kind /usr/local/bin/kind安装 kubectl:
KUBECTL_ARCH="$(uname -m)"
case "$KUBECTL_ARCH" in
x86_64) KUBECTL_ARCH=amd64 ;;
aarch64|arm64) KUBECTL_ARCH=arm64 ;;
*) echo "Unsupported architecture: $KUBECTL_ARCH"; exit 1 ;;
esac
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/${KUBECTL_ARCH}/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl安装 Helm:
curl -fsSL -o get_helm.sh \
https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
less get_helm.sh
chmod 700 get_helm.sh
./get_helm.shkind 用 Docker 容器模拟 Kubernetes 节点;kubectl 通过 kubeconfig 连接 Kubernetes API;Helm 用 Chart 组织复杂应用。当前还没有创建集群,因此 kubectl cluster-info 连接失败是正常现象。
观察动画,理解 kind 创建集群时 Docker、kubeadm、CNI 和 kubeconfig 各自出现在哪一步。
kind 创建集群全过程
左侧显示 Docker 中发生了什么,右侧显示对应的 Kubernetes 视角
1 / 7
Docker 视角
Kubernetes 视角
暂无集群
步骤 1:初始状态
Docker Engine 已经运行。此时还没有任何 kind 集群,Docker 中只有基础镜像。kubectl 没有可连接的集群。
关键关系
每个 kind 节点都是一个 Docker 容器。下一课会把节点数量、角色和端口映射写入 kind-config.yaml,再由 kind 创建本地集群。
Helm 中的 Chart、values 与 release
Helm 常被称为 Kubernetes 的包管理器,但它管理的不是普通操作系统软件包:
- Chart 是一组 Kubernetes 模板和元数据。
- values 为模板提供可替换参数。
- release 是某个 Chart 使用一组 values 安装到集群后的实例记录。
同一个 Chart 可以用不同 values 创建不同 release。Helm 最终仍然通过 Kubernetes API 创建或更新资源,因此安装 Helm 客户端并不代表集群中已经安装了应用。
选看视频:Helm 的基本定位(第 34 分 P)
看完后回答
- Chart、values 与 release 分别对应模板、参数还是安装实例?
- Helm 为什么仍然需要 kubeconfig?
helm version成功能否证明集群中已经存在 release?
1.5 验证:确认四个工具都能使用
不要通过桌面图标或安装器的“完成”页面判断结果。终端命令能直接证明 Docker Engine 是否可连接,以及三个客户端是否进入 PATH。
阅读前文中 kubectl 客户端与集群的关系,回答问题后运行整组验收命令。kubectl version 默认还会尝试联系集群;尚未创建集群时,应加上 --client 参数,只检查本地客户端。
通过标准:
| 检查项 | 通过现象 | 不通过时先检查 |
|---|---|---|
| Docker | docker info 同时显示 Client 与 Server 信息 | Docker Desktop 或 daemon 是否运行 |
| kind | kind version 返回版本信息 | 安装位置是否在 PATH |
| kubectl | kubectl version --client 返回客户端信息 | 命令名、PATH 与安装是否完成 |
| Helm | helm version 返回版本信息 | PATH 是否刷新 |
1.6 交付:只提交两张截图
本课不要求资源表、版本冻结表、安装报告、命令日志或故障工单。只保留以下两张截图:
- Docker 容器验证截图:终端中同时包含执行的
docker run --rm hello-world命令和Hello from Docker!成功信息。 - 工具链验证截图:同一终端画面中包含
kind version、kubectl version --client、helm version三条命令及其成功输出。
截图需要包含完整命令和关键结果,不需要截取桌面、个人目录、账号信息、代理地址或其他无关区域。
1.7 排错:从报错类型开始定位
| 现象 | 优先检查 | 常见原因 | 最小修复方向 |
|---|---|---|---|
docker info 无法连接 | Docker Desktop/daemon 状态 | 服务未启动 | 启动服务后重新检查 |
| Linux 报 Docker socket 权限错误 | id、ls -l /var/run/docker.sock | 组权限尚未生效 | 确认授权范围并重新登录 |
| 命令不存在 | command -v 或 Get-Command | PATH 未刷新或安装失败 | 确认安装位置并重开终端 |
| 下载超时 | DNS、代理与下载站连通性 | 网络或代理配置异常 | 先定位网络层,再配置代理 |
| 端口已监听 | 监听进程与用途 | 本机服务占用 | 后续映射时换端口,或确认影响后再停止服务 |
| 资源低于最低要求 | 资源预检答案 | 配置或后台负载不足 | 使用低配档;仍不满足时先释放或扩充资源 |
挑战任务:编写只读环境检查脚本
脚本可以汇总 CPU、内存、磁盘、虚拟化、工具版本和端口监听状态,但不得自动结束进程、修改系统设置或安装软件。输出应清楚区分“通过、警告、失败”;挑战任务不增加提交物。
本章小测
本章小结
完成本课后,你应能够:
- 用自己的话说明 Kubernetes 是什么,以及它为什么采用期望状态和持续控制循环。
- 判断多副本、自动恢复、统一发布等需求何时值得引入 Kubernetes,并说明它增加的复杂度。
- 说明 Docker、kind、kubectl 与 Helm 的依赖关系。
- 根据当前系统检查 CPU、内存、磁盘和虚拟化能力。
- 在预装环境中直接验证 Docker,也能在其他环境中找到对应安装路径。
- 使用
hello-world验证完整容器运行链路。 - 在尚未创建集群时使用
kubectl version --client检查客户端。 - 用两张终端截图证明工具链已经可用。
下一课将编写 kind-config.yaml,创建一套可删除、可重建的本地多节点模拟集群。
