《云原生从0到1:Kubernetes 工作负载实战------Deployment/Service/滚动更新/弹性伸缩》
作者:云原生学习者 | 系列:云原生工程师实战之路
一句话导读:集群搭好了(见系列前两篇),本篇开始"用起来":以一个 Go 编写的 HTTP 微服务为例,走一遍 Deployment 部署 → Service 暴露 → 滚动更新 → 水平伸缩 → 故障自愈的完整链路,带你建立对 K8s 工作负载的直观认识。
0. 实验环境回顾
| 项 | 值 |
|---|---|
| 集群 | 1 Master + 3 Worker(K8s v1.28.2) |
| 运行时 | containerd 2.2.1 |
| CNI | Calico(Pod 网段 10.244.0.0/16) |
| 示例应用 | go-demo(Go 编写的 JSON 接口服务) |
1. 编写 Go 微服务
一个返回服务实例信息的 HTTP 服务,用于直观展示"请求打到了哪个 Pod":
go
package main
import (
"encoding/json"
"log"
"net/http"
"os"
"time"
)
type Info struct {
Service string `json:"service"`
Version string `json:"version"`
Hostname string `json:"hostname"`
PodIP string `json:"pod_ip"`
Time string `json:"time"`
}
var version = "v1.0.0"
func infoHandler(w http.ResponseWriter, r *http.Request) {
hostname, _ := os.Hostname()
podIP := os.Getenv("POD_IP")
if podIP == "" {
podIP = r.RemoteAddr
}
json.NewEncoder(w).Encode(Info{
Service: "go-demo", Version: version,
Hostname: hostname, PodIP: podIP,
Time: time.Now().Format("2006-01-02 15:04:05"),
})
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/", infoHandler)
log.Fatal(http.ListenAndServe(":8080", mux))
}
多阶段构建 Dockerfile(builder 阶段编译 + 运行阶段仅保留二进制,镜像极小):
dockerfile
FROM golang:1.22-alpine AS builder
WORKDIR /app
COPY main.go .
RUN go mod init go-demo && go build -ldflags="-s -w" -o go-demo .
FROM alpine:3.19
WORKDIR /root/
COPY --from=builder /app/go-demo .
EXPOSE 8080
CMD ["./go-demo"]
2. Deployment:声明式管理应用
Deployment 是 K8s 中最常用的工作负载控制器,负责:副本数保证、滚动更新、故障自愈、回滚。
yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: go-demo
labels:
app: go-demo
spec:
replicas: 3 # 期望副本数
selector:
matchLabels:
app: go-demo
template:
metadata:
labels:
app: go-demo
spec:
containers:
- name: go-demo
image: go-demo:latest
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP # Downward API:把 Pod IP 注入环境变量
resources:
requests: # 资源请求(调度依据)
cpu: 100m
memory: 128Mi
limits: # 资源上限(限制使用)
cpu: 500m
memory: 256Mi
readinessProbe: # 就绪探针:通过才加入 Service 转发
httpGet:
path: /
port: 8080
initialDelaySeconds: 3
periodSeconds: 5
关键点解读:
selector.matchLabels必须与 template 的 labels 匹配,Deployment 通过它管理 Pod;- readinessProbe:Pod 就绪才接收流量,滚动更新时保证不中断服务;
- resources:requests 决定调度到哪个节点,limits 限制资源使用。
3. Service:稳定的访问入口
Pod 的 IP 会随重建而变化,Service 提供稳定的虚拟 IP(ClusterIP)+ DNS 名称:
yaml
apiVersion: v1
kind: Service
metadata:
name: go-demo
spec:
selector:
app: go-demo # 关联上面 Deployment 管理的 Pod
ports:
- port: 80 # Service 端口
targetPort: 8080 # 转发到 Pod 的端口
type: ClusterIP
集群内通过 go-demo.default.svc.cluster.local 或 go-demo 访问,Service 自动负载均衡到 3 个 Pod。
4. 滚动更新实战
修改镜像版本号触发更新:
bash
kubectl set image deployment/go-demo go-demo=go-demo:v2.0.0
# 或者声明式更新
kubectl rollout status deployment/go-demo
滚动更新过程(ReplicaSet 交替扩容/缩容,全程零停机):
text
Waiting for deployment "go-demo" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "go-demo" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "go-demo" successfully rolled out
回滚:
bash
kubectl rollout undo deployment/go-demo
5. 水平伸缩(HPA)
根据 CPU 使用率自动扩缩容:
bash
kubectl autoscale deployment go-demo --cpu-percent=50 --min=3 --max=10
# 或声明式
kubectl apply -f hpa.yaml
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: go-demo
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: go-demo
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
用压测工具(如 hey)打流量,观察 Pod 自动扩容:
bash
kubectl get hpa -w
kubectl get pods -w
6. 故障自愈演示
模拟 Pod 故障,观察 K8s 自动拉起新副本:
bash
kubectl delete pod <pod名称>
kubectl get pods -w
# 几秒内,Deployment 会重新创建一个新 Pod,服务不受影响
核心原理:kubelet 上报 Pod 状态 → controller-manager 中的 Deployment controller 发现副本数不足 → 通过 ReplicaSet 创建新 Pod → scheduler 调度到合适节点。这正是课程第 17 周"controller 底层原理"讲的**控制循环(reconcile loop)**思想。
7. 验证 Service 负载均衡
从集群内发起多次请求,观察返回的 hostname 是否在不同 Pod 间轮转:
bash
kubectl run curl-test --image=curlimages/curl -it --rm -- \
sh -c 'for i in $(seq 1 6); do curl -s go-demo | jq -r .hostname; done'
预期:3 个不同 Pod 名轮流出现,证明负载均衡生效。
8. 小结
本篇用一个小微服务完整演示了 K8s 工作负载的核心能力。这张表值得收藏:
| 能力 | 对应资源 | 一句话原理 |
|---|---|---|
| 副本管理 | Deployment → ReplicaSet | 控制循环保证期望状态 |
| 稳定访问 | Service (ClusterIP) | iptables/IPVS 规则转发 |
| 滚动更新 | Deployment strategy | 新旧 ReplicaSet 交替 |
| 自动伸缩 | HPA | 指标采集 + 期望副本计算 |
| 故障自愈 | kubelet + controller | 状态上报 + 控制循环 |
| 配置注入 | Downward API / ConfigMap | 运行时信息注入 |
下一篇将分享 Prometheus + Grafana 监控告警体系部署实战,敬请期待!
本文为原创实操记录。欢迎转载,请注明出处。