《Kubernetes 网络进阶、调度策略与自动扩缩容实战精要》

《Kubernetes 网络进阶、调度策略与自动扩缩容实战精要》

本总结覆盖 Kubernetes 网络模型(CNI/CNM)跨主机网络方案对比Calico 网络策略(NetworkPolicy)Pod 调度控制(nodeName / nodeSelector / 亲和性 / 污点容忍)节点维护(cordon/drain)Metrics Server 部署 以及 HPA(水平 Pod 自动伸缩) 的完整配置与实验代码,所有核心知识点均配有详细注释,可直接用于生产环境参考。


一、Kubernetes 网络模型概览

1.1 单主机网络(Docker / Containerd)

  • 容器使用 veth pair 连接至宿主机网桥(如 docker0),通过 Linux 内核直接复制数据包 实现高效通信,无需经过外部物理网络。
  • 外部访问需通过 端口映射(hostPort 或 NodePort)。

1.2 跨主机网络方案对比(重点)

CNI方案 网络模型(Underlay/Overlay) 性能 支持 NetworkPolicy 适用场景
Flannel host-gw (Underlay) / VXLAN (Overlay) host-gw 高,VXLAN 有封装开销 中小集群,简单连通需求
Calico BGP (Underlay) / IPIP/VXLAN (Overlay) BGP 最优,IPIP 有开销 ✅ 原生支持 生产环境,需要网络策略
Weave Net UDP 隧道 (Overlay) 较低 小规模测试
Macvlan Underlay(直连物理网络) 极高(无封装) 依赖配套插件 Pod 需要独立 MAC/IP,低延迟

核心结论

  • Underlay 性能优于 Overlay(无隧道封装)。
  • 若需 网络策略(NetworkPolicy),必须选择 Calico 或 Weave 等支持方案。
  • 生产环境推荐 Calico(BGP 模式)

二、容器网络接口模型(CNM vs CNI)

模型 提出者 最小单元 依赖 特点
CNM(Container Network Model) Docker 容器(Container) 依赖 dockerd 及 libnetwork Docker 原生,使用较少
CNI(Container Network Interface) Google / CoreOS Pod(一组容器) 无守护进程,插件化 Kubernetes 标准,插件可替换
  • CNI 工作流程:kubelet 调用 CNI 插件(如 Calico)为 Pod 创建网络命名空间、分配 IP 并设置路由。
  • IPAM 插件 :负责 IP 地址分配(如 calico-ipam)。

三、Calico 网络实战(容器网络策略与 IP 池)

3.1 Calico 架构要点

  • 纯三层方案 :每个节点作为路由器,通过 BGP 交换 Pod 路由,无 NAT 和隧道(默认 BGP 模式)。
  • 支持 NetworkPolicy:通过 Profile 和 Policy 规则精细化控制 Pod 间流量。
  • IP 池可定制:支持预定义子网或手动指定 IP。

3.2 部署 Calico(Docker 环境示例,带注释)

bash 复制代码
# 下载 calicoctl 工具
wget -O /usr/local/bin/calicoctl https://github.com/projectcalico/calicoctl/releases/download/v1.0.2/calicoctl
chmod +x /usr/local/bin/calicoctl

# 配置 calicoctl 连接 etcd(需提前部署 etcd)
mkdir /etc/calico
cat << EOF > /etc/calico/calicoctl.cfg
apiVersion: v1
kind: calicoApiConfig
metadata:
spec:
  etcdEndpoints: "http://10.1.8.30:2379"
EOF

# 启动 calico-node(以容器运行)
calicoctl node run
# 此时 calico 自动发现其他节点,并建立 BGP 连接

3.3 创建 Calico 网络(Docker 网络驱动)

bash 复制代码
# 创建一个名为 cal_net1 的 Calico 网络,使用 calico 驱动和 calico-ipam IPAM
docker network create --driver calico --ipam-driver calico-ipam cal_net1

3.4 定制 Network Policy(允许跨网络访问)

场景 :允许 cal_net2 中的 Pod 访问 cal_web 网络中 Web 服务的 80 端口。

yaml 复制代码
# web.yml - 修改 cal_web 的 profile,开放 ingress 规则
- apiVersion: v1
  kind: profile
  metadata:
    name: cal_web                     # 对应 cal_web 网络
  spec:
    ingress:
    - action: allow
      protocol: tcp
      destination:
        ports:
        - 80                          # 允许访问 80 端口
      source:
        tag: cal_net2                 # 仅允许来自 cal_net2 网络(标签)的源

