为什么需要 Kubernetes
Docker 解决了“单机容器化”的问题,但生产环境要面对的是:几十上百个容器跨多台机器运行、某台机器宕机要自动迁移、流量要负载均衡、版本要滚动更新与回滚、配置和密钥要集中管理。手动维护这些几乎不可能,这就是容器编排系统存在的意义。Kubernetes(K8s)在激烈的竞争中胜出,成为云原生时代的事实标准。
本文用最小认知负担带你入门:先理清核心概念,再动手部署第一个应用。
核心概念:一张图理清关系
理解 K8s,先记住这条数据流:Pod 跑容器,Deployment 管 Pod,Service 暴露 Pod,Ingress 把外部流量接入 Service。
Pod 与 Deployment
先看一个最简单的 Deployment,运行 3 个 Nginx 副本:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.27-alpine
ports:
- containerPort: 80
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 200m
memory: 128Mi关键字段解读:
replicas: 3:期望运行 3 个 Pod。selector.matchLabels + template.labels:Deployment 通过标签找到它管理的 Pod,两者必须匹配。resources:声明资源请求与上限,是调度和稳定性的基础。不设资源限制的容器是集群不稳定的头号元凶。kubectl apply -f deployment.yaml
kubectl get pods -l app=nginx
kubectl rollout status deployment/nginx-deployService:给 Pod 一个稳定入口
Pod 重启后 IP 会变,不能直接给前端用。Service 通过标签选择器动态关联一组 Pod,提供稳定 DNS 名:
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
type: ClusterIPClusterIP(默认):集群内可达,外部不可达。NodePort:在每个节点开一个端口,可从外部访问,适合调试。LoadBalancer:云厂商提供外部负载均衡器,生产常用。集群内其他服务可以通过 nginx-svc.default.svc.cluster.local 这个 DNS 名访问。
Ingress:统一外部入口
LoadBalancer 类型的 Service 每个都占一个云负载均衡器,成本高。Ingress 用一个入口按域名/路径路由到多个 Service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: api-svc
port:
number: 8080Ingress 需要安装 Ingress Controller(如 ingress-nginx)才能生效,它是真正处理流量的组件。
配置与密钥分离
把配置从镜像里剥离出来,是 12-Factor App 的核心实践。
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
DB_HOST: "db.internal"
---
apiVersion: v1
kind: Secret
metadata:
name: app-secret
type: Opaque
stringData:
DB_PASSWORD: "super-secret"在 Deployment 中注入:
spec:
containers:
- name: app
image: myapp:1.0
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: app-secretSecret 只是 base64 编码,并非加密,生产环境应配合云厂商的 KMS 或外部密钥管理(如 External Secrets Operator)。
健康检查:让 K8s 自动恢复故障
spec:
containers:
- name: app
image: myapp:1.0
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5滚动更新与回滚
Deployment 默认滚动更新:逐步创建新 Pod、逐步删除旧 Pod,全程服务不中断。
# 更新镜像版本
kubectl set image deployment/nginx-deploy nginx=nginx:1.28-alpine
# 查看发布历史
kubectl rollout history deployment/nginx-deploy
# 回滚到上一版本
kubectl rollout undo deployment/nginx-deploy
# 回滚到指定版本
kubectl rollout undo deployment/nginx-deploy --to-revision=2配合 readinessProbe 和合理的 maxUnavailable / maxSurge,可以实现零停机发布。
本地练手:用 kind 起一个集群
无需云账号,本地就能练:
# 安装 kind(Kubernetes in Docker)
kind create cluster --name demo
kubectl get nodes
# 部署前面的 yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# 端口转发,本地访问
kubectl port-forward svc/nginx-svc 8080:80
# 浏览器打开 http://localhost:8080小结
K8s 的学习曲线确实陡,但核心模型并不复杂:Pod 是运行单元,Deployment 管理副本与更新,Service 提供稳定网络,Ingress 统一入口,ConfigMap/Secret 管配置。从这五个对象入手,先在本地用 kind 跑通一个完整应用,再逐步接触 StatefulSet、HPA、PV/PVC 等进阶概念。别一上来就背全部 API,动手部署一次远比读十遍文档有效。当你能熟练地声明式管理应用并做滚动更新与回滚时,你就真正迈进了云原生的大门。
💬 评论区 (0)
暂无评论,快来抢沙发吧!