Lesson 0015:K8s 网络与配置——Ingress、ConfigMap、Secret、Volume

← Lesson 0014 讲了 Pod、Deployment、Service。这课解决:「外部怎么访问?」「配置怎么管?」「数据怎么存?」

1. Ingress——外部流量的入口

Service 的 NodePort 只在开发环境用。生产用 Ingress——相当于 K8s 里的 Nginx 反向代理。

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
    - host: example.com                # 域名
      http:
        paths:
          - path: /api
            pathType: Prefix
            backend:
              service:
                name: api-svc          # 指向 api Service
                port:
                  number: 80
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-svc          # 指向 web Service
                port:
                  number: 80
  tls:
    - hosts:
        - example.com
      secretName: example-tls          # TLS 证书存在 Secret 里

Ingress 需要 Ingress Controller 才能工作(如 nginx-ingress、traefik)。云 K8s 通常自带。

2. ConfigMap——非敏感配置

# 从字面量创建
kubectl create configmap app-config \
  --from-literal=LOG_LEVEL=debug \
  --from-literal=API_URL=https://api.example.com

# 从文件创建
kubectl create configmap nginx-config --from-file=nginx.conf

# 在 Deployment 里使用
spec:
  containers:
    - name: app
      image: my-app
      envFrom:
        - configMapRef:
            name: app-config           # 所有 key 变成环境变量
      # 或挂载为文件
      volumeMounts:
        - name: nginx-conf
          mountPath: /etc/nginx/conf.d
  volumes:
    - name: nginx-conf
      configMap:
        name: nginx-config

3. Secret——敏感配置

# 创建 Secret(数据要 base64 编码)
kubectl create secret generic db-secret \
  --from-literal=DB_PASSWORD=s3cret!

# 或者从文件
echo -n "s3cret!" | kubectl create secret generic db-secret --from-file=password=/dev/stdin

# 使用方式和 ConfigMap 一样,只是数据在 etcd 里加密存储
spec:
  containers:
    - name: app
      env:
        - name: DB_PASSWORD
          valueFrom:
            secretKeyRef:
              name: db-secret
              key: password
K8s Secret 默认只是 base64 编码,不是加密!任何人能看到 Secret YAML 就能解码。生产环境用 Sealed Secrets、External Secrets Operator 或 Vault。

4. Volume & PVC——持久化存储

Pod 里的文件是临时的。数据库数据需要持久化→用 PersistentVolume (PV) + PersistentVolumeClaim (PVC)。

# pvc.yaml —— 申请存储(类似「我要 10GB 的 SSD」)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: db-pvc
spec:
  accessModes:
    - ReadWriteOnce            # 单个 Pod 读写
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard   # 云厂商自动创建 PV

---
# Deployment 中使用 PVC
spec:
  containers:
    - name: postgres
      image: postgres:16
      volumeMounts:
        - name: db-data
          mountPath: /var/lib/postgresql/data
  volumes:
    - name: db-data
      persistentVolumeClaim:
        claimName: db-pvc

5. 资源限制——防止一个 Pod 吃光所有资源

spec:
  containers:
    - name: app
      image: my-app
      resources:
        requests:               # 调度保证(至少分配这么多)
          memory: "128Mi"
          cpu: "100m"           # 100 millicores = 0.1 CPU
        limits:                 # 硬上限(绝对不能超过)
          memory: "256Mi"       # 超过 → OOMKilled
          cpu: "500m"           # 超过 → throttled(被限速,不会被杀)

requests vs limits:requests 决定 Pod 调度到哪个 Node(Node 要有足够资源)。limits 是运行时天花板。

6. Probes——健康检查

spec:
  containers:
    - name: app
      image: my-app
      livenessProbe:               # 「还活着吗?」→ 失败就重启
        httpGet:
          path: /healthz
          port: 3000
        initialDelaySeconds: 10    # 启动等 10 秒再开始检查
        periodSeconds: 15          # 每 15 秒检查一次
        failureThreshold: 3        # 连续失败 3 次才重启

      readinessProbe:              # 「能接流量了吗?」→ 失败就摘除
        httpGet:
          path: /ready
          port: 3000
        initialDelaySeconds: 5
        periodSeconds: 10

      startupProbe:                # 启动完成了吗?(启动慢的应用专用)
        httpGet:
          path: /startup
          port: 3000
        failureThreshold: 30       # 最多等 30×10s=300s
        periodSeconds: 10
Probe作用失败后果
livenessProbe容器是否还活着kubelet 杀掉容器重建
readinessProbe容器能否接请求从 Service 摘除,不杀
startupProbe启动是否完成启动期间 disable liveness+readiness

小测验

Q1:livenessProbe 和 readinessProbe 的关键区别?
Q2:ConfigMap 和 Secret 的主要区别?
Q3:memory limits 设置 256Mi,容器用到了 300Mi,会发生什么?

下一步

Lesson 0016:K8s 生产实践 →——Helm、HPA、RBAC、监控集成。Plan A 最后一课。

← Lesson 0014 · Lesson 0016 →