K8S R&D: Kubernetes从核心调度到故障排查、网络优化与日志收集指南

Kubernetes调度机制

Kubernetes通过调度器(Scheduler)管理Pod与Node的匹配,核心调度方式如下:

1 ) 预选(Predicates)与优选(Priorities)机制

  • 预选:基于硬性条件(如CPU/内存余量、端口冲突)过滤不符合要求的Node

    yaml 复制代码
    # 资源请求示例
    resources:
      requests:
        memory: "128Mi"
        cpu: "250m"
  • 优选:在预选基础上通过算法(如LeastRequestedPriority)优化负载均衡

  • 技术细节:PodFitsResources过滤资源不足节点;SelectorSpreadPriority分散多副本Pod

2 ) 标签选择器(nodeSelector)

为Node打标签(如disk=ssd),在Pod中定向调度:

yaml 复制代码
spec:
  nodeSelector:
    disk: ssd 

3 ) 节点亲和性(nodeAffinity)

支持软硬策略:

  • 硬策略(requiredDuringSchedulingIgnoredDuringExecution):必须满足条件
  • 软策略(preferredDuringSchedulingIgnoredDuringExecution):优先满足

示例1:

yaml 复制代码
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.kubernetes.io/zone 
          operator: In 
          values: [zone-a]
    preferredDuringSchedulingIgnoredDuringExecution:  # 软策略 
    - weight: 1 
      preference:
        matchExpressions:
        - key: gpu 
          operator: In
          values: ["nvidia"]

示例2:

yaml 复制代码
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:  # 硬策略 
      nodeSelectorTerms:
      - matchExpressions:
        - key: gpu-type
          operator: In 
          values: ["a100"]
    preferredDuringSchedulingIgnoredDuringExecution:  # 软策略 
    - weight: 1
      preference:
        matchExpressions:
        - key: zone
          operator: In 
          values: ["us-west1-a"]

Node节点故障排查(断电场景)

当Node断电恢复后Pod无法启动,按以下步骤排查:

1 ) 检查污点(Taint)状态

Node异常时自动添加node.kubernetes.io/unreachable污点,恢复后手动删除:

bash 复制代码
kubectl describe node <node-name> | grep Taints  # 检查污点 
kubectl taint nodes <node-name> node.kubernetes.io/unreachable:NoSchedule- # 手动删除

2 )验证主机名与kubelet服务

  • 主机名不一致导致失联:

    bash 复制代码
    hostnamectl  # 验证主机名
    systemctl status kubelet | grep hostname  # 检查配置一致性
  • 重启服务并检查日志:

    bash 复制代码
    systemctl restart kubelet && systemctl restart docker && systemctl status kubelet  # 重启服务 
    journalctl -u kubelet -n 100 --no-pager | grep -E 'error|fail'

3 ) 确认Node资源状态

检查资源耗尽情况:

bash 复制代码
# 若Node处于`NotReady`,检查资源是否耗尽(如`kubectl describe node <node-name>`中的`Conditions`字段)
kubectl describe node <node-name> | grep -A 5 Conditions # 查看Conditions字段 
kubectl top nodes  # 查看资源使用 

Pod资源超限故障处理

故障类型 检测方法 解决方案
Pod数量超限 kubectl describe node 查看Allocatable 修改kubelet参数:--max-pods=150 或扩展集群节点 kubectl scale deployment <name> --replicas=5
容器资源超主机容量 对比Pod的limits与节点资源 调整资源配置: resources.limits.memory: "4Gi"
宿主机资源不足 kubectl top nodes 扩容工作节点或优化现有工作负载

Pod资源配置超过宿主机容量

示例:宿主机内存5Gi,但Pod申请6Gi。需调整YAML中的resources限制:

yaml 复制代码
# 资源限制正确配置示例
containers:
- name: app-container 
  resources:
    limits:
      cpu: "2"
      memory: "4Gi"
    requests:
      cpu: "1"
      memory: "2Gi"

宿主机资源不足

直接扩容Node或迁移Pod至新节点

Pod自动扩缩容策略

类型 机制 适用场景 配置示例
HPA 基于CPU/内存指标扩缩副本 流量波动大的无状态应用 kubectl autoscale deployment nginx --cpu-percent=80 --min=2 --max=10
KPA 基于HTTP请求量扩缩容 请求驱动型服务(如Serverless) 无需CPU指标,依赖Knative框架实现
VPA 动态调整Pod资源请求量 资源需求周期性变化的应用 yaml<br>apiVersion: autoscaling.k8s.io/v1<br>kind: VerticalPodAutoscaler<br>spec:<br> targetRef:<br> name: my-app

技术细节:HPA依赖Metrics Server;VPA避免与HPA混用导致冲突