应用策略:

bash 复制代码
calicoctl apply -f web.yml

3.5 定制 IP 池

bash 复制代码
# 定义 IP Pool(CIDR 为 17.2.0.0/16)
cat << EOF > ipPool.yml
- apiVersion: v1
  kind: ipPool
  metadata:
    cidr: 17.2.0.0/16
EOF
calicoctl create -f ipPool.yml

# 创建网络时指定子网
docker network create --driver calico --ipam-driver calico-ipam --subnet=17.2.0.0/16 my_net

四、Kubernetes NetworkPolicy(网络策略)

NetworkPolicy 通过 标签选择器 控制 Pod 的入站(Ingress)和出站(Egress)流量。需要支持 CNI(如 Calico)。

4.1 规约结构(带注释)

yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:                      # 策略作用的 Pod 选择器
    matchLabels:
      role: db
  policyTypes:                      # 必填,指定 Ingress / Egress
  - Ingress
  - Egress
  ingress:                          # 入站规则白名单
  - from:
    - ipBlock:                      # 允许来源 IP 段
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:            # 允许来自特定命名空间(标签)
        matchLabels:
          project: myproject
    - podSelector:                  # 允许来自同命名空间内特定 Pod
        matchLabels:
          role: frontend
    ports:                          # 允许访问的端口
    - protocol: TCP
      port: 6379
  egress:                           # 出站规则
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

4.2 实战示例(按条件限制访问)

① 限制同一 Namespace 内特定 Pod 访问(podSelector)
yaml 复制代码
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-test-to-web1
  namespace: web
spec:
  podSelector:
    matchLabels:
      run: web1                    # 作用于 web1 Pod
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          run: test                # 只允许标签 run=test 的 Pod 访问
    ports:
    - protocol: TCP
      port: 80
② 允许同一 Namespace 所有 Pod 访问(podSelector: {})
yaml 复制代码
ingress:
- from:
  - podSelector: {}                # 空选择器,匹配该 namespace 所有 Pod
  ports:
  - port: 80
③ 允许来自特定 Namespace(namespaceSelector)
yaml 复制代码
ingress:
- from:
  - namespaceSelector:
      matchLabels:
        project: myproject        # 只有标签为 project=myproject 的 namespace 内的 Pod 可访问
  ports:
  - port: 80
④ 根据 IP 段(ipBlock)控制
yaml 复制代码
ingress:
- from:
  - ipBlock:
      cidr: 10.1.8.0/24
      except:
      - 10.1.8.128/26             # 排除子网
  ports:
  - port: 80
⑤ 限制所有端口(不指定 ports)
yaml 复制代码
ingress:
- from:
  - podSelector:
      matchLabels:
        run: test
  # 未指定 ports,表示允许所有端口(包括 ICMP)
⑥ 多条件组合(满足任一即可)
yaml 复制代码
ingress:
- from:
  - ipBlock: { cidr: 10.1.1.0/24 }
  - namespaceSelector: { matchLabels: { project: myproject } }
  - podSelector: { matchLabels: { run: test } }
  # 任一条件满足即可

4.3 默认策略(隔离所有流量)

yaml 复制代码
# 默认拒绝所有入站
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  podSelector: {}
  policyTypes:
  - Ingress

# 默认拒绝所有出站
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress

注意:NetworkPolicy 无法实现"显式拒绝",只能通过允许白名单间接拒绝。


五、Pod 调度控制

调度器通过 过滤(Filter)打分(Score) 选择最佳节点。

5.1 nodeName(强制指定节点)

yaml 复制代码
spec:
  nodeName: worker32.laoma.cloud   # 直接指定节点名称,优先级最高,但不推荐

5.2 nodeSelector(基于标签的简单约束)

bash 复制代码
# 给节点打标签
kubectl label node worker31.laoma.cloud disktype=ssd

# Pod 配置
spec:
  nodeSelector:
    disktype: ssd                 # 必须匹配节点标签

5.3 节点亲和性(nodeAffinity)

支持 硬性(required)软性(preferred) 规则。

YAML 示例(带注释)

