4. 网络拓扑定义:在 Helm Chart 中定义 Service、Ingress、Endpoint 与网络策略

在 Kubernetes 网络模型中,Service、Ingress、Endpoint 与 NetworkPolicy 共同构成了应用流量的完整生命周期。Helm Chart 作为配置管理工具,需要以声明式模板精确描述这些资源的拓扑关系,才能实现可预测的网络性能与安全隔离。本节将逐一拆解每种资源的 Helm 定义方式、关键字段及性能影响。

4.1 四层负载抽象:Service 的 Helm 定义

Service 是 Pod 逻辑访问入口,其类型(ClusterIP、NodePort、LoadBalancer)直接决定数据平面的转发路径。在 Helm Chart 中,Service 模板通常位于 templates/service.yaml,通过 .Values 控制暴露策略。

性能要点: ClusterIP 模式经过 kube-proxy(iptables/IPVS)转发,延迟约 0.1-0.5ms;LoadBalancer 模式额外经过云厂商 LB,增加 1-3ms 延迟。NodePort 模式会引入 SNAT,对长连接性能影响较大。
{{- /* templates/service.yaml */ -}}
apiVersion: v1
kind: Service
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    {{- include "myapp.labels" . | nindent 4 }}
spec:
  type: {{ .Values.service.type }}
  ports:
    - port: {{ .Values.service.port }}
      targetPort: {{ .Values.service.targetPort }}
      protocol: TCP
      name: http
  selector:
    {{- include "myapp.selectorLabels" . | nindent 4 }}
Service 类型 Helm values 示例 转发路径 延迟影响
ClusterIP type: ClusterIP Pod → kube-proxy → Pod 低(0.1-0.5ms)
NodePort type: NodePort 节点端口 → SNAT → Pod 中(0.5-1ms)
LoadBalancer type: LoadBalancer LB → NodePort → Pod 高(1-3ms)

4.2 七层路由:Ingress 的 Helm 定义

Ingress 提供基于 HTTP/HTTPS 的七层路由能力,是南北流量的核心入口。Helm Chart 中 Ingress 模板通常配合 .Values.ingress 控制域名、TLS 与注解,其中注解对性能调优至关重要。

{{- /* templates/ingress.yaml */ -}}
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: {{ include "myapp.fullname" . }}
  annotations:
    {{- toYaml .Values.ingress.annotations | nindent 4 }}
spec:
  ingressClassName: {{ .Values.ingress.className }}
  rules:
    - host: {{ .Values.ingress.host }}
      http:
        paths:
          - path: {{ .Values.ingress.path }}
            pathType: Prefix
            backend:
              service:
                name: {{ include "myapp.fullname" . }}
                port:
                  number: {{ .Values.service.port }}
  {{- with .Values.ingress.tls }}
  tls:
    {{- toYaml . | nindent 4 }}
  {{- end }}
{{- end }}
性能调优注解示例:
nginx.ingress.kubernetes.io/proxy-body-size: "10m" — 调整请求体大小限制;
nginx.ingress.kubernetes.io/proxy-read-timeout: "60" — 控制后端超时;
nginx.ingress.kubernetes.io/ssl-redirect: "true" — 强制 HTTPS 减少重定向开销。

4.3 后端映射:Endpoint 与 EndpointSlice

Endpoint 是 Service 与 Pod 之间的实际映射表。在 Helm Chart 中,通常不需要手动定义 Endpoint(由 Kubernetes 自动管理),但在 ExternalName 服务或 自定义后端 场景下,需要显式声明。

{{- /* templates/endpoints.yaml (仅用于外部服务场景) */ -}}
apiVersion: v1
kind: Endpoints
metadata:
  name: {{ include "myapp.fullname" . }}-external
subsets:
  - addresses:
      - ip: {{ .Values.externalService.ip }}
    ports:
      - port: {{ .Values.externalService.port }}
        name: http

对于大规模集群(Pod 数量 > 1000),建议启用 EndpointSlice(Kubernetes v1.21+ 默认),它将 Endpoint 分片存储,减少单个对象大小,降低 API Server 与 kube-proxy 的负载。

