Kubernetes 进阶实战:监控、配额、健康检查、认证授权、存储与有状态应用全解析

一份涵盖 Metrics Server、HPA、ResourceQuota、LimitRange、健康探针、RBAC、Dashboard、动态存储和 StatefulSet 的完整学习笔记


写在前面

在前面的文章中,我们已经完成了 Kubernetes 集群的部署、核心控制器(Deployment/DaemonSet/Job)的学习以及网络策略和调度的深入探讨。今天这篇文章是 Kubernetes 进阶知识的集大成者,内容覆盖了生产环境中至关重要的几个方面:

  • 监控与扩缩容:Metrics Server + HPA(水平 Pod 自动扩缩容)
  • 资源管控:ResourceQuota(资源配额)和 LimitRange(限制范围)
  • 应用自愈:LivenessProbe、ReadinessProbe 健康检查
  • 安全体系:认证(Authentication)与 RBAC 授权(Authorization)
  • 管理界面:Kubernetes Dashboard 部署与使用
  • 存储进阶:动态卷供应(Local Path、NFS Provisioner)
  • 有状态应用:StatefulSet 实战(Nginx、Etcd、Redis、MySQL)

这是一篇 非常硬核的长文,建议收藏后慢慢消化。所有 YAML 和命令均基于 K8s v1.30 实测。


一、Metrics Server 与 HPA:自动扩缩容的基石

1.1 部署 Metrics Server

Metrics Server 是 Kubernetes 内置的资源指标采集器,它从 kubelet 收集 CPU 和内存使用数据,通过 Metrics API 暴露给 kubectl top 和 HPA。

# 下载部署文件
wget https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.1/components.yaml

# 添加 --kubelet-insecure-tls(因自签名证书)
sed -i '/metric-resolution/a\        - --kubelet-insecure-tls' components.yaml

kubectl apply -f components.yaml

验证部署:

kubectl top node
kubectl top pods -n kube-system

1.2 HPA 基于 CPU 自动扩缩容

创建一个 Deployment 并配置 HPA:

kubectl create deployment web --image=nginx
kubectl autoscale deployment web --max=5 --min=2 --cpu-percent=80

关键前提:Pod 必须设置 resources.limits.cpu,否则 HPA 无法计算利用率。

resources:
  limits:
    cpu: 100m
    memory: 200Mi

压力测试

# 安装压测工具
apt install -y apache2-utils

# 压测(替换为 Service IP)
while true; do ab -n 300000 -c 100 http://<service-ip>/; sleep 1; done

观察 HPA 逐步扩容到最大副本数:

watch 'kubectl get hpa; echo; kubectl top pods'

1.3 HPA 基于内存自动扩缩容

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  minReplicas: 2
  maxReplicas: 5
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  metrics:
  - resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 60
    type: Resource

注意:内存扩缩容需要 Pod 内存使用率持续高于阈值才会触发,且缩容有 5 分钟冷却期(--horizontal-pod-autoscaler-downscale-stabilization)。

1.4 扩容/缩容时间参数调优

修改 kube-controller-manager 静态 Pod 参数:

# /etc/kubernetes/manifests/kube-controller-manager.yaml
- --horizontal-pod-autoscaler-sync-period=10s          # 采样周期,默认15s
- --horizontal-pod-autoscaler-initial-readiness-delay=20s  # 启动就绪窗口,默认30s
- --horizontal-pod-autoscaler-downscale-stabilization=60s  # 缩容冷却,默认5min

二、ResourceQuota 与 LimitRange:资源管控

2.1 ResourceQuota:命名空间资源配额

ResourceQuota 限制一个命名空间内资源的总量(如 Pod 数量、CPU/内存总量)。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: myquota
spec:
  hard:
    pods: "10"
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    persistentvolumeclaims: "5"

重要规则:一旦命名空间设置了 requests.cpurequests.memory 配额,该命名空间下的所有 Pod 必须显式指定 requests 和 limits,否则创建被拒绝。

# 测试:不指定 resources 的 Pod
kubectl run web --image=nginx
# Error from server (Forbidden): ... must specify limits.cpu, limits.memory, requests.cpu, requests.memory