yaml 复制代码
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:   # 硬性要求
        nodeSelectorTerms:
        - matchExpressions:
          - key: CPU
            operator: In
            values:
            - L1
            - L2
      preferredDuringSchedulingIgnoredDuringExecution:  # 软性偏好(带权重)
      - weight: 1
        preference:
          matchExpressions:
          - key: MEM
            operator: In
            values:
            - L1
            - L2
  • operator 支持:InNotInExistsDoesNotExistGtLt
  • 若同时使用 nodeSelectornodeAffinity,需同时满足。

5.4 Pod 间亲和性与反亲和性(inter-pod affinity/anti-affinity)

基于 已有 Pod 标签 决定调度位置,需指定 topologyKey(节点标签键)。

亲和性(Pod 尽量调度到同一拓扑域)

yaml 复制代码
spec:
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - web1
        topologyKey: topology.kubernetes.io/zone   # 节点必须具有该标签键

反亲和性(Pod 尽量分散到不同拓扑域)

yaml 复制代码
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - store
        topologyKey: kubernetes.io/hostname   # 每个节点只能运行一个

示例(Redis 部署,每个节点最多一个副本)

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: store
spec:
  replicas: 3
  selector:
    matchLabels:
      app: store
  template:
    metadata:
      labels:
        app: store
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - store
            topologyKey: kubernetes.io/hostname
      containers:
      - name: nginx
        image: nginx

注意:Pod 亲和/反亲和在大规模集群中消耗性能,建议节点数 < 500。


六、污点(Taint)与容忍度(Toleration)

  • Taint 设置在节点上,用于 排斥 不匹配的 Pod。
  • Toleration 设置在 Pod 上,允许被调度到有匹配污点的节点。

6.1 管理污点

bash 复制代码
# 添加污点(key=value:effect)
kubectl taint nodes worker31.laoma.cloud CPU=L1:NoSchedule

# 移除污点(key:effect-)
kubectl taint nodes worker31.laoma.cloud CPU:NoSchedule-

Effect 类型

  • NoSchedule:硬性排斥,新 Pod 不调度。
  • PreferNoSchedule:软性排斥,尽量不调度。
  • NoExecute:立即驱逐不能容忍该污点的已有 Pod,且不调度新 Pod。

6.2 配置 Pod 容忍度

yaml 复制代码
spec:
  tolerations:
  - key: "CPU"
    operator: "Equal"            # 或 "Exists"
    value: "L1"
    effect: "NoSchedule"
    tolerationSeconds: 3600      # 仅在 NoExecute 时有效,指定容忍时间

匹配规则

  • 多个污点,Pod 必须容忍所有 NoSchedule 污点才能被调度。
  • 存在任意 NoExecute 污点未容忍,则 Pod 被驱逐(或无法调度)。

6.3 内置污点与自动容忍

  • 节点状态异常时,控制器会自动添加污点:
    • node.kubernetes.io/not-ready
    • node.kubernetes.io/unreachable
    • node.kubernetes.io/memory-pressure
  • Kubernetes 会自动为 Pod 添加容忍度(如 not-ready 容忍 300s),DaemonSet 的 Pod 则容忍无限长。

七、节点维护:cordon、drain、uncordon

7.1 cordon(标记不可调度)

bash 复制代码
kubectl cordon worker31.laoma.cloud   # 节点状态变为 SchedulingDisabled,新 Pod 不再调度到该节点

7.2 drain(驱逐 Pod + 标记不可调度)

bash 复制代码
kubectl drain worker31.laoma.cloud --ignore-daemonsets
# 会驱逐该节点上的所有非 DaemonSet Pod,并标记为不可调度
# 可添加 --pod-selector 过滤要驱逐的 Pod

7.3 uncordon(恢复调度)

bash 复制代码
kubectl uncordon worker31.laoma.cloud

八、Pod 优先级与抢占(PriorityClass)

  • 通过 PriorityClass 定义优先级值,值越大优先级越高。
  • 高优先级 Pod 可 抢占(Preempt) 低优先级 Pod 的资源(默认行为)。
  • 可设置 preemptionPolicy: Never 禁止抢占。

PriorityClass 示例

yaml 复制代码
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
  name: high-priority
value: 1000000
globalDefault: false
description: "用于重要服务"

Pod 引用

yaml 复制代码
spec:
  priorityClassName: high-priority

九、Metrics Server 部署与 HPA(水平 Pod 自动伸缩)

9.1 部署 Metrics Server(带注释)