yaml 复制代码
# HPA配置示例 
apiVersion: autoscaling/v2 
kind: HorizontalPodAutoscaler 
spec:
  scaleTargetRef:
    kind: Deployment 
    name: myapp 
  minReplicas: 2 
  maxReplicas: 10 
  metrics:
  - type: Resource 
    resource:
      name: cpu 
      target:
        type: Utilization 
        averageUtilization: 80 
 
# VPA配置示例 
apiVersion: autoscaling.k8s.io/v1 
kind: VerticalPodAutoscaler 
spec:
  targetRef:
    kind: Deployment
    name: my-app

三种核心扩缩容机制

  1. HPA(水平Pod扩缩容)

    基于CPU/内存等指标动态调整副本数

    bash 复制代码
    kubectl autoscale deployment nginx --cpu-percent=80 --min=2 --max=10 
  2. KPA(Knative扩缩容)

    根据HTTP请求量自动扩缩,适用于Serverless场景

  3. VPA(垂直Pod扩缩容)

    自动调整Pod资源请求量,保持资源配置比例

    yaml 复制代码
    apiVersion: autoscaling.k8s.io/v1 
    kind: VerticalPodAutoscaler 
    spec:
      targetRef:
        apiVersion: "apps/v1"
        kind: Deployment
        name: my-app

Service访问异常排查

不匹配 匹配 异常 正常 无 有 Service访问异常 标签匹配检查 修正selector标签 kube-proxy状态 重启kube-proxy服务 Endpoint是否存在 检查Pod就绪状态 检查网络插件

关键命令:

bash 复制代码
kubectl get endpoints <service-name>  # 验证后端Pod
kubectl describe svc <service> -o jsonpath='{.spec.selector}'  # 检查标签选择器
kubectl logs -n kube-system <kube-proxy-pod>  # 诊断代理服务 
kubectl get networkpolicy  # 检查网络策略

1 ) 标签匹配验证

检查Service的selector是否匹配Pod标签:

bash 复制代码
kubectl get endpoints <service-name>  # 确认后端Pod列表 

2 ) kube-proxy服务状态

  • 重启服务:systemctl restart kube-proxy
  • 日志分析:journalctl -u kube-proxy 检查iptables/IPVS错误

3 ) 网络策略

确保NetworkPolicy未阻断流量(如kubectl get networkpolicy

Pod删除失败场景处理

原因 解决方案
被资源引用锁定 先删除关联资源:kubectl delete deployment/my-appkubectl delete deploy <name>
Pod状态异常 修复根本问题(kubectl logs <pod-name> -p查日志)
Node故障 恢复通信或强制驱逐:kubectl drain <node> --force
K8s版本缺陷 升级集群:kubectl upgrade
强制删除(终极方案) kubectl delete pod <name> --grace-period=0 --force
API通信中断 检查控制平面网络连通性

pause容器的作用,作为Pod根容器提供关键功能:

  1. 创建共享网络命名空间(eth0虚拟网卡)
  2. 建立数据卷供业务容器挂载
  3. 通过veth pair连接宿主机网桥(如cni0
  4. 业务容器通过join共享其网络栈

核心价值:确保同Pod内容器间通信隔离和存储共享

Pod网络与通信模型

1 ) Pause容器作用

  • 作为Pod的根容器,创建共享网络命名空间和数据卷,供业务容器挂载
  • 创建共享网络命名空间和数据卷
  • 建立veth pair连接宿主机网桥(如cni0
    • 创建虚拟网卡eth0,一端连接宿主机网桥(如cni0),另一端接入Pod

2 ) 通信机制
跨节点通信 同节点通信 通过veth pair 转发流量 VXLAN封装 隧道传输 flannel.1 PodC Node2/flannel.1 Bridge PodA PodB

Flannel实现细节:

  • 每个Node部署flanneld,创建flannel.1虚拟网卡
  • 跨主机流量通过VXLAN隧道传输
类型 实现方式
同节点Pod通信 通过网桥(cni0)直接转发
跨节点Pod通信 Overlay网络(如Flannel VXLAN模式): - 流量路径:Pod → 网桥 → flannel.1 → 物理网卡 → 目标Node

2.1 同节点Pod通信
通过veth pair 转发流量 PodA cni0网桥 PodB

  • 直接通过宿主机网桥转发(如Flannel的cni0

2.2 跨节点Pod通信

  • CNI插件(如Flannel)创建flannel.1虚拟网卡

  • 流量封装为VXLAN隧道传输:

    bash 复制代码
    # Flannel网卡验证
    ip addr show flannel.1  # 查看网卡配置 
    ip route show | grep flannel  # 验证路由 

2.3 路径:

  • Pod → 网桥 → flannel.1 → 物理网卡 → 目标Node → Pod

核心要点:

  • 每个Pod分配唯一IP
  • Service通过iptables/IPVS实现负载均衡

跨命名空间服务调用

1 ) 全限定域名(FQDN)访问

  • <service-name>.<namespace>.svc.cluster.local
  • 示例:curl http://nginx.test.svc.cluster.local

2 ) ExternalName Service

