Kubernetes 进阶实战:监控、配额、健康检查、认证授权、存储与有状态应用全解析
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.cpu 或 requests.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 核心三要素
- Headless Service(
clusterIP: None):为每个 Pod 提供固定 DNS 解析 - VolumeClaimTemplate:为每个 Pod 自动创建独立的 PVC
- 有序部署/更新:按序号顺序操作
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 实测,版本差异请适当调整。
更多推荐

所有评论(0)