Kubernetes 容器编排入门教程
面向零基础用户 | 从概念到实战,一步步掌握 K8s 核心知识
目录
- 什么是 Kubernetes?
- Kubernetes 核心架构
- 环境搭建:安装 Minikube
- Pod:最小调度单元
- Deployment:声明式管理副本
- Service:服务发现与负载均衡
- Namespace:资源隔离
- ConfigMap 与 Secret:配置管理
- Ingress:七层流量入口
- PV 与 PVC:持久化存储
- HPA:水平自动伸缩
- 实战项目:部署微服务应用
- 常用命令速查表
- 学习路线建议
1. 什么是 Kubernetes?
Kubernetes(简称 K8s,因为 K 和 s 之间有 8 个字母)是 Google 开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。
为什么需要 Kubernetes?
假设你有一个 Web 应用,打包成了 Docker 镜像。手动部署一两个容器很简单,但当面临以下场景时,事情就变得复杂了:
- 应用需要 10 个副本来应对流量高峰
- 某个容器崩溃了,需要自动重启
- 需要滚动更新,不停机发布新版本
- 不同服务之间需要互相发现和通信
- 需要根据 CPU 使用率自动扩缩容
Kubernetes 就是为了解决这些问题而生的。你只需要声明期望状态(比如"我要 3 个副本"),K8s 会自动帮你实现并维持这个状态。
核心理念
| 理念 | 说明 |
|---|---|
| 声明式 API | 你告诉 K8s "我想要什么",而不是 "怎么做" |
| 自愈能力 | 容器挂了自动重启,节点挂了自动迁移 |
| 水平扩展 | 轻松增减副本数量 |
| 服务发现 | 内置 DNS,服务间自动寻址 |
| 滚动更新 | 零停机部署新版本 |
2. Kubernetes 核心架构
K8s 采用 主从架构(Master-Worker),由控制平面和工作节点组成。
2.1 控制平面(Control Plane)
控制平面是集群的大脑,负责全局决策和状态管理。
| 组件 | 职责 |
|---|---|
| kube-apiserver | 所有操作的统一入口,提供 RESTful API |
| etcd | 分布式键值存储,保存集群的所有状态数据 |
| kube-scheduler | 决定 Pod 应该调度到哪个节点 |
| kube-controller-manager | 运行各种控制器(如副本控制器、节点控制器) |
2.2 工作节点(Worker Node)
工作节点是实际运行容器的地方。
| 组件 | 职责 |
|---|---|
| kubelet | 确保 Pod 中的容器正常运行 |
| kube-proxy | 维护网络规则,实现 Service 的负载均衡 |
| 容器运行时 | 实际运行容器的引擎(如 containerd、Docker) |
2.3 架构图示
┌─────────────────── 控制平面 ───────────────────┐
│ │
│ ┌──────────────┐ ┌──────────────────────────┐ │
│ │ API Server │ │ Controller Manager │ │
│ └──────┬───────┘ └──────────────────────────┘ │
│ │ │
│ ┌──────┴───────┐ ┌──────────────────────────┐ │
│ │ etcd │ │ Scheduler │ │
│ └──────────────┘ └──────────────────────────┘ │
└─────────────────────────────────────────────────┘
│
┌─────────┼─────────┐
▼ ▼ ▼
┌────────┐┌────────┐┌────────┐
│ Node 1 ││ Node 2 ││ Node 3 │
│ kubelet││ kubelet││ kubelet│
│ proxy ││ proxy ││ proxy │
│ [Pods] ││ [Pods] ││ [Pods] │
└────────┘└────────┘└────────┘
3. 环境搭建:安装 Minikube
Minikube 是官方提供的本地单节点 K8s 环境,非常适合学习和开发。
3.1 前置条件
- 操作系统:Linux / macOS / Windows
- 内存:至少 2GB 可用
- CPU:至少 2 核
- 容器运行时:Docker(推荐)
3.2 安装步骤
Linux (amd64):
# 安装 Docker(如果尚未安装)
# 注意:以下为标准安装步骤,实际安装请参考 Docker 官方文档
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
# 重新登录终端以生效
# 安装 kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
# 安装 minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
macOS(使用 Homebrew):
brew install kubectl
brew install minikube
Windows(使用 Chocolatey):
choco install kubernetes-cli
choco install minikube
3.3 启动集群
# 使用 Docker 作为驱动启动
minikube start --driver=docker
# 查看状态
minikube status
# 验证 kubectl 能正常通信
kubectl cluster-info
kubectl get nodes
预期输出类似:
NAME STATUS ROLES AGE VERSION
minikube Ready control-plane 30s v1.28.3
3.4 启用常用插件
# 启用 Ingress 控制器
minikube addons enable ingress
# 启用 Metrics Server(HPA 需要)
minikube addons enable metrics-server
# 启用 Dashboard
minikube addons enable dashboard
# 查看所有插件
minikube addons list
4. Pod:最小调度单元
4.1 什么是 Pod?
Pod 是 K8s 中最小的可部署单元。一个 Pod 可以包含一个或多个紧密关联的容器,它们:
- 共享同一个网络命名空间(可以用 localhost 互访)
- 共享存储卷
- 总是被调度到同一个节点
大多数情况下,一个 Pod 只运行一个容器。多容器 Pod 用于 sidecar 模式(如日志收集、代理)。
4.2 创建 Pod
创建文件 pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: my-nginx
labels:
app: nginx
env: demo
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
cpu: "100m" # 0.1 核
memory: "128Mi"
limits:
cpu: "250m" # 0.25 核
memory: "256Mi"
部署并查看:
kubectl apply -f pod.yaml
kubectl get pods
kubectl describe pod my-nginx
kubectl logs my-nginx
kubectl exec -it my-nginx -- /bin/bash
4.3 多容器 Pod 示例(Sidecar 模式)
apiVersion: v1
kind: Pod
metadata:
name: sidecar-example
spec:
containers:
# 主容器:Web 应用
- name: web
image: nginx:1.25
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
# Sidecar 容器:日志收集器
- name: log-collector
image: busybox:1.36
command: ["sh", "-c", "tail -f /var/log/nginx/access.log"]
volumeMounts:
- name: shared-logs
mountPath: /var/log/nginx
volumes:
- name: shared-logs
emptyDir: {}
4.4 Pod 生命周期
Pod 有以下几种状态:
| 状态 | 说明 |
|---|---|
Pending |
已创建,但容器尚未全部就绪 |
Running |
所有容器已创建,至少一个正在运行 |
Succeeded |
所有容器正常终止 |
Failed |
至少一个容器异常退出 |
Unknown |
无法获取 Pod 状态 |
5. Deployment:声明式管理副本
5.1 为什么需要 Deployment?
直接创建 Pod 有一个问题:如果 Pod 挂了,没人会帮你重建。Deployment 提供了:
- 副本管理:确保指定数量的 Pod 始终运行
- 滚动更新:逐步替换旧版本 Pod
- 回滚能力:一键回退到之前的版本
- 自愈能力:Pod 挂了自动重建
5.2 创建 Deployment
创建文件 deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3 # 期望 3 个副本
selector:
matchLabels:
app: nginx # 选择标签为 app=nginx 的 Pod
strategy:
type: RollingUpdate # 滚动更新策略
rollingUpdate:
maxUnavailable: 1 # 更新时最多 1 个不可用
maxSurge: 1 # 更新时最多多出 1 个 Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
readinessProbe: # 就绪探针
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe: # 存活探针
httpGet:
path: /
port: 80
initialDelaySeconds: 15
periodSeconds: 20
部署操作:
kubectl apply -f deployment.yaml
# 查看 Deployment 状态
kubectl get deployments
kubectl rollout status deployment/nginx-deployment
# 查看 ReplicaSet(Deployment 自动创建)
kubectl get rs
# 查看 Pod
kubectl get pods -l app=nginx
5.3 滚动更新与回滚
# 更新镜像版本
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
# 观察滚动更新过程
kubectl rollout status deployment/nginx-deployment
# 查看更新历史
kubectl rollout history deployment/nginx-deployment
# 回滚到上一个版本
kubectl rollout undo deployment/nginx-deployment
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deployment --to-revision=2
5.4 扩缩容
# 手动扩容到 5 个副本
kubectl scale deployment/nginx-deployment --replicas=5
# 缩容到 2 个副本
kubectl scale deployment/nginx-deployment --replicas=2
6. Service:服务发现与负载均衡
6.1 为什么需要 Service?
Pod 的 IP 地址是临时的,重建后会变化。Service 为一组 Pod 提供:
- 稳定的访问入口(固定 ClusterIP 或 DNS 名称)
- 负载均衡:自动将流量分发到后端 Pod
- 服务发现:通过 DNS 名称访问
6.2 Service 类型
| 类型 | 说明 | 使用场景 |
|---|---|---|
ClusterIP |
仅集群内部可访问(默认) | 微服务间通信 |
NodePort |
在每个节点上开放一个端口 | 开发/测试环境 |
LoadBalancer |
创建外部负载均衡器 | 生产环境(云平台) |
ExternalName |
映射到外部 DNS 名称 | 访问外部服务 |
6.3 创建 ClusterIP Service
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: ClusterIP
selector:
app: nginx # 匹配标签为 app=nginx 的 Pod
ports:
- protocol: TCP
port: 80 # Service 端口
targetPort: 80 # Pod 端口
6.4 创建 NodePort Service
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080 # 节点端口范围:30000-32767
访问方式:
# Minikube 环境下获取访问地址
minikube service nginx-nodeport --url
# 或直接访问
curl $(minikube ip):30080
6.5 DNS 服务发现
K8s 内置 DNS,Service 创建后自动注册:
# 同命名空间内访问
http://<service-name>
# 跨命名空间访问
http://<service-name>.<namespace>.svc.cluster.local
# 示例:访问 default 命名空间下的 nginx-service
http://nginx-service.default.svc.cluster.local
7. Namespace:资源隔离
7.1 什么是 Namespace?
Namespace(命名空间)用于将集群资源逻辑隔离,适合:
- 多团队共享集群
- 区分开发、测试、生产环境
- 设置资源配额和权限
7.2 默认命名空间
| 命名空间 | 说明 |
|---|---|
default |
默认命名空间,未指定时使用 |
kube-system |
K8s 系统组件 |
kube-public |
公共资源 |
kube-node-lease |
节点心跳 |
7.3 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
env: dev
或使用命令:
kubectl create namespace development
7.4 在指定命名空间中部署资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
namespace: development # 指定命名空间
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: nginx:1.25
ports:
- containerPort: 80
7.5 资源配额
限制命名空间的资源使用:
apiVersion: v1
kind: ResourceQuota
metadata:
name: dev-quota
namespace: development
spec:
hard:
pods: "10" # 最多 10 个 Pod
requests.cpu: "4" # CPU 请求总和不超过 4 核
requests.memory: "8Gi" # 内存请求总和不超过 8GB
limits.cpu: "8" # CPU 限制总和不超过 8 核
limits.memory: "16Gi" # 内存限制总和不超过 16GB
8. ConfigMap 与 Secret:配置管理
8.1 ConfigMap:存储非敏感配置
ConfigMap 用于存储键值对配置数据,与 Pod 解耦。
创建 ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
# 键值对形式
APP_ENV: "production"
APP_DEBUG: "false"
LOG_LEVEL: "info"
# 文件形式
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
在 Pod 中使用 ConfigMap:
apiVersion: v1
kind: Pod
metadata:
name: config-demo
spec:
containers:
- name: app
image: nginx:1.25
# 方式一:作为环境变量
envFrom:
- configMapRef:
name: app-config
# 方式二:单独映射某个键
env:
- name: CUSTOM_ENV
valueFrom:
configMapKeyRef:
name: app-config
key: APP_ENV
# 方式三:挂载为文件
volumeMounts:
- name: config-volume
mountPath: /etc/nginx/conf.d
volumes:
- name: config-volume
configMap:
name: app-config
items:
- key: nginx.conf
path: default.conf
8.2 Secret:存储敏感数据
Secret 用于存储密码、Token、证书等敏感信息,数据以 Base64 编码存储。
创建 Secret:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
DB_HOST: bXlzcWwtaG9zdA== # echo -n 'mysql-host' | base64
DB_USER: cm9vdA== # echo -n 'root' | base64
DB_PASSWORD: czNjcjN0UEBzc3cwcmQ= # echo -n 's3cretP@ssw0rd' | base64
或使用命令创建:
kubectl create secret generic db-secret \
--from-literal=DB_HOST=mysql-host \
--from-literal=DB_USER=root \
--from-literal=DB_PASSWORD='s3cretP@ssw0rd'
在 Pod 中使用 Secret:
apiVersion: v1
kind: Pod
metadata:
name: secret-demo
spec:
containers:
- name: app
image: my-app:1.0
envFrom:
- secretRef:
name: db-secret
volumeMounts:
- name: secret-volume
mountPath: /etc/secrets
readOnly: true
volumes:
- name: secret-volume
secret:
secretName: db-secret
9. Ingress:七层流量入口
9.1 什么是 Ingress?
Ingress 是 K8s 的七层(HTTP/HTTPS)流量管理组件,提供:
- 基于域名的路由:不同域名指向不同服务
- 基于路径的路由:不同 URL 路径指向不同服务
- TLS 终止:在入口处处理 HTTPS
- 虚拟主机:多个服务共享一个外部 IP
9.2 架构示意
互联网流量
│
▼
┌─────────┐
│ Ingress │ ← Ingress Controller (如 nginx-ingress)
│Controller│
└────┬────┘
│
├── api.example.com ──→ api-service:8080
├── web.example.com ──→ web-service:80
└── app.example.com/admin ──→ admin-service:8080
9.3 创建 Ingress 资源
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
# 基于域名的路由
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- host: web.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
# 基于路径的路由
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
9.4 TLS 配置
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tls-ingress
spec:
ingressClassName: nginx
tls:
- hosts:
- secure.example.com
secretName: tls-secret # 包含证书的 Secret
rules:
- host: secure.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: secure-service
port:
number: 80
创建 TLS Secret:
kubectl create secret tls tls-secret \
--cert=path/to/tls.crt \
--key=path/to/tls.key
10. PV 与 PVC:持久化存储
10.1 为什么需要持久化存储?
容器中的数据是临时的,容器重建后数据丢失。K8s 提供了两层抽象:
- PV(PersistentVolume):集群级别的存储资源,由管理员创建
- PVC(PersistentVolumeClaim):用户对存储的请求,类似 "我需要 10GB 存储"
10.2 创建 PV
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi # 存储容量
accessModes:
- ReadWriteOnce # 单节点读写
storageClassName: standard
hostPath: # 本地目录(仅用于测试)
path: /data/pv
10.3 创建 PVC
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 5Gi # 请求 5GB 存储
10.4 在 Pod 中使用 PVC
apiVersion: v1
kind: Pod
metadata:
name: data-pod
spec:
containers:
- name: app
image: nginx:1.25
volumeMounts:
- name: data-volume
mountPath: /usr/share/nginx/html
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: my-pvc # 引用 PVC
10.5 动态存储供给
在云环境中,可以通过 StorageClass 实现自动创建 PV:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: fast-storage
provisioner: kubernetes.io/aws-ebs # AWS EBS 示例
parameters:
type: gp3
fsType: ext4
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
使用动态存储的 PVC:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: dynamic-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: fast-storage # 引用 StorageClass
resources:
requests:
storage: 20Gi
11. HPA:水平自动伸缩
11.1 什么是 HPA?
HPA(Horizontal Pod Autoscaler) 根据 CPU、内存或自定义指标自动调整 Pod 副本数量。
工作流程:
指标监控 → 与目标值比较 → 调整副本数 → 等待冷却 → 重复
11.2 前置条件
需要安装 Metrics Server:
# Minikube 环境
minikube addons enable metrics-server
# 验证
kubectl top nodes
kubectl top pods
11.3 创建 HPA
方式一:命令行
kubectl autoscale deployment nginx-deployment \
--cpu-percent=50 \
--min=2 \
--max=10
方式二:YAML 文件
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nginx-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
minReplicas: 2 # 最少 2 个副本
maxReplicas: 10 # 最多 10 个副本
metrics:
# 基于 CPU 使用率
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 # 目标:平均 CPU 使用率 50%
# 基于内存使用率
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 70 # 目标:平均内存使用率 70%
behavior:
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Pods
value: 4
periodSeconds: 60
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 10
periodSeconds: 60
11.4 验证 HPA
# 查看 HPA 状态
kubectl get hpa
# 详细信息
kubectl describe hpa nginx-hpa
# 生成负载测试(另开终端)
kubectl run -i --tty load-generator --rm --image=busybox:1.36 -- /bin/sh
# 在容器内执行
while true; do wget -q -O- http://nginx-service; done
12. 实战项目:部署微服务应用
12.1 项目架构
我们将部署一个简单的微服务应用,包含:
- 前端(Frontend):Nginx 反向代理,端口 80
- 后端 API(Backend):简单的 HTTP 服务,端口 8080
- Redis 缓存:存储访问计数
用户请求 → Ingress → Frontend Service → Frontend Pod
↓
Backend Service → Backend Pod
↓
Redis Service → Redis Pod
12.2 第一步:创建命名空间
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: microservice-demo
labels:
project: demo
12.3 第二步:部署 Redis
# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: microservice-demo
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:7-alpine
ports:
- containerPort: 6379
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
---
apiVersion: v1
kind: Service
metadata:
name: redis-service
namespace: microservice-demo
spec:
selector:
app: redis
ports:
- port: 6379
targetPort: 6379
12.4 第三步:部署后端 API
# backend-deployment.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: backend-config
namespace: microservice-demo
data:
REDIS_HOST: "redis-service"
REDIS_PORT: "6379"
APP_PORT: "8080"
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: microservice-demo
spec:
replicas: 2
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: hashicorp/http-echo:latest
args:
- "-text=Hello from Backend! Visit count is tracked by Redis."
- "-listen=:8080"
ports:
- containerPort: 8080
envFrom:
- configMapRef:
name: backend-config
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
name: backend-service
namespace: microservice-demo
spec:
selector:
app: backend
ports:
- port: 8080
targetPort: 8080
12.5 第四步:部署前端
# frontend-deployment.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-config
namespace: microservice-demo
data:
default.conf: |
server {
listen 80;
server_name localhost;
location / {
return 200 '{"status": "ok", "service": "frontend"}';
add_header Content-Type application/json;
}
location /api/ {
proxy_pass http://backend-service:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: microservice-demo
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "200m"
memory: "128Mi"
volumes:
- name: nginx-config
configMap:
name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
namespace: microservice-demo
spec:
selector:
app: frontend
ports:
- port: 80
targetPort: 80
12.6 第五步:配置 Ingress
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: microservice-ingress
namespace: microservice-demo
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: demo.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 8080
12.7 第六步:配置 HPA
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: backend-hpa
namespace: microservice-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: backend
minReplicas: 2
maxReplicas: 8
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 60
12.8 部署整个应用
# 创建目录结构
mkdir -p k8s-microservice
cd k8s-microservice
# 将上面的 YAML 文件分别保存,然后一键部署
kubectl apply -f namespace.yaml
kubectl apply -f redis-deployment.yaml
kubectl apply -f backend-deployment.yaml
kubectl apply -f frontend-deployment.yaml
kubectl apply -f ingress.yaml
kubectl apply -f hpa.yaml
# 或者一次性部署整个目录
kubectl apply -f .
12.9 验证部署
# 查看所有资源
kubectl get all -n microservice-demo
# 查看 Pod 状态
kubectl get pods -n microservice-demo -o wide
# 查看 Service
kubectl get svc -n microservice-demo
# 查看 Ingress
kubectl get ingress -n microservice-demo
# 查看 HPA
kubectl get hpa -n microservice-demo
# 测试前端
kubectl run -it --rm test-curl --image=curlimages/curl --restart=Never -- \
curl http://frontend-service.microservice-demo.svc.cluster.local
# 测试后端 API
kubectl run -it --rm test-curl --image=curlimages/curl --restart=Never -- \
curl http://backend-service.microservice-demo.svc.cluster.local:8080
# Minikube 环境下通过 Ingress 访问
# 先添加 hosts 映射
echo "$(minikube ip) demo.local" | sudo tee -a /etc/hosts
curl http://demo.local
curl http://demo.local/api
12.10 清理资源
# 删除整个命名空间(会删除其中所有资源)
kubectl delete namespace microservice-demo
13. 常用命令速查表
资源查看
# 查看所有资源
kubectl get all
# 查看指定命名空间的资源
kubectl get all -n <namespace>
# 查看详细信息
kubectl describe <resource-type> <resource-name>
# 以 YAML 格式查看资源
kubectl get pod <pod-name> -o yaml
# 以 JSON 格式查看
kubectl get pod <pod-name> -o json
# 查看资源使用情况(需要 metrics-server)
kubectl top nodes
kubectl top pods
资源操作
# 创建/更新资源
kubectl apply -f <file.yaml>
# 删除资源
kubectl delete -f <file.yaml>
kubectl delete pod <pod-name>
kubectl delete deployment <deployment-name>
# 强制删除卡住的 Pod
kubectl delete pod <pod-name> --grace-period=0 --force
调试排查
# 查看 Pod 日志
kubectl logs <pod-name>
kubectl logs <pod-name> -f # 实时跟踪
kubectl logs <pod-name> --previous # 查看上一个容器的日志
# 进入容器
kubectl exec -it <pod-name> -- /bin/sh
kubectl exec -it <pod-name> -- /bin/bash
# 端口转发(本地调试)
kubectl port-forward pod/<pod-name> 8080:80
kubectl port-forward svc/<service-name> 8080:80
# 查看事件
kubectl get events --sort-by='.lastTimestamp'
配置管理
# 查看当前上下文
kubectl config current-context
# 切换上下文
kubectl config use-context <context-name>
# 查看所有上下文
kubectl config get-contexts
# 设置默认命名空间
kubectl config set-context --current --namespace=<namespace>
14. 学习路线建议
初级阶段
- 理解核心概念:Pod、Deployment、Service、Namespace
- 掌握基本操作:kubectl 的常用命令
- 本地实践:用 Minikube 搭建环境,跟着教程动手
中级阶段
- 配置管理:ConfigMap、Secret、环境变量
- 存储管理:PV、PVC、StorageClass
- 网络管理:Ingress、NetworkPolicy
- 自动伸缩:HPA、VPA
- 安全基础:RBAC、ServiceAccount
高级阶段
- Helm:K8s 包管理工具
- Operator 模式:自定义控制器
- 服务网格:Istio、Linkerd
- CI/CD 集成:GitOps(ArgoCD、Flux)
- 监控告警:Prometheus + Grafana
推荐学习资源
- 官方文档:https://kubernetes.io/zh/docs/
- 互动教程:https://kubernetes.io/zh/docs/tutorials/
- Katacoda 替代:https://killercoda.com/playgrounds/scenario/kubernetes
- kubectl 速查:https://kubernetes.io/zh/docs/reference/kubectl/cheatsheet/
总结
本教程涵盖了 Kubernetes 的核心知识体系:
| 知识点 | 核心作用 |
|---|---|
| Pod | 最小调度单元,运行容器 |
| Deployment | 管理副本,滚动更新,自愈 |
| Service | 服务发现,负载均衡 |
| Namespace | 资源隔离 |
| ConfigMap/Secret | 配置与敏感数据管理 |
| Ingress | 七层流量入口 |
| PV/PVC | 持久化存储 |
| HPA | 自动水平伸缩 |
最重要的建议:K8s 是实践性很强的技术,光看文档远远不够。一定要动手操作,从 Minikube 开始,逐步构建自己的实验环境。遇到问题时,kubectl describe 和 kubectl logs 是你最好的调试伙伴。
祝你学习愉快!🚀