Kubernetes(K8s)入门
K8s 是容器编排平台:自动部署、扩缩容、故障恢复。前端面试重点是概念 + 选型,不要求会写复杂 manifest。本篇聚焦前端 SSR / Node 服务的 K8s 实战。
一、避坑指南
K8s 不是银弹,小项目用 K8s 是过度设计:
- 1 台机器 → 用 PM2 够了
- 3~5 台机器 → Docker + Swarm 或 compose
- 10+ 台 → 才有 K8s 价值
概念先于 YAML:不要上来就抄 manifest,先理解 Pod / Deployment / Service。
资源限制必加:不设 limits 会一台 Pod 吃光整个节点。
# ❌ 不设限制
containers:
- name: web
image: myapp:1.0
# ✅ 必设
containers:
- name: web
image: myapp:1.0
resources:
requests: # 调度依据
memory: "256Mi"
cpu: "250m" # 0.25 核
limits: # 上限
memory: "512Mi"
cpu: "500m"健康检查必加:缺 health check K8s 不知道 Pod 是不是真挂了。
不要把所有配置塞进镜像:
# ❌ 改个环境变量要重新 build
env:
- name: DATABASE_URL
value: "postgresql://..."
# ✅ 用 ConfigMap / Secret
envFrom:
- configMapRef:
name: myapp-config
- secretRef:
name: myapp-secrets镜像 tag 不要用
latest:用latestK8s 不会自动更新,且每次拉的可能不一样。
二、什么时候用 K8s?
| 规模 / 场景 | 用 K8s? | 替代方案 |
|---|---|---|
| 单机内部工具 | ❌ | PM2 / 直接跑 |
| 1~3 台机器 | ❌ | PM2 / Docker Compose |
| 5~10 台,需要扩缩容 | ✅ 推荐 | Docker Swarm / 阿里云 SAE |
| 10+ 台,多团队多服务 | ✅ 必用 | — |
| 大流量弹性扩缩 | ✅ 必用 | — |
| 国内云厂商托管 | ✅ | 阿里云 ACK / 腾讯云 TKE / 华为 CCE |
| 不想运维 K8s | ✅ 但用托管 | EKS / AKS / GKE / 阿里云 ACK |
决策原则:机器数 ≤ 5 用 PM2/Docker;> 10 用 K8s;中间用云厂商托管 K8s。
三、K8s vs Docker vs PM2
| 维度 | PM2 | Docker | K8s |
|---|---|---|---|
| 资源隔离 | ❌ | ✅ | ✅ |
| 自动扩缩容 | ❌ | ❌ | ✅ HPA |
| 故障自愈 | 部分 | restart policy | ✅ 自动重启 / 重新调度 |
| 负载均衡 | cluster 内置 | 需外部 | ✅ Service |
| 滚动更新 | reload | 手动 | ✅ Deployment |
| 服务发现 | ❌ | docker network | ✅ DNS / Service |
| 配置管理 | 文件 | env / file | ✅ ConfigMap / Secret |
| 学习成本 | 低 | 中 | 高 |
| 运维成本 | 低 | 中 | 高(除非托管) |
前端角度:K8s 通常是后端 / SRE 在管,前端要懂概念和会写简单 manifest,不要求精通。
四、核心概念(面试必背)
K8s 架构
├─ 控制平面(Control Plane) ← 大脑
│ ├─ kube-apiserver ← API 入口
│ ├─ etcd ← 集群状态存储
│ ├─ kube-scheduler ← 调度 Pod 到 Node
│ └─ kube-controller-manager
│
└─ 工作节点(Node) ← 干活的机器
├─ kubelet ← 与 apiserver 通信
├─ kube-proxy ← 网络代理
└─ Container Runtime(containerd / CRI-O)
4.1 资源对象
| 对象 | 作用 | 类比 |
|---|---|---|
| Pod | 最小调度单位,1~N 个容器 | 一个进程 |
| Deployment | 管理 Pod 副本(replicas)+ 滚动更新 | 应用 |
| Service | Pod 的稳定访问入口(IP + DNS) | 反向代理 |
| Ingress | 集群外部 HTTP/HTTPS 入口 | Nginx |
| ConfigMap | 非敏感配置 | env file |
| Secret | 敏感配置(base64 编码,非加密) | .env |
| StatefulSet | 有状态服务(DB) | — |
| DaemonSet | 每节点一个 Pod(日志收集) | — |
| Job / CronJob | 一次性 / 定时任务 | — |
| HPA | Horizontal Pod Autoscaler(自动扩缩) | — |
4.2 一句话理解
Pod = 进程,Deployment = 进程组,Service = 进程的固定地址,Ingress = 集群门口的网关。
五、前端 SSR 的 K8s 部署清单
完整 k8s/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-web
labels:
app: my-web
spec:
replicas: 3 # 3 个副本
selector:
matchLabels:
app: my-web
template:
metadata:
labels:
app: my-web
spec:
containers:
- name: web
image: ghcr.io/myorg/myapp:v1.0.0 # 必带版本号
ports:
- containerPort: 3000
# 资源限制
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
# 环境变量
env:
- name: NODE_ENV
value: "production"
- name: PORT
value: "3000"
envFrom:
- configMapRef:
name: my-web-config
- secretRef:
name: my-web-secrets
# 健康检查
livenessProbe: # 活探:失败 → 重启
httpGet:
path: /api/health
port: 3000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe: # 就绪探:失败 → 不接流量
httpGet:
path: /api/ready
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
---
# Service:把 3 个 Pod 暴露成单一入口
apiVersion: v1
kind: Service
metadata:
name: my-web
spec:
selector:
app: my-web
ports:
- port: 80
targetPort: 3000
type: ClusterIP # 集群内部访问
---
# Ingress:暴露到公网
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-web
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-web
port:
number: 80
---
# ConfigMap:非敏感配置
apiVersion: v1
kind: ConfigMap
metadata:
name: my-web-config
data:
APP_NAME: "MyApp"
LOG_LEVEL: "info"
---
# Secret:敏感配置(base64 编码)
apiVersion: v1
kind: Secret
metadata:
name: my-web-secrets
type: Opaque
stringData: # 用 stringData 自动 base64
DATABASE_URL: "postgresql://user:pass@db:5432/mydb"
JWT_SECRET: "xxx"
kubectl apply -f k8s/
kubectl get pods
kubectl get svc
kubectl get ingress
六、HPA(自动扩缩容)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-web-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-web
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU > 70% 自动扩
HPA 原理:每 15s 检查指标 → 超阈值扩 / 降阈值缩 → 配合 readiness 探针保证流量不打到还没就绪的 Pod。
七、Helm Chart 入门
Helm = K8s 的包管理器。一个 Chart 管理一组相关 manifest,支持版本化、参数化。
my-chart/
├─ Chart.yaml # Chart 元信息
├─ values.yaml # 默认值
└─ templates/
├─ deployment.yaml
├─ service.yaml
└─ ingress.yaml
values.yaml:
replicaCount: 3
image:
repository: ghcr.io/myorg/myapp
tag: "v1.0.0"
service:
port: 80
ingress:
enabled: true
host: example.com
templates/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Chart.Name }}
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: web
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
helm install myapp ./my-chart --set replicaCount=5
helm upgrade myapp ./my-chart
helm rollback myapp 1
八、CI/CD 集成(GitOps)
现代 K8s 推荐 GitOps 模式:Git 是真理来源,K8s 自动同步。
Git push → CI 构建镜像 → 更新 Git 仓库的 manifest →
ArgoCD 检测变化 → 自动 apply 到 K8s
ArgoCD:
# argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: my-web
spec:
project: default
source:
repoURL: https://github.com/myorg/k8s-manifests
targetRevision: main
path: overlays/production
destination:
server: https://kubernetes.default.svc
namespace: production
syncPolicy:
automated:
prune: true
selfHeal: true
九、面试高频(重点)
Q1:K8s 核心组件有哪些?各自干什么?
A:控制面(kube-apiserver / etcd / scheduler / controller-manager)+ 节点(kubelet / kube-proxy / 容器运行时)。最常问的是 Pod → Node 的调度流程:apiserver 收到请求 → scheduler 看资源决定放到哪个 Node → kubelet 在 Node 上启动容器。
Q2:Pod 是什么?为什么不直接用容器?
A:Pod 是共享网络和存储的容器组。K8s 调度的最小单位是 Pod 不是容器。典型场景:一个 Pod 里有主应用容器 + sidecar 容器(如日志收集),共享网络。
Q3:Deployment 和 Pod 关系?
A:Pod 是一次性的(挂了就没了),Deployment 是Pod 的控制器,保证「期望副本数」一直满足。Pod 挂了 Deployment 自动重启新的。生产环境不直接创建 Pod,用 Deployment。
Q4:Service 怎么负载均衡到多个 Pod?
A:Service 通过 label selector 选中一组 Pod,用 iptables / IPVS 做负载均衡(kube-proxy 维护转发规则)。默认轮询。
Q5:K8s 怎么做到零停机发布?
A:Deployment 滚动更新:
- 创建新版本 Pod
- 旧 Pod 流量不立刻切(等 readiness 通过)
- 逐个替换(旧的下线 → 新的上线)
- 任何时刻都有 Pod 在线
如果新版本有问题:kubectl rollout undo 秒级回滚。
Q6:ConfigMap 和 Secret 区别?
A:
- ConfigMap:非敏感配置(明文)
- Secret:敏感配置(base64 编码,不是加密**)
- 真正加密要用外部 KMS(AWS KMS / 阿里云 KMS)
Q7:什么时候考虑 K8s?
A:机器数 ≥ 10、需自动扩缩、多团队多服务。1~3 台机器用 PM2 够了。K8s 学习成本高、运维贵,小项目过度设计反而拖慢迭代。
Q8:什么是 HPA?
A:Horizontal Pod Autoscaler,根据 CPU / 内存 / 自定义指标自动调整 Pod 副本数。比如 CPU > 70% 持续 5 分钟,自动加一个 Pod。