文章目录
-
- 核心作用
- 整体架构
- 关键概念
- Kubernetes下载安装
-
- [步骤一:在 Docker Desktop 中启用 Kubernetes](#步骤一:在 Docker Desktop 中启用 Kubernetes)
- 步骤二:验证集群状态
- 使用案例
-
- 第一步:准备应用代码
- [第二步:创建 Deployment(管理 Pod 副本)](#第二步:创建 Deployment(管理 Pod 副本))
- [第三步:创建 Service(暴露内部访问)](#第三步:创建 Service(暴露内部访问))
- 第四步:核心能力体验
- 第五步:清理资源
- 常用命令速查表
Kubernetes(常简称为 K8s )是一个开源的 容器编排平台 ,用于自动部署、扩展和管理容器化应用程序。
核心作用
服务发现与负载均衡 :自动分配 IP,为容器组提供统一访问入口并分发流量。
存储编排 :可挂载多种存储系统(本地、云存储等)。
自动部署与回滚 :支持滚动更新,且能自动回滚到上一版本。
弹性伸缩 :根据 CPU/内存或自定义指标自动扩缩应用实例数。
自我修复 :重启失败容器、替换不响应健康检查的节点、阻止未就绪的容器接收流量。
密钥与配置管理:管理敏感信息(密码、令牌、证书)和应用配置。
-
启用 Kubernetes 前后的核心区别
维度 未启用 K8s 已启用 K8s 容器管理 管理单个容器 管理 Pod(一组容器) 扩容能力 手动启动多个容器 kubectl scale 一键扩容 负载均衡 手动配置反向代理 Service 自动负载均衡 服务发现 手动记录 IP:端口 DNS 自动服务发现 自愈能力 ❌ 容器挂了需要手动重启 ✅ 自动重启、重建 Pod 滚动更新 手动逐个替换容器 kubectl rollout 零停机更新 配置管理 环境变量或挂载文件 ConfigMap + Secret
整体架构
#mermaid-svg-ugkuR3MAbVU6Gdbh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ugkuR3MAbVU6Gdbh .error-icon{fill:#552222;}#mermaid-svg-ugkuR3MAbVU6Gdbh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ugkuR3MAbVU6Gdbh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .marker.cross{stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ugkuR3MAbVU6Gdbh p{margin:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label text{fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label span{color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster-label span p{background-color:transparent;}#mermaid-svg-ugkuR3MAbVU6Gdbh .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh span{fill:#333;color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node rect,#mermaid-svg-ugkuR3MAbVU6Gdbh .node circle,#mermaid-svg-ugkuR3MAbVU6Gdbh .node ellipse,#mermaid-svg-ugkuR3MAbVU6Gdbh .node polygon,#mermaid-svg-ugkuR3MAbVU6Gdbh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .rough-node .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label text,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label{text-anchor:middle;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .rough-node .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label,#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label{text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node.clickable{cursor:pointer;}#mermaid-svg-ugkuR3MAbVU6Gdbh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .arrowheadPath{fill:#333333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster text{fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh .cluster span{color:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ugkuR3MAbVU6Gdbh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ugkuR3MAbVU6Gdbh rect.text{fill:none;stroke-width:0;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape p,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ugkuR3MAbVU6Gdbh .icon-shape .label rect,#mermaid-svg-ugkuR3MAbVU6Gdbh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ugkuR3MAbVU6Gdbh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ugkuR3MAbVU6Gdbh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ugkuR3MAbVU6Gdbh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 🌐 外部
🖥️ 工作节点 2
🖥️ 工作节点 1
🎛️ 控制平面 (Control Plane)
kube-apiserver
📡 集群入口
kube-scheduler
📅 调度器
kube-controller-manager
🎮 控制器管理器
etcd
💾 分布式存储
kubelet
kube-proxy
Pod A
Pod B
kubelet
kube-proxy
Pod C
Pod D
👤 用户
kubectl
命令行工具
- 控制平面(Master):
kube-apiserver:所有操作的唯一入口。etcd:键值存储:存储集群所有配置和状态。kube-scheduler:决定 Pod 运行在哪个 Node 上。kube-controller-manager:维持集群的期望状态,运行各种控制器(节点控制器、副本控制器等)。
- 工作节点(Worker):
kubelet:管理节点上的 Pod。kube-proxy:维护网络规则,实现 Service 负载均衡。- 容器运行时(如 containerd、CRI‑O、Docker)。
关键概念
| 概念 | 说明 |
|---|---|
| Pod | K8s最小部署单元,包含一个或多个容器(通常是一个主容器 + 辅助容器)。 |
| Node | 工作节点(物理机或虚拟机),上面运行 Pod。 |
| Deployment | 管理无状态应用的 Pod 副本、滚动更新、回滚。 |
| Service | 为一组 Pod 提供稳定的网络访问入口(ClusterIP、NodePort、LoadBalancer)。 |
| Ingress | HTTP/HTTPS 路由规则,将外部请求映射到 Service。 |
| ConfigMap / Secret | 分别存储配置信息和敏感数据。 |
| Namespace | 虚拟集群,用于隔离资源(如开发、测试、生产环境)。 |
Kubernetes下载安装
步骤一:在 Docker Desktop 中启用 Kubernetes
- 启动并配置 Docker Desktop :打开 Docker Desktop ,点击右上角的 设置 (齿轮图标)进入
Settings。 - 开启 K8s 开关 :在左侧菜单中找到并点击
Kubernetes,然后勾选Enable Kubernetes这个选项,下方会出现Cluster settings (集群设置),本地测试选择单节点的Kubeadm就可以。 - 等待并确认 :点击右下角的
Apply按钮。之后 Docker Desktop 会自动重启并开始拉取和启动 Kubernetes 的必要组件。这个过程需要一点时间,请耐心等待。当 Docker Desktop 界面左下角出现 "Kubernetes is running" 的提示时,就说明启动成功了。

注意:若出现Failed to start pulling images,这说明 Docker Desktop 在尝试拉取 Kubernetes 所需的镜像时失败了,原因通常是网络问题导致无法访问 registry.k8s.io。通过配置国内镜像加速器解决:-
打开 Docker Desktop → 右上角 Settings(齿轮图标)→ 左侧选择 Docker Engine
-
在 JSON 配置中添加 registry-mirrors,内容如下:
json"registry-mirrors": [ "https://docker.1ms.run", "https://docker.xuanyuan.me", "https://mirrors.aliyun.com/docker-ce/", "https://mirror.ccs.tencentyun.com", "https://hub-mirror.c.163.com", "https://docker.mirrors.ustc.edu.cn" ] -
点击右下角 Apply,等待 Docker 重启
-
重启后,回到 Settings → Kubernetes,点击 Reset cluster 按钮重置集群
-
再次确保选中
Kubeadm,然后点击 Apply,让 Docker 重新拉取镜像
-
步骤二:验证集群状态
K8s 启用后,可以打开 PowerShell 或命令提示符,用 kubectl 命令来验证一下。
首先,确保 kubectl 正指向 Docker Desktop 的集群:
bash
kubectl config use-context docker-desktop
然后,查看集群中的节点状态:
bash
kubectl get nodes
果看到 NAME 为 docker-desktop,STATUS 为 Ready,就说明一切正常。

使用案例
部署一个 Python Web 应用,并通过浏览器访问它。完整项目结构,创建一个新目录,比如 my-k8s-demo,然后创建以下文件:
text
my-k8s-demo\ (项目根目录)
├── app.py
├── deployment.yaml
├── Dockerfile
└── service.yaml
第一步:准备应用代码
创建 my-k8s-demo 文件夹,新建一个 app.py:
python
from flask import Flask
import socket
import os
app = Flask(__name__)
@app.route('/')
def hello():
hostname = socket.gethostname()
return f"Hello from Kubernetes! Pod: {hostname}"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)
创建 Dockerfile:
text
FROM python:3.9-slim
WORKDIR /app
COPY app.py .
RUN pip install flask
EXPOSE 5000
CMD ["python", "app.py"]
构建镜像:
bash
docker build -t my-k8s-demo:latest .
第二步:创建 Deployment(管理 Pod 副本)
创建一个文件 deployment.yaml:
yaml
# ---------- 第一部分:API 版本和资源类型 ----------
apiVersion: apps/v1 # API 版本号,apps/v1 是 Deployment 的稳定版本
kind: Deployment # 资源类型,告诉 K8s 这是一个 Deployment
# ---------- 第二部分:元数据(标识信息) ----------
metadata:
name: my-demo-app # Deployment 的名称,后续操作会用到
# ---------- 第三部分:规格说明(核心配置) ----------
spec:
# 3.1 副本管理
replicas: 3 # 期望保持运行 3 个 Pod 副本,少了会自动补
# 3.2 标签选择器(Deployment 通过它找到自己管理的 Pod)
selector:
matchLabels: # 匹配带有以下标签的 Pod
app: my-demo-app # 标签键值对:app=my-demo-app
# 3.3 Pod 模板(定义每个 Pod 的"模样")
template:
# Pod 的元数据
metadata:
labels: # Pod 的标签,必须和上面的 selector 一致
app: my-demo-app # 这样 Deployment 才能找到并管理这个 Pod
# Pod 的规格(里面运行什么容器)
spec:
containers: # 容器列表(一个 Pod 可以有多个容器)
- name: app # 容器名称,在 Pod 内唯一
image: my-k8s-demo:latest # 使用的 Docker 镜像及版本
imagePullPolicy: Never # 添加这一行,告诉 K8s 不要从远程拉取,只用本地镜像
ports: # 容器暴露的端口(仅作文档说明)
- containerPort: 5000 # 容器内应用监听的端口
# 可选:资源限制
# resources:
# requests:
# memory: "64Mi"
# cpu: "250m"
# limits:
# memory: "128Mi"
# cpu: "500m"
应用配置:
bash
# 创建 Deployment
kubectl apply -f deployment.yaml
YAML 核心字段速记:
yaml
# Deployment 核心
apiVersion: apps/v1 # 版本
kind: Deployment # 类型
metadata.name: xxx # 名字
spec.replicas: 3 # 副本数
spec.selector # 找 Pod 的标签
spec.template # Pod 模板
spec.containers # 容器定义
imagePullPolicy # 镜像拉取策略
第三步:创建 Service(暴露内部访问)
创建一个文件 service.yaml:
yaml
# ---------- 第一部分:API 版本和资源类型 ----------
apiVersion: v1 # Service 使用核心 API v1 版本
kind: Service # 资源类型,告诉 K8s 这是一个 Service
# ---------- 第二部分:元数据(标识信息) ----------
metadata:
name: my-demo-service # Service 的名称,集群内部 DNS 会用到
# ---------- 第三部分:规格说明(核心配置) ----------
spec:
# 3.1 Service 类型
type: NodePort # 服务类型:
# - ClusterIP(默认):仅集群内部访问
# - NodePort:节点上开放端口,外部可访问
# - LoadBalancer:云服务商负载均衡器
# 3.2 标签选择器(Service 把流量转发给哪些 Pod)
selector:
app: my-demo-app # 只转发给带有 app=my-demo-app 标签的 Pod
# 必须和 Deployment 中 Pod 的标签一致
# 3.3 端口映射
ports:
- port: 5000 # Service 自己监听的端口(集群内部访问用)
targetPort: 5000 # 目标 Pod 容器实际监听的端口
nodePort: 30080 # 节点上开放的端口(仅 NodePort 类型需要)
# 范围:30000-32767,外部通过 localhost:30080 访问
# 可选:指定协议
# protocol: TCP # TCP(默认)、UDP
应用配置:
bash
kubectl apply -f service.yaml
现在可以通过浏览器访问:http://localhost:30080多刷新几次可以看到PodName会不断变化。
第四步:核心能力体验
首先新建一个终端,持续观察Pod变化:
bash
# 终端1:持续观察 Pod 变化
kubectl get pods -w
-
场景一:自愈能力(Self-Healing)
验证 Kubernetes 能在 Pod 故障时自动恢复:
bash# 手动删除一个 Pod,模拟 Pod 崩溃 kubectl delete pod <pod-name> # 替换成实际的 Pod 名称会发现,新的 Pod 自动创建了:

📝 核心理解
K8s 动作 :自动创建新 Pod 恢复到 3 个
用户无感:Service 自动将流量转发到新 Pod
-
场景二:水平伸缩(Horizontal Scaling)
体验 Kubernetes 根据负载快速调整应用实例数量。
bash# 1. 扩容到 5 个副本(应对流量高峰) kubectl scale deployment my-demo-app --replicas=5 # 2. 缩容到 2 个副本(流量下降时节省资源) kubectl scale deployment my-demo-app --replicas=2📝 核心理解
秒级扩缩容 :几秒钟内就能增加/减少应用实例
自动负载均衡 :Service 自动将流量分发到所有 Pod
资源优化:根据实际负载动态调整资源使用
-
场景三:滚动更新(Rolling Update)
体验零停机地更新应用版本。
-
准备一个新版本镜像
修改
app.py,改变返回信息:pythonfrom flask import Flask import socket import os app = Flask(__name__) @app.route('/') def hello(): hostname = socket.gethostname() return f"Hello from Kubernetes v2! Pod: {hostname} (Updated!)" # 修改这里 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)重新构建镜像并打上新标签:
bash# 构建新版本镜像 docker build -t my-k8s-demo:v2 . # 也可以同时保留 latest 标签 docker tag my-k8s-demo:v2 my-k8s-demo:latest -
执行滚动更新
bash# 方法1:直接设置新镜像(推荐) kubectl set image deployment/my-demo-app app=my-k8s-demo:v2 # 方法2:编辑 Deployment 配置 # kubectl edit deployment my-demo-app # 将 image: my-k8s-demo:latest 改为 image: my-k8s-demo:v2 -
观察滚动更新过程
bashkubectl rollout status deployment/my-demo-app -
模拟更新失败并回滚
bash# 故意设置一个不存在的镜像(模拟错误版本) kubectl set image deployment/my-demo-app app=my-k8s-demo:not-exist # 查看更新状态(会卡住) kubectl rollout status deployment/my-demo-app # 立即回滚到上一个稳定版本 kubectl rollout undo deployment/my-demo-app # 确认回滚成功 kubectl rollout status deployment/my-demo-app kubectl get pods
📝 核心理解
零停机 :新旧 Pod 交替替换,始终有可用的服务
可控速率 :可以控制每次替换多少个 Pod(maxSurge、maxUnavailable)
快速回滚 :一键回到上一个版本
健康检查:新 Pod 不健康时自动停止更新
-
第五步:清理资源
bash
# 删除 Service
kubectl delete service my-demo-service
# 删除 Deployment(会自动删除所有 Pods)
kubectl delete deployment my-demo-app
# 验证清理结果
kubectl get all
常用命令速查表
| 命令 | 说明 |
|---|---|
kubectl get nodes |
查看所有节点 |
kubectl get pods |
查看所有 Pods |
kubectl get service |
查看 Services(简称 svc) |
kubectl get deployments |
查看所有 Deployments |
kubectl get all |
查看当前命名空间所有常见资源 |
kubectl describe pod <pod-name> |
查看 Pod 的详细信息和事件 |
kubectl describe deployment <deployment-name> |
查看某个 Deployment 详细信息 |
kubectl describe svc <service-name> |
查看 Service 详细信息 |
kubectl logs <pod-name> |
查看 Pod的日志 |
ubectl apply -f <file.yaml> |
创建或更新资源(声明式) |
kubectl create -f <file.yaml> |
创建资源(命令式) |
kubectl delete -f <file.yaml> |
通过 YAML 文件删除资源 |
kubectl delete pod <pod-name> |
删除指定 Pod |
kubectl delete deployment <deploy-name> |
删除指定 Deployment |
kubectl delete svc <service-name> |
删除指定 Service |
kubectl delete pods --all |
删除当前命名空间所有 Pods |
kubectl scale deployment <name> --replicas=n |
手动扩容/缩容到指定副本数 |
kubectl set image deployment/<name> <container>=<image> |
滚动更新镜像版本 |
kubectl rollout status deployment/<name> |
查看滚动更新状态 |
kubectl rollout history deployment/<name> |
查看更新历史版本 |
kubectl rollout undo deployment/<name> |
回滚到上一个版本 |
kubectl rollout undo deployment/<name> --to-revision=2 |
回滚到指定版本 |
kubectl get pods -w |
实时监控 Pod 状态变化 |
kubectl logs -f <pod-name> |
实时跟踪日志 |