在K8S service类型中,NodePort 服务包含了 ClusterIP 服务的所有能力。
这是一个重要的核心概念:NodePort 服务是在 ClusterIP 服务基础上的扩展,而不是一个独立的替代品。
详细解释:
1.架构层次
NodePort Service = ClusterIP Service + NodePort 端口映射2.实际访问方式
一个 NodePort 类型的 Service 实际上同时支持三种访问方式:
方式一:通过 ClusterIP(内部访问)✅
apiVersion:v1kind:Servicemetadata:name:my-servicespec:type:NodePort# 注意这里指定的是 NodePortselector:app:my-appports:-port:80# ClusterIP 端口targetPort:8080# Pod 端口nodePort:30007# NodePort 端口(可选,系统自动分配)集群内部访问:
# 通过 ClusterIP 直接访问curlhttp://<cluster-ip>:80# 通过 DNS 域名访问(完全支持!)✅curlhttp://my-service.default.svc.cluster.local:80curlhttp://my-service:80# 同一命名空间内可省略后缀方式二:通过 NodePort(外部访问)
# 通过任何节点的 IP + NodePort 访问curlhttp://<node-ip>:30007方式三:通过 LoadBalancer(如果有云提供商)
如果你在云环境,还可以配置 LoadBalancer,它又是在 NodePort 基础上的扩展。
3.DNS 解析验证
# 查看服务详情kubectl get svc my-service# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)# my-service NodePort 10.96.123.456 <none> 80:30007/TCP# 查看 DNS 解析kubectl run -it --rmtest--image=busybox --restart=Never --nslookupmy-service# Server: 10.96.0.10# Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local## Name: my-service# Address 1: 10.96.123.456 my-service.default.svc.cluster.local4.实际示例
apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deployspec:replicas:2selector:matchLabels:app:nginxtemplate:metadata:labels:app:nginxspec:containers:-name:nginximage:nginx:alpineports:-containerPort:80---apiVersion:v1kind:Servicemetadata:name:nginx-servicespec:type:NodePort# NodePort 类型selector:app:nginxports:-port:80# 集群内访问端口targetPort:80# Pod 端口nodePort:30080# 节点端口测试访问:
# 1. 在集群内部通过 DNS 访问(ClusterIP 能力)kubectlexec-it<pod-name>--curlhttp://nginx-service# 2. 从外部通过 NodePort 访问curlhttp://<任意节点IP>:300805.流量流向示意
外部用户 ↓ Node IP:NodePort (如 192.168.1.100:30007) ↓ Service ClusterIP (如 10.96.123.456:80) ↓ Pod IP:Port (如 10.244.1.2:8080)总结要点:
- ✅NodePort 服务一定包含 ClusterIP,每个 NodePort 服务都会自动分配一个 ClusterIP
- ✅K8S DNS 完全支持,可以通过服务名在集群内解析到 ClusterIP
- ✅集群内部访问优先使用 ClusterIP/DNS,不经过节点端口,效率更高
- ❌NodePort 不是 ClusterIP 的替代,而是它的超集
- 💡最佳实践:集群内部组件间通信使用服务名(DNS),外部访问才用 NodePort
所以,可以完全放心地在集群内部通过service-name.namespace.svc.cluster.local来访问 NodePort 服务!