bash 复制代码
# 下载部署文件(已修改镜像源及添加 --kubelet-insecure-tls 参数)
wget -O components.yaml http://example.com/metrics-server-components-v0.7.1.yaml

# 查看关键部分,确保添加了 --kubelet-insecure-tls(如证书问题)
# 修改镜像地址为私有仓库
sed -i 's/registry.k8s.io/hub.laoma.cloud/g' components.yaml

# 部署
kubectl apply -f components.yaml

验证

bash 复制代码
kubectl top nodes
kubectl top pods -n kube-system

9.2 HPA(Horizontal Pod Autoscaler)

基于 CPU 使用率伸缩
bash 复制代码
# 创建 Deployment(需设置资源 requests/limits)
kubectl create deployment web --image=nginx
kubectl set resources deployment web --limits=cpu=100m,memory=200Mi

# 创建 HPA(最小 2,最大 5,目标 CPU 利用率 80%)
kubectl autoscale deployment web --min=2 --max=5 --cpu-percent=80

生成的 HPA YAML(带注释)

yaml 复制代码
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: web
spec:
  minReplicas: 2
  maxReplicas: 5
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: web
  metrics:
  - resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80       # CPU 利用率目标
    type: Resource
基于内存使用率伸缩
yaml 复制代码
metrics:
- resource:
    name: memory
    target:
      type: Utilization
      averageUtilization: 60         # 内存利用率目标
压力测试(生成 CPU 负载)
bash 复制代码
# 暴露 Service
kubectl expose deployment web --port=80

# 使用 ab 压测(需安装 apache2-utils)
while true; do ab -n 300000 -c 100 http://<Service-IP>/; sleep 1; done
  • HPA 会监控指标,当 CPU 超过 80% 时逐步扩容 Pod(最多 5 个)。
  • 停止压测后,因缩容冷却时间(默认 5 分钟),Pod 数量会逐步降回最小值。
调整扩缩容冷却参数(kube-controller-manager)
yaml 复制代码
# 编辑 /etc/kubernetes/manifests/kube-controller-manager.yaml
spec:
  containers:
  - command:
    - --horizontal-pod-autoscaler-sync-period=10s          # 指标采样周期
    - --horizontal-pod-autoscaler-initial-readiness-delay=20s  # Pod 就绪等待
    - --horizontal-pod-autoscaler-downscale-stabilization=60s  # 缩容冷却

修改后,静态 Pod 自动重启生效。


十、VPA(Vertical Pod Autoscaler)简介

  • VPA 自动调整 Pod 的 requests 和 limits,不改变副本数。
  • 需要重启 Pod 才能生效(通常配合 VPA 的 updateMode)。
  • 不能与 HPA 同时使用(会冲突)。
  • 适用于资源配置不合理、长期稳定的服务。

十一、环境清理

bash 复制代码
kubectl delete ns network          # 清理网络策略实验
kubectl delete ns scheduler        # 清理调度实验
kubectl delete ns metric           # 清理自动扩缩容实验

以上内容涵盖 Kubernetes 网络、调度、节点维护和自动扩缩容的核心知识点

相关推荐
路由侠内网穿透3 小时前
本地部署企业级快速开发平台芋道管理后台并实现外部访问
运维·服务器·网络·网络协议
basketball6163 小时前
软考中级网络工程师 第4章 无线通信网 备考总结
linux·服务器·网络·网络工程师·软考
睡一觉就好了。5 小时前
Linux 信号机制
linux·运维·网络
AAA@峥7 小时前
K8s 流量入口管理|Ingress 核心原理 + ingress-nginx 部署 + 生产实战案例合集
nginx·容器·kubernetes
A_humble_scholar8 小时前
Linux(二) C++ TCP/UDP网络编程
linux·网络·c++
nnerddboy8 小时前
Rust教程05:结构体,枚举与模式匹配
开发语言·网络·rust
xiaoxiangsiyan8 小时前
企业园区局域网交换技术完整版手册主打华为设备
运维·网络·学习·华为·路由·交换机·企业网
深圳联瑞电子LRLINK9 小时前
数据中心TOR交换机和服务器网卡怎么搭配
网络·网卡
GlobalInfo9 小时前
AI与另类数据融合,市场研究正在从“经验驱动”走向“数据智能”
大数据·网络·人工智能·ai
天吾cc9 小时前
RTT-MQTT
网络·单片机·嵌入式硬件·算法