目标
部署:
互联网 → Ingress → Service → Deployment(3 副本) → Pods
↑
ConfigMap / Secret
一份完整 yaml(拆解版)
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
labels: { app: webapp }
spec:
replicas: 3
selector:
matchLabels: { app: webapp }
template:
metadata:
labels: { app: webapp }
spec:
containers:
- name: webapp
image: ghcr.io/me/webapp:1.4.2 # 永远具体版本
ports:
- containerPort: 8080
resources:
requests: { cpu: 100m, memory: 128Mi }
limits: { cpu: 500m, memory: 512Mi }
env:
- name: NODE_ENV
value: production
- name: DATABASE_URL
valueFrom:
secretKeyRef: { name: webapp-secret, key: db-url }
envFrom:
- configMapRef: { name: webapp-config }
readinessProbe:
httpGet: { path: /health, port: 8080 }
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet: { path: /health, port: 8080 }
initialDelaySeconds: 30
periodSeconds: 30
要点:
- resources 要写:
requests决定调度上限,limits决定 OOMKill 触发;不写就乱了 - readiness vs liveness:readiness = "能接流量了吗";liveness = "进程还活吗"。两个都重要
- initialDelay:应用慢启动的话给够时间,否则 liveness 会一直 kill
Service
apiVersion: v1
kind: Service
metadata:
name: webapp
spec:
selector: { app: webapp }
ports:
- port: 80
targetPort: 8080
type: ClusterIP # 仅集群内可访问
type 三种:
ClusterIP(默认):仅集群内NodePort:集群任一节点 IP:30000+ 可达LoadBalancer:云上自动开 LB;裸金属需要 MetalLB
生产几乎都用 ClusterIP + Ingress。
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
ingressClassName: nginx
tls:
- hosts: [app.wadely.com]
secretName: webapp-tls
rules:
- host: app.wadely.com
http:
paths:
- path: /
pathType: Prefix
backend:
service: { name: webapp, port: { number: 80 } }
需要先装 Ingress Controller(nginx-ingress / Traefik / cloud-native LB)+ cert-manager。
操作命令
kubectl apply -f . # 应用所有 yaml
kubectl get pods -w # 实时看 Pod 状态
kubectl describe pod webapp-xxx
kubectl logs webapp-xxx -f # 流式日志
kubectl logs --previous # 看上次崩溃前的日志
kubectl exec -it webapp-xxx -- sh
kubectl rollout status deployment/webapp
kubectl rollout undo deployment/webapp
探针的三种类型
| 类型 | 失败结果 | 何时用 |
|---|---|---|
livenessProbe |
重启容器 | 应用死锁 / 内存泄漏 |
readinessProbe |
摘出 Service 列表 | 启动慢 / 间歇不健康 |
startupProbe |
阻塞 liveness 直到通过 | 应用启动特别慢 |
3 个都给同一个 /health 端点是反模式——分清职责:
/healthz/ready: 依赖(DB / Redis)通了吗/healthz/live: 进程还在 event loop 吗
资源单位
cpu: 100m = 0.1 核(1000m = 1 核)
memory: 128Mi = 128 兆(Mi 二进制;M 是十进制)
requests 算调度,limits 算限制。memory 超过 limits 直接 OOMKilled;CPU 超过被 throttle。
别忘了 namespace
kubectl apply -f . -n production
kubectl get pods --all-namespaces
不写 namespace 默认 default——别把生产堆这里。
推荐阅读
- K8s: Configure Liveness, Readiness and Startup Probes
- Resource Management for Pods and Containers
- Ingress NGINX — 主流 Ingress 实现
- cert-manager — K8s 内自动签证书
下一篇:ConfigMap 和 Secret 怎么用对、坑在哪。