一、什么是 K8s?
Kubernetes(简称 K8s) 是一个开源的容器编排平台,最初由 Google 设计并捐赠给 Cloud Native Computing Foundation(CNCF)管理。它用于自动化容器化应用的部署、扩缩容和管理。
K8s 的核心能力:
- 服务发现与负载均衡:自动为容器分配 IP 和 DNS 名,并分发流量
- 自动修复:容器挂了自动重启,节点挂了自动迁移 Pod
- 自动扩缩容:根据 CPU/内存使用率自动调整容器数量
- 存储编排:自动挂载本地或云存储
- 滚动更新与回滚:逐个替换容器实例,更新失败自动回退
二、有了 Docker,为什么还要用 K8s?
Docker 和 K8s 解决的是不同层面问题,两者互补:
| 需求 | Docker | K8s |
|---|---|---|
| 单个容器的构建和运行 | ✅ 原生支持 | ❌ 不负责构建 |
| 多个容器的编排调度 | ❌ 需手动管理 | ✅ 声明式自动管理 |
| 容器崩溃后自动恢复 | ❌ 不复原 | ✅ 自动重启 Pod |
| 流量波动时自动扩容 | ❌ 手动操作 | ✅ 支持 Horizontal Pod Autoscaler |
| 发布新版本无停机 | ❌ 需手动编排 | ✅ 支持 Rolling Update |
| 跨机器的集群管理 | ❌ 单机为主 | ✅ 天然支持集群 |
在实际项目中,通常用 Docker 构建镜像,用 K8s 运行和管理容器,两者配合使用。Docker Desktop 内置了 K8s,开发者可以在本地一键启动一个单节点 K8s 集群进行开发和测试。
三、环境说明
本文的环境如下:
宿主机:Windows 11
WSL 2:Ubuntu 22.04
Docker Desktop:已安装,启用 WSL 2 后端
⚠️ 如果你用的是真实的 Linux 系统或传统虚拟机(如 VMware、VirtualBox),操作步骤会有所不同。本文基于 WSL + Docker Desktop 的组合。
四、在 Docker Desktop 中启用 K8s
4.1 确认 Docker Desktop 正常运行
在 PowerShell 中执行:
docker version
确认 Docker Engine 和 Client 都有版本信息输出。
4.2 启用 Kubernetes
- 打开 Docker Desktop
- 点击左侧导航栏的 Kubernetes 图标(☸️)
- 点击 "Create cluster" 按钮
- 配置集群参数:
- Provisioning method:选择
kubeadm或kind(详见下方对比) - Kubernetes version:选择当前最新稳定版(如 v1.35)
- Nodes:1(单节点已涵盖运行应用所需的所有组件)
- Provisioning method:选择
- 点击 Create,等待 1~2 分钟创建完成
两种模式的对比如下:
| 特性 | kubeadm 模式 | kind 模式 |
|---|---|---|
| 节点名 | docker-desktop |
desktop-control-plane |
| API Server 地址 | kubernetes.docker.internal:6443(固定) |
127.0.0.1:XXXXX(随机端口,重启会变) |
| Docker Desktop 普通重启(Restart)后数据 | 保留 ✅ | 保留 ✅ |
| K8s 界面点 Stop 后数据 | 保留 ✅ | 丢失 ❌(有明确提示) |
| 最大节点数 | 单节点 | 支持多节点 |
| 适用场景 | 日常开发、数据持久化 | 多节点调度、学习 Pod 调度原理 |
⚠️ 重要提醒:两种模式各有优劣,根据需求选择:
kubeadm模式:重启或 Stop 后数据均保留,API 地址固定。WSL 中可通过kubernetes.docker.internal:6443固定地址访问,推荐日常开发使用kind模式:区分两种操作——点击 Docker Desktop 的 Restart 按钮不会释放资源;但在 K8s 界面点击 Stop 会清除所有运行中的资源(Docker Desktop 会提示 "Stopping the Kubernetes cluster removes all running resources.")。此外,API Server 端口每次创建都是随机的,导致 WSL 子系统中的 kubectl 无法自动感知新地址。支持多节点(1 control-plane + N worker),适合学习 Pod 调度原理

创建完成后,Docker Desktop 的 Kubernetes 视图中可以看到集群的运行状态:

