|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
 | apiVersion: v1
kind: Pod
metadata:
  name: node-nginx-pod
  labels:
    app: node-nginx
spec:
  volumes:
  - name: node-nginx-volume
    emptyDir:
      # 使用tmpfs
      medium: Memory
      # 必须设置容量限制
      sizeLimit: 1Gi
  containers:
  - name: node
    image: node:v1
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 8080
    # 存活探针和就绪探针在启动探针成功之前不会启动
    # 启动探针,保护启动期的"婴儿阶段",触发容器重启,Java/Python 等慢启动语言
    startupProbe:
      httpGet:
        path: /info
        port: 8080
      failureThreshold: 30     # 最长等待 30*5=150 秒
      periodSeconds: 5
    # 就绪探针,决定是否接收流量,从 Service 摘除流量,慢启动服务、依赖预热
    # 存活/就绪探针必须同时配置
    readinessProbe:
      httpGet:
        path: /info
        port: 8080
      initialDelaySeconds: 5   # 等待时间(冷启动保护),启动 3 秒后开始检测
      periodSeconds: 1         # 检测间隔(频率控制),每隔 1 秒检测
      successThreshold: 3      # 成功确认次数(防误判),连续 3 次成功才标记就绪
    # 存活探针,判断是否该"安乐死",杀死容器并重启,死锁检测、僵尸进程
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 30  # 避免冷启动误杀
      periodSeconds: 5         # 检测间隔(频率控制)
      failureThreshold: 3      # 失败容忍度(防抖动),连续 3 次失败才判定死亡
    resources:
      requests:          # 最低保障资源
        cpu: "500m"      # 0.5 核
        memory: "500Mi"  # 500M 内存
      limits:            # 资源使用天花板
        cpu: "1"         # 1 核 
        memory: "1Gi"    # 1GB 内存
    volumeMounts:
    - name: node-nginx-volume
      mountPath: /opt/share/
  - name: nginx
    image: nginx:1.26.2-alpine-perl
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    resources:
      requests:          # 最低保障资源
        cpu: "500m"      # 0.5 核
        memory: "500Mi"  # 500M 内存
      limits:            # 资源使用天花板
        cpu: "1"         # 1 核 
        memory: "1Gi"    # 1GB 内存
    volumeMounts:
    - name: node-nginx-volume
      mountPath: /opt/share/
---
# headerless Service
apiVersion: v1
kind: Service
metadata:
  name: node-nginx-service
spec:
  #type: NodePort
  # headerless
  clusterIP: None
  selector:
    app: node-nginx
  ports:
    - name: node
      protocol: TCP
      port: 8080         # Service端口
      targetPort: 8080   # Pod端口
      #nodePort: 38080   # 手动指定端口(可选)
    - name: nginx
      protocol: TCP
      port: 80            # Service端口
      targetPort: 80      # Pod端口
      # nodePort: 38080   # 手动指定端口(可选)
# Pod DNS命名规则
# <pod-name>.<service-name>.<namespace>.svc.cluster.local
# node-nginx-service.default.svc.cluster.local
 | 
 
参考 Kubernetes生产级资源管理指南:从QoS到成本优化 博客,若有冒犯或认为侵权,请联系删除更正(写得好,都不需要改)。
| 1
2
3
4
5
6
7
 |     resources:
      requests:          # 最低保障资源
        cpu: "500m"      # 0.5 核
        memory: "500Mi"  # 500M 内存
      limits:            # 资源使用天花板
        cpu: "1"         # 1 核 
        memory: "1Gi"    # 1GB 内存
 | 
 
| 资源类型 | 单位格式 | 示例 | 实际含义 | 
| CPU | 毫核(m) | 500m | 0.5个CPU核心 | 
| 内存 | 二进制单位(Mi) | 4096Mi | 4GB内存 | 
QoS三级管控体系
等级对比矩阵:
| QoS等级 | 配置特征 | 调度优先级 | 驱逐顺序 | 适用场景 | 
| Guaranteed(专用区) | requests == limits | 最高 | 最后 | 数据库/支付核心 | 
| Burstable(共享池) | requests < limits | 中等 | 中间 | 业务应用 | 
| BestEffort(剩余空间) | 未设置 requests/limits | 最低 | 最先 | 日志收集 | 
常见问题排查
| 1
2
3
4
5
6
7
8
 | # 查看资源使用情况
kubectl top pods --sort-by=memory
# 检查Pod驱逐原因
kubectl get events --field-selector=reason=Evicted
# 诊断OOM事件
journalctl -k | grep -i 'oom'
 | 
 
资源优化公式
| 1
2
 | 理想requests = 第95百分位用量 × 1.2
合理limits = requests × 2 (内存), requests × 3 (CPU)
 | 
 
关键服务配置
| 1
2
3
4
5
6
7
8
9
 | # 数据库 Pod 示例
# Guaranteed 等级
resources:
  requests:
    cpu: "4"
    memory: "16Gi"
  limits:
    cpu: "4" 
    memory: "16Gi"
 | 
 
