Kubernetes 服务访问外部地址
在 Kubernetes 中,服务访问外部地址是常见需求,比如连接外部数据库、API 服务或其他资源。以下是 Kubernetes 服务访问外部地址的几种方式及其流量拓扑。
1. 服务访问外部地址的方式
方式 1:直接通过 Pod 发起请求
描述:Pod 中的应用程序直接访问外部地址(IP 或域名)。
流量路径:
- Pod -> 宿主节点的虚拟网桥(如
cni0
)。 - 节点通过 NAT 转换 Pod 的源 IP。
- 节点出口发送请求到外部地址。
- 外部地址响应返回通过节点转发到 Pod。
使用场景:访问外部数据库、REST API 或其他网络资源。
Pod (10.244.0.5) --> Node NAT --> External Service (10.1.32.1)
方式 2:使用 ExternalName
服务
描述:创建一个 ExternalName
服务,将 Kubernetes 服务映射到外部地址(域名)。
流量路径:
- Pod 请求
ExternalName
服务的 ClusterIP。 - CoreDNS 将 ClusterIP 解析为外部地址的域名。
- Pod 直接与外部地址通信。
使用场景:通过服务名访问外部资源,提高配置灵活性。
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
type: ExternalName
externalName: external.example.com
Pod --> CoreDNS --> ExternalName (external.example.com) --> External Service
方式 3:通过 ClusterIP 服务代理外部地址
描述:使用 ClusterIP 服务将外部地址代理到集群内部。需要设置 Endpoints
资源,手动定义外部地址的后端。
流量路径:
- Pod 访问 ClusterIP 服务。
- kube-proxy 根据服务配置将流量转发到外部地址。
使用场景:需要通过 Kubernetes 服务统一管理外部地址。
apiVersion: v1
kind: Service
metadata:
name: proxy-service
spec:
clusterIP: 10.96.0.10
ports:
- port: 80
targetPort: 8080
---
apiVersion: v1
kind: Endpoints
metadata:
name: proxy-service
subsets:
- addresses:
- ip: 10.1.32.1
ports:
- port: 8080
Pod --> ClusterIP (10.96.0.10) --> External Service (10.1.32.1)
方式 4:通过 NodePort 或 LoadBalancer 暴露内部服务
描述:外部地址通过 NodePort 或 LoadBalancer 服务访问,集群内的服务访问这些服务转发到外部地址。
流量路径:
- Pod 访问 NodePort 或 LoadBalancer 的地址。
- 节点通过 kube-proxy 将流量转发到外部地址。
使用场景:与外部系统双向通信,或为外部服务提供内部代理。
apiVersion: v1
kind: Service
metadata:
name: external-proxy
spec:
type: NodePort
ports:
- port: 80
nodePort: 30001
targetPort: 8080
Pod --> NodePort (30001) --> External Service (10.1.32.1)
方式 5:通过 Ingress 控制器代理外部地址
描述:使用 Ingress 规则定义外部地址的代理路径。
流量路径:
- Pod 请求 Ingress 代理的服务域名。
- Ingress 规则将流量代理到外部地址。
使用场景:通过集群统一代理外部资源,并支持路径或域名级别路由。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-ingress
spec:
rules:
- host: external.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: proxy-service
port:
number: 80
Pod --> Ingress (external.example.com) --> External Service (10.1.32.1)
流量拓扑汇总
访问方式 | 流量路径 | 适用场景 |
---|---|---|
直接访问外部地址 | Pod -> Node NAT -> External Service | 简单、高效直接访问外部资源 |
ExternalName 服务 | Pod -> CoreDNS -> ExternalName -> External Service | 通过服务名管理外部资源 |
ClusterIP + Endpoints | Pod -> ClusterIP -> kube-proxy -> External Service | 通过内部服务代理外部地址 |
NodePort/LoadBalancer | Pod -> NodePort/LoadBalancer -> External Service | 内外部双向通信场景 |
Ingress | Pod -> Ingress -> kube-proxy -> External Service | 复杂代理规则和统一域名管理 |
注意事项
- 网络策略 (NetworkPolicy):如果启用了
NetworkPolicy
,需要明确允许 Pod 的 Egress 流量访问外部地址:apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-egress spec: podSelector: {} policyTypes: - Egress egress: - to: - ipBlock: cidr: 10.1.32.0/24 ports: - protocol: TCP port: 3306
- DNS 配置:如果通过域名访问外部服务,确保 CoreDNS 配置正确。
- 防火墙和安全组:确保外部服务允许 Kubernetes 节点或 Pod 的 IP 访问。
- 性能与稳定性:外部访问可能增加网络延迟和故障点,建议为高频访问场景引入缓存机制。
通过以上方式,可根据需求选择合适的外部访问方案,设计流量路径。