2.2 LimitRange:默认资源限制

LimitRange 为命名空间内的 Pod/容器设置默认的 requests/limits 以及最小/最大值约束。

apiVersion: v1
kind: LimitRange
metadata:
  name: mylimit
spec:
  limits:
  - type: Container
    max:
      cpu: 1
      memory: 1Gi
    min:
      cpu: 100m
      memory: 128Mi
    default:
      cpu: 500m
      memory: 512Mi
    defaultRequest:
      cpu: 200m
      memory: 256Mi

约束关系min <= defaultRequest <= default <= max

验证:创建未指定 resources 的 Pod,查看其自动注入的值:

kubectl get pod web -o yaml | grep -A5 resources

三、健康检查:LivenessProbe 与 ReadinessProbe

3.1 为什么需要健康检查?

没有健康检查时,即使容器内应用崩溃(如删除了 index.html),Pod 状态依然是 Running,流量仍会被转发,导致服务不可用。

3.2 三种探针类型

探针 作用 失败后果
LivenessProbe 判断容器是否存活 重启容器
ReadinessProbe 判断容器是否就绪可接收流量 从 Service Endpoints 中摘除
StartupProbe 判断慢启动容器是否完成初始化 重启容器(期间禁用其他探针)

3.3 HTTP 探针(最常用)

livenessProbe:
  httpGet:
    path: /index.html
    port: 80
    scheme: HTTP
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 3
  timeoutSeconds: 10

验证 LivenessProbe:删除主页文件后,容器会被重启。

验证 ReadinessProbe:删除某 Pod 的主页文件,该 Pod 的 READY 状态变为 0/1,且从 Service Endpoints 中移除。

3.4 Exec 探针

在容器内执行命令,返回 0 表示成功:

livenessProbe:
  exec:
    command:
    - cat
    - /tmp/healthy

3.5 TCP 探针

尝试建立 TCP 连接,成功则视为健康:

livenessProbe:
  tcpSocket:
    port: 80

3.6 滚动更新中的应用

在滚动更新时,ReadinessProbe 可以防止流量被路由到尚未就绪的新 Pod,避免服务中断。


四、认证与 RBAC 授权

4.1 Kubernetes API 访问控制链路

客户端请求 → 传输安全(TLS) → 认证(Authentication) → 鉴权(Authorization) → 准入控制(Admission) → 存储

4.2 认证方式

Kubernetes 支持多种认证插件:

  • X509 客户证书(最常用,kubeconfig 默认)
  • 服务账号令牌(Pod 访问 API)
  • 静态令牌文件(已废弃)
  • 启动引导令牌(kubeadm 使用)
  • Webhook 令牌认证

4.3 创建用户(X509 证书方式)

客户端生成私钥和 CSR:

openssl genrsa -out laoma.key 2048
openssl req -new -key laoma.key -out laoma.csr -subj '/CN=laoma/O=kubernets'

管理员签发证书:

openssl x509 -req -in laoma.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out laoma.crt -days 1095

客户端构建 kubeconfig:

kubectl config set-cluster kubernetes --kubeconfig=config --certificate-authority=ca.crt --embed-certs --server=https://10.1.8.30:6443
kubectl config set-credentials laoma --kubeconfig=config --client-key=laoma.key --client-certificate=laoma.crt --embed-certs
kubectl config set-context laoma --kubeconfig=config --cluster=kubernetes --user=laoma
kubectl config use-context laoma --kubeconfig=config

4.4 RBAC 授权模型

RBAC 的核心四要素:

资源 作用域 说明
Role 命名空间 定义某命名空间内的权限
ClusterRole 集群 定义集群范围的权限
RoleBinding 命名空间 将 Role 绑定到用户/组/SA
ClusterRoleBinding 集群 将 ClusterRole 绑定到用户/组/SA

4.5 常用预定义 ClusterRole

ClusterRole 权限范围
view 只读权限(get/list/watch)
edit 读写权限(不含 RBAC 和 Secret)
admin 命名空间内所有权限
cluster-admin 集群所有权限

4.6 实战:创建 Role 并绑定