弹性应用配置
| 1
2
3
4
5
6
7
8
9
 | # Web 服务 Pod 示例
# Burstable 等级
resources:
  requests:
    cpu: "500m"
    memory: "2Gi"
  limits:
    cpu: "2"
    memory: "4Gi"
 | 
 
批量任务配置
| 1
2
3
 | # 日志处理 Job 示例
# BestEffort 等级
resources: {}
 | 
 
这块儿也是参考大佬 Kubernetes探针全解 博客讲解,若有冒犯或认为侵权,请联系删除更正(写得好,都不需要改)。
注意: 存活探针和就绪探针在启动探针成功之前不会启动
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 |     # 存活探针和就绪探针在启动探针成功之前不会启动
    # 启动探针,保护启动期的"婴儿阶段",触发容器重启,Java/Python 等慢启动语言
    startupProbe:
      httpGet:
        path: /info
        port: 8080
      failureThreshold: 30     # 最长等待 30*5=150 秒
      periodSeconds: 5
    # 就绪探针,决定是否接收流量,从 Service 摘除流量,慢启动服务、依赖预热
    # 存活/就绪探针必须同时配置
    readinessProbe:
      httpGet:
        path: /info
        port: 8080
      initialDelaySeconds: 5   # 等待时间(冷启动保护),启动 3 秒后开始检测
      periodSeconds: 1         # 检测间隔(频率控制),每隔 1 秒检测
      successThreshold: 3      # 成功确认次数(防误判),连续 3 次成功才标记就绪
    # 存活探针,判断是否该"安乐死",杀死容器并重启,死锁检测、僵尸进程
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
      initialDelaySeconds: 30  # 避免冷启动误杀
      periodSeconds: 5         # 检测间隔(频率控制)
      failureThreshold: 3      # 失败容忍度(防抖动),连续 3 次失败才判定死亡
 | 
 
github 下载链接,加速下载链接,自提本地下载链接
修改镜像 [registry.k8s.io/metrics-server/metrics-server:v0.7.2] 为加速镜像 [swr.cn-north-4.myhuaweicloud.com/ddn-k8s/registry.k8s.io/metrics-server/metrics-server:v0.7.2]
添加/编辑参数:
| 1
2
 | - --kubelet-insecure-tls
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname,InternalDNS,ExternalDNS
 | 
 
- 
- --kubelet-insecure-tls添加参数,不验证 https 证书
 
- 
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname,InternalDNS,ExternalDNS修改此参数,metrics 按照指定的顺序连接 kubelet
 
- 
InternalIP: Kubelet 的内部 IP 地址
 
- 
Hostname: Kubelet 的主机名
 
- 
InternalDNS: Kubelet 的内部 DNS 名称
 
- 
ExternalDNS: Kubelet 的外部 DNS 名称
 
- 
ExternalIP: Kubelet 的外部 IP 地址
 
部署 metrics server
| 1
 | kubectl create -f metrics-server_v0.7.2.yaml
 | 
 
验证 metrics 服务是否部署成功
| 1
 | kubectl get pods -n kube-system -l k8s-app=metrics-server
 | 
 
查看 pod 和 node 的资源使用情况
| 1
2
3
4
5
6
 | # 查看节点资源使用情况
kubectl top node
# 查看Pod资源使用情况
kubectl top pod
# 查看指定命名空间的 pod 资源使用情况
kubectl top pod -n kube-system
 | 
 
参考 Kubernetes 水平自动扩缩参考文档
合理设置冷却时间:避免频繁扩缩容
| 1
2
3
4
5
6
 | # 调整扩缩容延迟
behavior:
  scaleDown:
    stabilizationWindowSeconds: 300  # 缩容冷却 5 分钟
  scaleUp:
    stabilizationWindowSeconds: 60   # 扩容冷却 1 分钟
 | 
 
在 HPA Spec 下 behavior 字段,下面有 scaleUp 和 scaleDown 两个字段分别控制扩容和缩容的行为
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 | apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: app-hpa
spec:
  minReplicas: 2
  maxReplicas: 10
  # 监控的指标数组,支持多种类型的指标共存
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  # HPA 伸缩对象描述,HPA 会动态修改该对象的 Pod 数量
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: app
  behavior: # 这里是重点
    scaleDown:
      stabilizationWindowSeconds: 300 # 需要缩容时,先观察 5 分钟,如果一直持续需要缩容才执行缩容
      policies:
      - type: Percent
        value: 100 # 允许全部缩掉
        periodSeconds: 15
    scaleUp:
      stabilizationWindowSeconds: 0 # 需要扩容时,立即扩容,扩容前等待的时间窗口
      selectPolicy: Max # 使用以上两种扩容策略中算出来扩容 Pod 数量最大的
      policies:
      - type: Percent
        value: 100
        periodSeconds: 15 # 每 15s 最大允许扩容当前 1 倍数量的 Pod
      - type: Pods
        value: 4
        periodSeconds: 15 # 每 15s 最大允许扩容 4 个 Pod
 | 
 