五、Node(节点)的概念
Node(节点) 是 K8s 集群中的工作机器,可以是物理机或虚拟机,负责运行容器化应用。
K8s 集群由两种类型的节点组成:
| 节点类型 | 职责 | 组件 |
|---|---|---|
| Control Plane(控制面) | 管理整个集群,做出全局决策 | API Server、Scheduler、Controller Manager、etcd |
| Worker Node(工作节点) | 实际运行应用容器 | kubelet、kube-proxy、容器运行时 |
在 Docker Desktop 的单节点模式下,control-plane 同时也具备 worker 的功能,可以直接调度 Pod。
通过以下命令查看集群中的节点:
kubectl get nodes
输出示例(kubeadm 模式):
NAME STATUS ROLES AGE VERSION
docker-desktop Ready control-plane 10m v1.34.1
STATUS为 Ready 表示节点正常运行ROLES为 control-plane 表示它是管理节点VERSION显示 K8s 版本号
六、配置 kubectl(关键步骤)
6.1 什么是 kubectl?
kubectl 是 K8s 的命令行客户端工具,通过调用 K8s API Server 来管理集群资源(节点、Pod、Service 等)。所有对集群的操作几乎都可以通过 kubectl 完成。
6.2 问题本质:kubeconfig 与环境隔离
kubectl 通过读取 kubeconfig 配置文件(默认位置 ~/.kube/config)来连接集群。Docker Desktop 启用 K8s 后,会在 Windows 侧自动生成这个配置:
Windows 路径:C:\Users\<用户名>\.kube\config ✅ 自动生成,开箱即用
WSL 路径:/root/.kube/config ❌ 不存在,需手动处理
所以关键点就一个:kubectl 在哪运行,就得让对应的 .kube/config 里有正确的集群信息。
6.3 推荐方案:在 Windows 中使用 kubectl(零配置 ⭐)
Docker Desktop 启动 K8s 后,Windows 上的 kubectl 已经可以直接使用,完全不需要任何配置。
第一步:打开 PowerShell 或 CMD
Windows 自带的 PowerShell 或命令提示符即可,无需管理员权限。
第二步:运行 kubectl 命令验证
kubectl get nodes

如果提示 kubectl 不是系统命令,说明还没安装 kubectl。有两种安装方式:
方式 A:通过 Docker Desktop 自带版本
# Docker Desktop 自带 kubectl,在 Docker 资源目录下
& "C:\Program Files\Docker\Docker\resources\kubectl.exe" get nodes
方式 B:单独安装 kubectl(推荐)
从 Kubernetes 官方下载:
# 下载最新稳定版 kubectl
curl.exe -LO "https://dl.k8s.io/release/v1.35.0/bin/windows/amd64/kubectl.exe"
将 kubectl.exe 所在目录添加到系统 PATH,或直接放到 C:\Windows\System32\ 目录下。
验证安装:
kubectl version --client
💡 为什么 Windows 上能直接用?
Docker Desktop 在启动 K8s 集群后,会自动将连接的 kubeconfig 写入
C:\Users\<用户名>\.kube\config,并且 API Server 地址kubernetes.docker.internal:6443在 Windows 网络中是可达的。整个过程完全自动化,用户无需干预。
6.4 备选方案:在 WSL 中使用 kubectl
如果你习惯在 WSL Ubuntu 终端中操作,可以在 WSL 中配置 kubectl。相比 Windows 方案,需要额外两步:打通网络 + 同步配置。
步骤一:打通网络(永久方案)
WSL 2 默认使用 NAT 网络模式,无法直接访问 Windows 上的 localhost 服务。编辑 Windows 上的 .wslconfig 文件(路径:C:\Users\<你的用户名>\.wslconfig),写入:
[wsl2]
networkingMode=mirrored
networkingMode=mirrored(镜像网络模式)让 WSL 2 与 Windows 共享网络命名空间,WSL 中的 127.0.0.1 将直接指向 Windows 宿主机。
使配置生效:
# PowerShell 中执行
wsl --shutdown
重新打开 WSL Ubuntu 即可。
步骤二:同步 kubeconfig
在 WSL Ubuntu 中执行:
# 1. 确认 kubectl 是否已安装
kubectl version --client# 如果没有安装,则下载
curl -LO "https://dl.k8s.io/release/v1.35.0/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/# 2. 创建 .kube 目录(如果不存在)
mkdir -p ~/.kube# 3. 复制 Windows 的 K8s 配置到 WSL
cp /mnt/c/Users/<你的Windows用户名>/.kube/config ~/.kube/config
如果 WSL 使用 root 用户登录,则路径为
/root/.kube/config;如果使用普通用户,则为/home/<用户名>/.kube/config。
为什么需要同步配置?
Windows 和 WSL 是两套独立的文件系统,各自的 ~/.kube/config 互不相干。Docker Desktop 只自动维护 Windows 侧的配置,WSL 侧需要手动复制。如果是 kind 模式,由于 API Server 端口每次随机,WSL 中的旧配置还需要重新同步才能继续使用。
6.5 验证连接
kubectl get nodes
成功输出:
NAME STATUS ROLES AGE VERSION
docker-desktop Ready control-plane 10m v1.34.1