创建 Role(auth 命名空间):

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: auth
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]

绑定到用户 laoma:

kubectl create rolebinding laoma-pod-reader --role=pod-reader --user=laoma -n auth

验证

kubectl get pods -n auth --kubeconfig=config

4.7 服务账号(ServiceAccount)

Pod 使用 ServiceAccount 身份访问 API。每个命名空间默认有一个 default SA。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-sa
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: my-sa-admin
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: my-sa
  namespace: default

Pod 使用指定 SA:

spec:
  serviceAccountName: my-sa

创建临时令牌(v1.22+ 推荐):

kubectl create token my-sa

五、Kubernetes Dashboard

5.1 部署 Dashboard

wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.6.1/aio/deploy/recommended.yaml
kubectl apply -f recommended.yaml

5.2 暴露访问

将 Service 改为 NodePort 类型:

kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
# 修改 type: NodePort

获取访问端口:

kubectl get svc -n kubernetes-dashboard

5.3 创建管理员 Token

apiVersion: v1
kind: ServiceAccount
metadata:
  name: admin-user
  namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: admin-user
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- kind: ServiceAccount
  name: admin-user
  namespace: kubernetes-dashboard

获取 Token:

kubectl -n kubernetes-dashboard create token admin-user

使用 Token 登录 Dashboard(Bearer Token 方式)。


六、动态卷供应(Dynamic Provisioning)

6.1 什么是动态卷供应?

传统方式需要管理员预先创建 PV(静态供应)。动态供应通过 StorageClass 自动创建 PV,用户只需创建 PVC 即可。

6.2 Local Path Provisioner(本地存储)

适用于使用节点本地磁盘的场景。

wget https://github.com/rancher/local-path-provisioner/blob/v0.0.35/deploy/local-path-storage.yaml
kubectl apply -f local-path-storage.yaml

验证:

kubectl get sc local-path
# 输出: local-path   rancher.io/local-path   Delete   WaitForFirstConsumer

创建 PVC 和 Pod 测试:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: local-path-pvc
spec:
  accessModes: ["ReadWriteOnce"]
  resources:
    requests:
      storage: 5Gi
  storageClassName: local-path

6.3 NFS Provisioner(网络存储)

适合多节点共享存储的场景。

部署 NFS 服务器

apt install -y nfs-kernel-server
mkdir -m 777 /shares
echo "/shares *(rw,sync,no_root_squash)" >> /etc/exports
systemctl restart nfs-server

部署 NFS Provisioner

# 创建 RBAC、Deployment、StorageClass(参考完整 YAML)
kubectl apply -f nfs-provisioner.yaml

StorageClass 示例

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-storage
provisioner: fuseim.pri/ifs
reclaimPolicy: Delete
volumeBindingMode: Immediate

使用方式与 Local Path 类似,只需指定 storageClassName: nfs-storage


七、StatefulSet:有状态应用管理

7.1 StatefulSet vs Deployment

特性 StatefulSet Deployment
Pod 名称 固定序号(web-0, web-1…) 随机后缀
网络标识 Headless Service + 固定 DNS 共享 Service
存储 PVC 模板,每个 Pod 独立 PVC 共享或不使用 PVC
启停顺序 有序(0→N 启动,N→0 停止) 无序
适用场景 数据库、消息队列、分布式系统 无状态 Web/API

7.2 StatefulSet 核心三要素

  1. Headless ServiceclusterIP: None):为每个 Pod 提供固定 DNS 解析
  2. VolumeClaimTemplate:为每个 Pod 自动创建独立的 PVC
  3. 有序部署/更新:按序号顺序操作

7.3 实战:部署 Nginx StatefulSet

创建 Headless Service

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  clusterIP: None
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80

创建 StatefulSet

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: nginx
spec:
  serviceName: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: nginx-data
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates:
  - metadata:
      name: nginx-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: nfs-storage
      resources:
        requests:
          storage: 10Gi

验证固定 DNS:

kubectl run test --image=busybox -it --rm -- sh
/ # curl nginx-0.nginx
/ # curl nginx-1.nginx

7.4 实战:部署 Etcd 集群