- 以上 behavior配置是默认的,即如果不配置,会默认加上。
- scaleUp和- scaleDown都可以配置1个或多个策略,最终扩缩时用哪个策略,取决于- selectPolicy。
- selectPolicy默认是- Max,即扩缩时,评估多个策略算出来的结果,最终选取扩缩 Pod 数量最多的那个策略的结果。
- stabilizationWindowSeconds是稳定窗口时长,即需要指标高于或低于阈值,并持续这个窗口的时长才会真正执行扩缩,以防止抖动导致频繁扩缩容。扩容时,稳定窗口默认为0,即立即扩容;缩容时,稳定窗口默认为5分钟。
- policies中定义扩容或缩容策略,- type的值可以是- Pods或- Percent,表示每- periodSeconds时间范围内,允许扩缩容的最大副本数或比例。
pod 配置示例
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
 | apiVersion: apps/v1
kind: Deployment
metadata:
  name: jdk-app-deployment
  labels:
    app: jdk-app
spec:
  selector:
    matchLabels:
      app: jdk-app
  replicas: 2
  template:
    metadata:
      name: jdk-app
      labels:
        app: jdk-app
    spec:
      containers:
      - name: jdk-app-pod
        image: app-jdk-8u421-debian-12.10:v1
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 31808
        resources:
          requests:
            cpu: "500m"
            memory: "500Mi"
          limits:
            cpu: "500m"
            memory: "500Mi"
        # 存活探针和就绪探针在启动探针成功之前不会启动
        # 启动探针,保护启动期的"婴儿阶段",触发容器重启,Java/Python 等慢启动语言
        startupProbe:
          httpGet:
            path: /ip
            port: 31808
          # 最长等待 30*5=150 秒
          failureThreshold: 30
          periodSeconds: 5
        # 就绪探针,决定是否接收流量,从 Service 摘除流量,慢启动服务、依赖预热
        # 存活/就绪探针必须同时配置
        readinessProbe:
          httpGet:
            path: /ip
            port: 31808
          initialDelaySeconds: 10   # 等待时间(冷启动保护),启动 3 秒后开始检测
          periodSeconds: 1         # 检测间隔(频率控制),每隔 1 秒检测
          successThreshold: 3      # 成功确认次数(防误判),连续 3 次成功才标记就绪
        # 存活探针,判断是否该"安乐死",杀死容器并重启,死锁检测、僵尸进程
        livenessProbe:
          httpGet:
            path: /ip
            port: 31808
          initialDelaySeconds: 30  # 避免冷启动误杀
          periodSeconds: 5         # 检测间隔(频率控制)
          failureThreshold: 3      # 失败容忍度(防抖动),连续 3 次失败才判定死亡
---
apiVersion: v1
kind: Service
metadata:
  name: jdk-app-service
spec:
  #clusterIP: None
  type: NodePort
  selector:
    app: jdk-app
    release: v1
  ports:
    - name: jdk-app-port
      protocol: TCP
      port: 31808
      targetPort: 31808
 | 
 
hpa 配置示例
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 | apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: jdk-app-hpa
spec:
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 60
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: jdk-app-deployment
  behavior:
    scaleDown:
      # 需要缩容时,先观察 5 分钟,如果一直持续需要缩容才执行缩容
      stabilizationWindowSeconds: 30
      policies:
      - type: Percent
        # 允许全部缩掉
        value: 100
        periodSeconds: 15
    scaleUp:
      # 需要扩容时,立即扩容,扩容前等待的时间窗口
      stabilizationWindowSeconds: 0
      policies:
      - type: Percent
        value: 100
        # 每 15s 最大允许扩容当前 1 倍数量的 Pod
        periodSeconds: 15
      - type: Pods
        value: 2
        # 每 15s 最大允许扩容 4 个 Pod
        periodSeconds: 15
      # 使用以上两种扩容策略中算出来扩容 Pod 数量最大的
      selectPolicy: Max
 | 
 
查看节点标签
| 1
2
3
4
5
 | # 查看节点标签
kubectl get nodes --show-labels
# 给指定节点打上标签
kubectl label nodes <your-node-name> disktype=ssd
 | 
 
亲和性调度POD:节点亲和性配置  requiredDuringSchedulingIgnoredDuringExecution, 这意味着 pod 只会被调度到具有 disktype=ssd 标签的节点上。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
 | apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd            
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
 | 
 
节点亲和性调度 Pod:节点亲和性设置 preferredDuringSchedulingIgnoredDuringExecution ,这意味着 Pod 将首选具有 disktype=ssd 标签的节点。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
 | apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disktype
            operator: In
            values:
            - ssd          
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
 | 
 
Pod 会被调度到标签为 role 不等于 database 的节点上。
|  1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 | apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - matchExpressions:
        - key: role
          operator: In
          values:
          - database
 |