预计时间
1 周
定位
这一节只要求理解概念 + 跑通 demo,不要求成为 K8s 专家。K8s 学习曲线陡峭,初学搞清楚 Pod / Deployment / Service / Ingress 就够了。
学习目标
- 理解 Pod、Deployment、Service、Ingress
- 能用 kubectl 操作集群
- 能把 Docker Compose 项目迁移到 K8s
一、K8s 解决什么问题?
text
Docker Compose 的局限:
- 单机 — 一台服务器挂了全挂
- 手动扩容 — 要改 compose 文件加 replicas
- 滚动更新 — 手动操作
- 服务发现 — 靠 DNS 名,跨机器就不行
K8s 的答案:
你告诉它"我要 3 个 backend、2 个 frontend、1 个 PostgreSQL"
K8s 自动调度到多台机器、自动重启挂了容器、自动滚动更新二、核心概念
2.1 Pod — 最小调度单元
yaml
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: backend-pod
labels:
app: backend
spec:
containers:
- name: backend
image: my-backend:latest
ports:
- containerPort: 3001
env:
- name: DATABASE_URL
value: "postgresql://user:pass@postgres:5432/db"text
Pod 是什么?
- K8s 不直接管理容器,管理 Pod
- 1 个 Pod 通常有 1 个 Container(也有 sidecar 模式放 2 个)
- Pod 里的容器共享网络和存储
- Pod 是临时的,IP 会变,随时可能被销毁重建一般不直接创建 Pod
Pod 是"底层",直接创建 Pod 挂了不会自动重启。实际使用 Deployment 管理 Pod。
2.2 Deployment — 管理 Pod
yaml
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend-deployment
spec:
replicas: 3 # 3 个副本
selector:
matchLabels:
app: backend
template: # Pod 模板
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: my-backend:v1.0
ports:
- containerPort: 3001
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe: # 健康检查
httpGet:
path: /health
port: 3001
initialDelaySeconds: 10
periodSeconds: 5text
Deployment 做什么?
- 保持 Pod 副本数(挂了自动补上)
- 滚动更新(一个一个替换 Pod,服务不中断)
- 回滚(kubectl rollout undo)2.3 Service — 稳定的访问入口
yaml
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend # 选择哪些 Pod
ports:
- port: 80 # Service 的端口
targetPort: 3001 # Pod 的端口
type: ClusterIP # 默认,集群内部访问text
问题:Pod IP 会变 → 前端怎么知道连哪个 IP?
解决:Service 提供固定的 ClusterIP + DNS 名
集群内访问:
http://backend-service → Service → 自动负载均衡到 3 个 Pod
Service 类型:
ClusterIP — 仅集群内部访问(默认)
NodePort — 宿主机端口暴露(不推荐生产用)
LoadBalancer — 云厂商 LB(生产用)2.4 Ingress — 外部流量入口
yaml
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
spec:
rules:
- host: api.myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: backend-service
port:
number: 80
- host: myapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80text
Ingress = K8s 版的 Nginx 反向代理
myapp.com → frontend-service
api.myapp.com → backend-service
需要安装 Ingress Controller(如 nginx-ingress)才能工作。三、ConfigMap & Secret
yaml
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
NODE_ENV: "production"
LOG_LEVEL: "info"
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DATABASE_URL: "postgresql://user:password@postgres:5432/db"
JWT_SECRET: "your-secret-key"yaml
# 在 Deployment 中使用
spec:
containers:
- name: backend
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secret四、常用命令
bash
# 查看
kubectl get pods # 所有 Pod
kubectl get deployments # 所有 Deployment
kubectl get services # 所有 Service
kubectl get ingress # 所有 Ingress
kubectl describe pod <pod-name> # Pod 详情
# 日志
kubectl logs <pod-name> # 查看日志
kubectl logs -f <pod-name> # 实时日志
# 操作
kubectl apply -f deployment.yaml # 创建/更新资源
kubectl delete -f deployment.yaml # 删除资源
kubectl rollout restart deployment/backend # 重启
kubectl rollout undo deployment/backend # 回滚
# 调试
kubectl exec -it <pod-name> -- /bin/sh # 进容器
kubectl port-forward <pod-name> 3001:3001 # 端口转发到本地五、Docker Compose → K8s 迁移对照
| Docker Compose | Kubernetes |
|---|---|
| Service | Deployment + Service |
ports: "3000:3000" | Service port + targetPort |
depends_on | initContainers 或 healthcheck + readinessProbe |
volumes: - pgdata:/data | PersistentVolume + PersistentVolumeClaim |
environment | ConfigMap / Secret |
networks | 默认 Pod 间互通 + NetworkPolicy 隔离 |
六、本地开发
不用买云服务器,本地就能跑 K8s:
bash
# 选项 1: Docker Desktop 内置 K8s
# Settings → Kubernetes → Enable Kubernetes
# 选项 2: minikube
brew install minikube
minikube start
# 选项 3: kind (Kubernetes in Docker)
brew install kind
kind create cluster实践
- 装一个 minikube 或 kind
- 把 Docker Compose 项目转成 Deployment + Service YAML
kubectl apply -f .部署kubectl port-forward访问- 故意删一个 Pod → 观察自动恢复