场景1:代理外部服务

yaml 复制代码
apiVersion: v1
kind: Service 
spec:
  type: ExternalName 
  externalName: www.example.com 

场景2:代理跨命名空间服务

yaml 复制代码
apiVersion: v1 
kind: Service 
metadata:
  name: cross-ns-proxy
  namespace: default 
spec:
  type: ExternalName 
  externalName: nginx-service.test-ns.svc.cluster.local 

Docker镜像优化方法

方法 示例/命令 优化效果
精简基础镜像 FROM alpine:latest 减少基础层体积
合并RUN指令 RUN apt update && apt install -y git && rm -rf /var/lib/apt/lists/* 减少层数+清理缓存
多阶段构建 dockerfile<br>FROM golang AS builder<br>COPY . .<br>RUN go build<br>FROM alpine<br>COPY --from=builder /app /app 分离构建/运行环境
排除非必要文件 .dockerignore中声明*.log, tmp/ 减小镜像体积
单层指令合并 RUN指令合并操作与清理步骤 避免冗余缓存产生

合并指令减少层数

dockerfile 复制代码
RUN apt-get update && apt-get install -y git \ 
   && rm -rf /var/lib/apt/lists/*  # 清理中间文件 

多阶段构建示例

dockerfile 复制代码
FROM golang:1.18 AS builder 
COPY . /app
RUN go build -o /app/main 
 
FROM alpine:3.15 
COPY --from=builder /app/main /main 
CMD ["/main"]

日志收集策略

1 ) 标准化输出日志

  • 路径:/var/log/containers/<pod>_<ns>_<container>-<id>.log

    • 示例路径:/var/lib/docker/containers/<container-id>/*.log
  • DaemonSet部署Filebeat:

    bash 复制代码
    kubectl apply -f - <<EOF 
    apiVersion: apps/v1
    kind: DaemonSet
    spec:
      template:
        spec:
          volumes:
            - name: varlog 
              hostPath:
                path: /var/log/containers
          containers:
          - name: filebeat
            volumeMounts:
              - mountPath: /logs 
                name: varlog
    EOF

    yaml 复制代码
    volumes:
      - name: docker-logs 
        hostPath:
          path: /var/lib/docker/containers 
    containers:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.14.0 
        volumeMounts:
          - name: docker-logs
            mountPath: /logs 

2 ) 容器内部日志收集

Sidecar模式共享卷:

yaml 复制代码
volumes:
  - name: shared-logs 
    emptyDir: {}
containers:
  - name: app 
    volumeMounts:
      - mountPath: /app/logs 
        name: shared-logs 
  - name: filebeat-sidecar 
    volumeMounts:
      - mountPath: /sidecar-logs 
        name: shared-logs 

yaml 复制代码
多容器Pod共享日志卷
apiVersion: v1
kind: Pod
metadata:
  name: log-collector 
spec:
  volumes:
    - name: log-volume
      emptyDir: {}
  containers:
  - name: app
    image: nginx
    volumeMounts:
      - name: log-volume
        mountPath: /app/logs 
  - name: filebeat
    image: elastic/filebeat 
    volumeMounts:
      - name: log-volume 
        mountPath: /logs

关键总结

  • 调度核心:预选/优选保证资源匹配,nodeAffinity提供策略灵活性
  • 故障排查:污点管理、kubelet状态及资源限制是关键切入点
  • 网络架构:Pause容器初始化环境,CNI插件实现跨节点通信
  • 运维实践:日志收集需区分输出类型,镜像优化聚焦层数与体积控制
  • 扩展能力:HPA/VPA/KPA覆盖动态扩缩容场景,ExternalName解决跨空间调用
相关推荐
不吃鱼的羊3 小时前
ZSAR配置CANSM模块
服务器·网络
asom223 小时前
互联网大厂Java求职面试实战:Spring Boot到Kubernetes的技术问答
java·spring boot·kubernetes·oauth2·电商·microservices·面试技巧
枫叶丹43 小时前
测试自动化新突破:金仓KReplay助力金融核心系统迁移周期缩减三周
网络·金融·自动化
Lowjin_4 小时前
UDP-复用分用
网络·网络协议·udp
Bypass--4 小时前
《云原生安全攻防》-- K8s集群安全事件响应
安全·云原生·容器·kubernetes
此生只爱蛋5 小时前
【Linux】自定义协议+序列和反序列化
linux·服务器·网络
huangyuchi.5 小时前
【Linux网络】Socket编程实战,基于UDP协议的Dict Server
linux·网络·c++·udp·c·socket
jenchoi4136 小时前
【2025-11-05】软件供应链安全日报:最新漏洞预警与投毒预警情报汇总
网络·安全·web安全·网络安全
爱编程的鱼9 小时前
403 是什么意思?一文读懂 HTTP 状态码 403 及解决方法
网络·网络协议·http