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 控制暴露策略。
{{- /* 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 控制启用与规则。
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 之间的逻辑关系与流量路径:
4.6 网络策略的准入控制与性能影响
NetworkPolicy 在 Helm 部署中不仅用于安全隔离,还会影响网络性能。以下是关键调优维度:
- 规则数量:每个 NetworkPolicy 对象中的规则数建议不超过 50 条,过多规则会导致 CNI 的 iptables/BPF 规则膨胀,增加转发延迟。
- 标签选择器粒度:使用精确的
matchLabels而非宽泛的matchExpressions,减少策略匹配时的计算开销。 - 策略顺序:NetworkPolicy 是白名单机制,默认拒绝所有流量。建议将最常用的允许规则放在前面,减少遍历次数。
- Egress 规则优化:对于对外部服务的访问,使用
ipBlock而非namespaceSelector,避免跨命名空间标签查询。
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 的访问控制协同工作,为后续的性能调优与准入控制奠定基础。