七、部署第一个应用
环境配置完成,接下来部署一个 Nginx Web 服务器,验证集群能正常工作。
7.1 创建 Deployment
Deployment 是 K8s 中最常用的资源类型,用于声明式地管理 Pod:
kubectl create deployment k8s-test --image=nginx
k8s-test:Deployment 的名称--image=nginx:使用的容器镜像(从 Docker Hub 拉取)
K8s 会自动拉取 Nginx 镜像,创建一个 Pod 并在节点上启动容器。
7.2 查看 Pod 状态
kubectl get pods
输出示例:
NAME READY STATUS RESTARTS AGE
k8s-test-66588d67cf-stvgs 1/1 Running 0 66s
READY 1/1:Pod 中 1 个容器,1 个就绪STATUS Running:正常运行RESTARTS 0:未发生重启
如果状态为 ContainerCreating 或 Pending,等待几秒再次检查即可。
7.3 查看完整资源状态
kubectl get pods,svc
svc 是 Service 的缩写,Service 为 Pod 提供一个稳定的入口地址。刚创建时只有默认的 kubernetes 服务。
7.4 访问 Nginx:方式一(端口转发)
因为 Pod 运行在 K8s 集群内部网络,不能直接从宿主机访问。使用 port-forward 将本地端口映射到 Pod 端口:
kubectl port-forward deployment/k8s-test 8080:80
这条命令将本地 8080 端口的流量转发到 k8s-test 的 80 端口。
保持终端窗口打开,在浏览器访问 http://localhost:8080,出现 Nginx 欢迎页面即部署成功:

port-forward适合快速调试,终端关闭后转发即停止。
7.5 访问 Nginx:方式二(LoadBalancer 服务)
上一节的 port-forward 是临时调试手段,终端关闭就失效。更接近生产环境的方式是为 Deployment 创建一个 Service,类型设为 LoadBalancer。
为什么需要 LoadBalancer?——理解 Docker Desktop 的网络隔离
K8s 集群运行在 Docker Desktop 的容器环境中,与 Windows 宿主机之间存在网络隔离:
- Pod 的 Cluster IP 是 Docker 内部网络的私有地址,宿主机无法直接访问
- NodePort 类型的 Service 在真实的 Linux 集群中可以通过
节点IP:NodePort直接访问。但 Docker Desktop 中的"节点"本身是 Docker 容器,Windows 宿主机无法直接到达容器内部,所以 NodePort 在这里行不通 - 简单说:Cluster IP 和 NodePort 都是 Docker 容器网络的内部地址,Windows 根本看不见它们
Docker Desktop 也考虑到了这个问题,所以它内置了 LoadBalancer 支持——当你创建 LoadBalancer 类型的 Service 时,Docker Desktop 会自动在宿主机上创建代理容器(如 docker-desktop-lb 或 kindccm-xxx,实质上是 Envoy 代理),直接在 Windows 宿主机上监听端口,并将收到的流量转发到 K8s 集群内部。相当于在 Windows 和 K8s 集群之间搭了一座桥。
这也是为什么在 Docker Desktop 上开发时,推荐用 LoadBalancer 而非 NodePort。
kubectl expose deployment k8s-test --type=LoadBalancer --port=8888 --target-port=80
--type=LoadBalancer:创建一个负载均衡器类型的 Service--port=8888:Service 对外暴露的端口号--target-port=80:转发到 Pod 内部的 80 端口(Nginx 默认端口)
查看 Service 状态:
kubectl get svc k8s-test
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
k8s-test LoadBalancer 10.108.248.16 localhost 8888:31812/TCP 30s
当 EXTERNAL-IP 显示为 localhost 时,直接在浏览器访问 http://localhost:8888 即可看到 Nginx 欢迎页。
工作原理:Docker Desktop 检测到 LoadBalancer 类型的 Service 后,会自动在宿主机上创建 Envoy 代理容器(kubeadm 模式下为
docker-desktop-lb,kind 模式下为kindccm-xxx),将宿主机的 8888 端口流量转发到集群内部的 Service。相比port-forward,这种方式是持久化的,终端关闭后服务依然可访问。可以在 Docker Desktop 的 Containers 视图中看到这些envoyproxy类型的代理容器。