Etcd 是典型的有状态分布式协调服务,3 节点集群:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: etcd
spec:
  serviceName: etcd
  replicas: 3
  selector:
    matchLabels:
      app: etcd
  template:
    metadata:
      labels:
        app: etcd
    spec:
      containers:
      - name: etcd
        image: registry.aliyuncs.com/google_containers/etcd:3.5.10-0
        env:
        - name: ETCD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: ETCD_INITIAL_CLUSTER
          value: "etcd-0=http://etcd-0.etcd:2380,etcd-1=http://etcd-1.etcd:2380,etcd-2=http://etcd-2.etcd:2380"
        # ... 其他环境变量
        volumeMounts:
        - name: etcd-data
          mountPath: /var/lib/etcd
  volumeClaimTemplates:
  - metadata:
      name: etcd-data
    spec:
      accessModes: ["ReadWriteOnce"]
      storageClassName: nfs-storage
      resources:
        requests:
          storage: 10Gi

验证集群状态:

kubectl exec etcd-0 -- etcdctl member list
kubectl exec etcd-0 -- etcdctl put /test key value
kubectl exec etcd-2 -- etcdctl get /test key

7.5 实战:部署 Redis 主从集群

一个包含 1 主 2 从的 Redis 集群,使用 Sentinel 实现高可用。核心配置:

spec:
  containers:
  - name: redis
    image: redis:7.0-alpine
    command: ["/bin/sh", "-c"]
    args:
    - |
      NODE_ID=$(hostname | awk -F'-' '{print $2}')
      # 配置主从
      if [ "$NODE_ID" != "0" ]; then
        echo "replicaof redis-0.redis 6379" >> /data/redis.conf
      fi
      # 启动 Redis
      redis-server /data/redis.conf &
      
      # 配置 Sentinel
      cat > /data/sentinel.conf << EOF
      sentinel monitor mymaster redis-0.redis 6379 2
      sentinel auth-pass mymaster redis123
      EOF
      redis-sentinel /data/sentinel.conf

验证故障切换

# 删除主节点
kubectl delete pod redis-0

# 等待重建后查看角色
kubectl exec redis-0 -- redis-cli -a redis123 info replication
# 预期:role:slave(另一个节点已升为主)

八、总结与避坑指南

核心知识点速查表

组件 用途 关键命令/文件
Metrics Server 资源监控 kubectl top node/pod
HPA 自动扩缩容 kubectl autoscale
ResourceQuota 命名空间资源限额 kubectl get quota
LimitRange 默认资源限制 kubectl get limitrange
健康探针 应用自愈和流量管理 livenessProbe/readinessProbe
RBAC 权限控制 Role/ClusterRole + Binding
StorageClass 动态卷供应 provisioner + parameters
StatefulSet 有状态应用 Headless Service + PVC 模板

常见问题与解决方案

问题 解决方案
kubectl top 报错 检查 Metrics Server 是否 Running,添加 --kubelet-insecure-tls
HPA 不生效 确认 Pod 已设置 resources.limits
Pod 创建被拒绝(配额) 检查 ResourceQuota,确保 Pod 指定了 requests/limits
StatefulSet Pod 启动顺序乱 检查 Headless Service 配置是否正确
PVC 一直 Pending 检查 StorageClass 是否存在,PV 是否满足 PVC 要求
RBAC 权限不生效 确认 RoleBinding 的 namespace 与用户操作的 namespace 一致

写在最后

这篇文章从 监控扩缩容资源管控,从 健康检查认证授权,再到 动态存储有状态应用,涵盖了 Kubernetes 生产环境中最重要的进阶主题。这些知识是 CKA/CKAD 考试的高频考点,也是实际运维中的必备技能。

如果你一路看到这里,相信你对 Kubernetes 的理解已经上了一个新台阶。后续可以继续深入:

  • Service Mesh(Istio/Linkerd)
  • GitOps(ArgoCD/Flux)
  • 多集群管理(Karmada/Federation)

觉得有帮助的话,欢迎点赞、收藏、转发!


本文所有 YAML 和命令均基于 Kubernetes v1.30 + containerd + Calico 实测,版本差异请适当调整。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