kubernetes pod 推荐配置

kubernetes pod|pod 推荐配置

Kubernetes 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
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 字段,下面有 scaleUpscaleDown 两个字段分别控制扩容和缩容的行为

 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 配置是默认的,即如果不配置,会默认加上。
  • scaleUpscaleDown 都可以配置1个或多个策略,最终扩缩时用哪个策略,取决于 selectPolicy
  • selectPolicy 默认是 Max,即扩缩时,评估多个策略算出来的结果,最终选取扩缩 Pod 数量最多的那个策略的结果。
  • stabilizationWindowSeconds 是稳定窗口时长,即需要指标高于或低于阈值,并持续这个窗口的时长才会真正执行扩缩,以防止抖动导致频繁扩缩容。扩容时,稳定窗口默认为0,即立即扩容;缩容时,稳定窗口默认为5分钟。
  • policies 中定义扩容或缩容策略,type 的值可以是 PodsPercent,表示每 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

相关内容