特性 Endpoint EndpointSlice
最大条目数 无限制(但对象大) 每 Slice 最多 100 个地址
更新粒度 全量替换 增量更新
API Server 压力 高(大对象频繁更新) 低(分片+增量)
Helm 支持 原生支持 需 discovery.k8s.io/v1 API

4.4 网络策略:NetworkPolicy 的 Helm 定义

NetworkPolicy 是 Kubernetes 原生的网络访问控制机制,基于标签选择器定义 Pod 间、Pod 与外部之间的流量规则。在 Helm Chart 中,NetworkPolicy 模板通常放在 templates/networkpolicy.yaml,通过 .Values.networkPolicy 控制启用与规则。

注意: NetworkPolicy 依赖 CNI 插件支持(如 Calico、Cilium、Antrea)。如果集群未安装支持 NetworkPolicy 的 CNI,策略将不会生效,但也不会报错。建议在 Helm Chart 的 README 中明确标注 CNI 依赖。
{{- /* templates/networkpolicy.yaml */ -}}
{{- if .Values.networkPolicy.enabled -}}
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ include "myapp.fullname" . }}
spec:
  podSelector:
    matchLabels:
      {{- include "myapp.selectorLabels" . | nindent 6 }}
  policyTypes:
    - Ingress
    - Egress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - protocol: TCP
          port: {{ .Values.service.port }}
  egress:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
      ports:
        - protocol: TCP
          port: 443
{{- end }}

4.5 网络拓扑关系图

下图展示了 Helm Chart 中定义的 Service、Ingress、Endpoint 与 NetworkPolicy 之间的逻辑关系与流量路径:

Helm 网络拓扑资源关系图 Ingress (七层路由) Service (四层负载) Endpoint / EndpointSlice Pod A (app=frontend) Pod B (app=backend) Pod C (app=db) NetworkPolicy HTTP 路由 负载均衡 映射 入站规则 出站规则 图例说明 实线:数据流路径 虚线:策略控制范围 颜色区分资源类型

4.6 网络策略的准入控制与性能影响

NetworkPolicy 在 Helm 部署中不仅用于安全隔离,还会影响网络性能。以下是关键调优维度:

  • 规则数量:每个 NetworkPolicy 对象中的规则数建议不超过 50 条,过多规则会导致 CNI 的 iptables/BPF 规则膨胀,增加转发延迟。
  • 标签选择器粒度:使用精确的 matchLabels 而非宽泛的 matchExpressions,减少策略匹配时的计算开销。
  • 策略顺序:NetworkPolicy 是白名单机制,默认拒绝所有流量。建议将最常用的允许规则放在前面,减少遍历次数。
  • Egress 规则优化:对于对外部服务的访问,使用 ipBlock 而非 namespaceSelector,避免跨命名空间标签查询。
Helm 最佳实践: 在 values.yaml 中为 NetworkPolicy 提供 enabled 开关和 rules 列表,允许用户按环境(dev/staging/prod)启用不同粒度的策略。生产环境建议开启所有策略,开发环境可关闭以降低调试复杂度。

4.7 完整拓扑定义示例

以下是一个综合 Helm Chart 的 values.yaml 片段,展示了如何通过参数化控制上述所有网络资源:

# values.yaml
service:
  type: ClusterIP
  port: 80
  targetPort: 8080

ingress:
  enabled: true
  className: nginx
  host: myapp.example.com
  path: /
  annotations:
    nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
  tls:
    - hosts:
        - myapp.example.com
      secretName: myapp-tls

networkPolicy:
  enabled: true
  ingressRules:
    - from:
        - podSelector:
            matchLabels:
              app: frontend
      ports:
        - port: 80
  egressRules:
    - to:
        - ipBlock:
            cidr: 0.0.0.0/0
            except:
              - 10.0.0.0/8
      ports:
        - port: 443

externalService:
  ip: 192.168.1.100
  port: 3306

通过上述定义,Helm Chart 能够一次性部署完整的网络拓扑,确保 Service 的负载均衡、Ingress 的七层路由、Endpoint 的后端映射以及 NetworkPolicy 的访问控制协同工作,为后续的性能调优与准入控制奠定基础。