排查技巧:端口冲突与代理容器清理
如果端口已被其他程序占用,代理容器会创建失败,表现为 EXTERNAL-IP 一直处于 <pending> 状态。
正确的操作顺序如下(顺序很重要):
# 1. 查找旧的代理容器
docker ps -a --filter "name=kindccm"# 2. 删除旧容器(Docker Desktop 会自动重建)
docker rm -f kindccm-LXUFEC6ZYEIUPGUBRWB556226BYGOZKZSQBDOQZS# 3. 修改 Service 端口(避开被占用的端口)
kubectl patch svc k8s-test --type='json' \-p='[{"op":"replace","path":"/spec/ports/0/port","value":8888}]'
⚠️ 关键顺序:先删除旧容器 → 再修改端口,这样 Docker Desktop 会自动创建新的代理容器。如果先改端口再删旧容器,新容器不会自动创建,需要重启 Docker Desktop。
7.6 查看 Pod 日志
kubectl logs k8s-test-66588d67cf-stvgs
可以看到 Nginx 的访问日志,便于调试。
7.7 清理测试资源
依次删除 Service 和 Deployment:
# 删除 Service(停止端口映射)
kubectl delete svc k8s-test# 删除 Deployment(终止并清除 Pod)
kubectl delete deployment k8s-test
先删 Service 再删 Deployment,确保流量先断开,再终止 Pod,避免资源竞争。
八、常用命令速查
| 命令 | 作用 |
|---|---|
kubectl get nodes |
查看所有节点 |
kubectl get pods |
查看当前命名空间的所有 Pod |
kubectl get pods -n kube-system |
查看 K8s 系统组件(CoreDNS、API Server 等) |
kubectl get svc |
查看所有 Service |
kubectl get all |
查看当前命名空间的所有资源 |
kubectl create deployment <名称> --image=<镜像> |
创建 Deployment |
kubectl expose deployment <名称> --type=LoadBalancer --port=对外端口 --target-port=容器端口 |
将 Deployment 暴露为 Service |
kubectl port-forward deployment/<名称> 本地端口:容器端口 |
将本地端口转发到 Pod |
kubectl delete deployment <名称> |
删除 Deployment |
kubectl delete svc <名称> |
删除 Service |
kubectl logs <Pod名称> |
查看 Pod 日志 |
kubectl describe pod <Pod名称> |
查看 Pod 详细信息(事件、状态等) |
kubectl get events |
查看集群事件(排错常用) |
九、总结
本文从零开始,在 Docker Desktop 上完成了 K8s 的启用、配置和部署验证:
| 步骤 | 操作 | 验证方式 |
|---|---|---|
| 启用 K8s | Docker Desktop → Kubernetes → Create cluster | 界面显示集群运行中 |
| 配置 kubectl(推荐) | 直接在 Windows PowerShell 中使用,零配置 | kubectl get nodes 返回节点信息 |
| 配置 kubectl(备选) | WSL 配置镜像网络 + 同步 kubeconfig | kubectl get nodes 返回节点信息 |
| 部署应用 | kubectl create deployment |
kubectl get pods 显示 Running |
| 访问验证(调试) | kubectl port-forward |
浏览器访问 localhost:8080 |
| 访问验证(持久化) | kubectl expose 创建 LoadBalancer Service |
浏览器访问 localhost:8888 |
以上步骤验证了 Docker Desktop 内置的 K8s 集群可以正常使用。基于这个环境,可以进一步学习:
- 编写 YAML 配置文件实现声明式管理
- 使用多节点 kind 集群
- 部署完整的 Web + 数据库应用
- 学习 ConfigMap、Secret、Ingress 等高级资源