Kubernetes Crash Course

Pods, Deployments, Services, Ingress and ConfigMaps — the mental model and the daily commands for running stateless services on K8s.

IntermediateUpdated 2026-10-2844K views

The object model in one screen

Kubernetes vocabulary feels huge, but for a stateless web service you only need five objects, wrapped in a strict hierarchy: Deployment manages ReplicaSets which manage Pods; Service gives them a stable address; Ingress routes HTTP from outside; ConfigMap/Secret injects config.

ObjectPurposeStability
Pod最小调度单元,1+ 共享网络/存储的容器IP 会变,随生死
ReplicaSet维持指定数量的 Pod 副本随滚动更新换代
Deployment声明期望副本数与镜像版本,做滚动更新/回滚长期存在
Service为一组 Pod 提供稳定 ClusterIP + 负载均衡长期存在
Ingress七层路由:域名/路径 → Service长期存在
ConfigMap/Secret配置与敏感数据,可挂载为文件或环境变量独立于 Pod 生命周期
外部流量
  │
  ▼
Ingress (backend-wiki.example.com → svc:api)
  │
  ▼
Service api (ClusterIP 10.96.x.x, selectors app=api)   ← 稳定入口
  │ kube-proxy 在各节点做 DNAT
  ▼
Deployment api (replicas=3)
  └─ ReplicaSet (镜像 v1.4.2)
       ├─ Pod api-7d8b9c-x2k4p   ← 真正跑容器的地方
       ├─ Pod api-7d8b9c-mp1qz
       └─ Pod api-7d8b9c-v9w3t

Your first Deployment + Service

apiVersion: apps/v1
kind: Deployment
metadata: {name: api}
spec:
  replicas: 3
  selector: {matchLabels: {app: api}}
  template:
    metadata: {labels: {app: api}}
    spec:
      containers:
      - name: api
        image: registry.example.com/api:1.4.2
        ports: [{containerPort: 8080}]
        resources:
          requests: {cpu: 100m, memory: 128Mi}
          limits:   {cpu: 500m, memory: 512Mi}
        readinessProbe:
          httpGet: {path: /health, port: 8080}
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata: {name: api}
spec:
  selector: {app: api}
  ports: [{port: 80, targetPort: 8080}]
requests are for scheduling (which node can fit me) and limits are for enforcement (throttle/kill). Setting limits without requests means the scheduler ignores your real needs — set both.
  • readinessProbe failures remove the Pod from the Service endpoints — it stays alive but receives no traffic
  • Rolling update: Deployment creates a new ReplicaSet, scales it up and the old one down, respecting maxSurge/maxUnavailable
  • rollout undo / rollout status are your undo and progress bar
kubectl apply -f api.yaml
kubectl get pods -l app=api -o wide
kubectl rollout status deployment/api
kubectl rollout undo deployment/api --to-revision=2
kubectl describe pod api-7d8b9c-x2k4p   # 看 Events 排查为什么没起来

Config injection: ConfigMap & Secret

Twelve-factor style: config lives outside the image. ConfigMap and Secret can be consumed three ways: env vars (simple, but no live update), command args, or mounted files (supports dynamic reload).

apiVersion: v1
kind: ConfigMap
metadata: {name: api-conf}
data:
  config.yaml: |
    log_level: info
    feature_flags:
      new_search: true
---
# 在 Deployment spec.template.spec 里:
      volumes:
      - name: conf
        configMap: {name: api-conf}
      containers:
      - name: api
        volumeMounts:
        - {name: conf, mountPath: /etc/api}
        # 或用环境变量
        env:
        - {name: LOG_LEVEL, valueFrom: {configMapKeyRef: {name: api-conf, key: log_level}}}
        - {name: DB_PASSWORD, valueFrom: {secretKeyRef: {name: api-secret, key: password}}}
etcd stores Secrets base64-encoded, NOT encrypted by default — anyone with kubectl get secrets -o yaml reads them. Enable encryption at rest, or keep real secrets in an external vault.

The daily debugging loop

Ninety percent of K8s debugging is describe + logs + events, in that order. The Events section of describe tells you why the scheduler, kubelet or the probe controller is unhappy.

kubectl get events --sort-by='.lastTimestamp' -n prod    # 全命名空间事件
kubectl top pod -n prod           # 需要 metrics-server
kubectl logs -f api-7d8b9c-x2k4p --previous   # 看崩之前的日志
kubectl exec -it api-7d8b9c-x2k4p -- sh
kubectl debug -it api-7d8b9c-x2k4p --image=nicolaka/netshoot   # 带工具箱的临时容器
SymptomLook at
Pod 一直 Pendingdescribe Events:资源不足/调度约束/镜像拉不下来
CrashLoopBackOfflogs --previous:应用启动失败的真实报错
就绪探针失败应用日志 + endpoint 是否真的监听
503 时有时无get endpoints:Pod 是否被全数摘除
节点压力kubectl top node + describe node 的 Conditions

Friends & Partners