k8s中service概述(二)NodePort
NodePort 是 Kubernetes 中一种用于对外暴露服务的 Service 类型。它通过在集群的每个节点上开放一个静态端口(NodePort),使得外部用户可以通过节点的 IP 地址和该端口访问集群内部的服务。以下是关于 NodePort Service 的详细说明:
1. NodePort 的核心功能
-
外部访问:NodePort 允许外部用户通过集群中任意节点的 IP 地址和指定的端口访问服务。
-
端口映射:NodePort 会在每个节点上开放一个静态端口(默认范围是 30000-32767),并将该端口的流量转发到后端的 Pod。
-
负载均衡:与 ClusterIP 类似,NodePort 也会自动将流量负载均衡到后端的多个 Pod。
-
集群内部访问:NodePort Service 也会分配一个 ClusterIP,因此集群内部仍然可以通过 ClusterIP 访问服务。
2. NodePort 的工作原理
NodePort 的实现依赖于 Kubernetes 的网络模型和核心组件:
-
Service 创建:
-
当创建一个 NodePort Service 时,Kubernetes 会为其分配一个 ClusterIP,并在每个节点上开放一个静态端口(NodePort)。
-
NodePort 的默认范围是 30000-32767,但可以手动指定。
-
-
Endpoints 创建:
-
与 ClusterIP 类似,Kubernetes 会自动创建与 Service 同名的 Endpoints 对象,其中包含所有匹配
selector
的 Pod 的 IP 和端口。
-
-
kube-proxy 的作用:
-
每个节点上的
kube-proxy
组件会监听 Service 和 Endpoints 的变化。 -
kube-proxy
通过以下方式实现流量转发:-
iptables 模式:在节点上配置 iptables 规则,将流量从 NodePort 转发到后端 Pod。
-
IPVS 模式:使用更高效的 IPVS 实现流量转发。
-
-
无论使用哪种模式,
kube-proxy
都会确保流量被正确负载均衡到后端 Pod。
-
-
外部访问:
-
外部用户可以通过任意节点的 IP 地址和 NodePort 访问服务。
-
例如,如果 NodePort 为 31000,节点的 IP 地址为 192.168.1.100,则外部用户可以通过
http://192.168.1.100:31000
访问服务。
-
3. NodePort 的配置示例
以下是一个典型的 NodePort Service 的 YAML 配置文件:
apiVersion: v1
kind: Service
metadata:
name: my-service # Service 名称
namespace: default # 命名空间,默认为 default
spec:
type: NodePort # Service 类型
selector:
app: my-app # 选择标签为 app=my-app 的 Pod
ports:
- protocol: TCP # 协议类型,支持 TCP、UDP、SCTP
port: 80 # Service 暴露的端口
targetPort: 9376 # 后端 Pod 的端口
nodePort: 31000 # 手动指定的 NodePort,范围为 30000-32767
-
selector:用于选择后端 Pod,只有匹配标签的 Pod 才会被纳入 Service 的后端。
-
ports:
-
port
:Service 暴露的端口,集群内的其他服务通过该端口访问 Service。 -
targetPort
:后端 Pod 实际监听的端口。 -
nodePort
:手动指定的 NodePort,范围为 30000-32767。如果不指定,Kubernetes 会自动分配一个可用的端口。
-
-
type:Service 类型,这里设置为
NodePort
。
4. NodePort 的使用场景
NodePort 适用于以下场景:
-
开发和测试环境:
-
在开发和测试环境中,NodePort 可以快速暴露服务,方便外部访问和调试。
-
-
小型生产环境:
-
在小型生产环境中,如果没有负载均衡器,可以使用 NodePort 暴露服务。
-
-
特殊需求:
-
某些场景下,可能需要直接通过节点的 IP 地址访问服务,例如某些网络设备或旧系统。
-
-
与 LoadBalancer 结合使用:
-
在云环境中,NodePort 通常与 LoadBalancer 结合使用,LoadBalancer 会将外部流量导入 NodePort。
-
5. NodePort 的优缺点
优点:
-
简单易用,快速暴露服务。
-
不需要额外的负载均衡器,适合小型环境。
-
可以在任意节点上访问服务,具有较高的可用性。
缺点:
-
端口范围有限(30000-32767),可能与现有服务冲突。
-
直接暴露节点的 IP 地址,可能存在安全风险。
-
需要手动管理节点的 IP 地址,不适合大规模生产环境。
6. NodePort 的调试和排查
-
查看 Service 信息:
kubectl get svc <service-name>
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE my-service NodePort 10.96.123.45 <none> 80:31000/TCP 5m
-
查看 Endpoints:
kubectl get endpoints <service-name>
输出示例:
NAME ENDPOINTS AGE my-service 10.244.1.2:9376,10.244.2.3:9376 5m
-
检查节点端口:
-
登录到节点,检查 NodePort 是否正常开放:
netstat -tuln | grep 31000
-
-
检查 kube-proxy 和 iptables/IPVS 规则:
-
登录到节点,检查 iptables 或 IPVS 规则是否正常配置。
-
7. 总结
NodePort 是 Kubernetes 中用于对外暴露服务的 Service 类型,它通过在集群的每个节点上开放一个静态端口,使得外部用户可以通过节点的 IP 地址和该端口访问集群内部的服务。NodePort 简单易用,适合开发和测试环境,但在生产环境中通常需要结合 LoadBalancer 或 Ingress 使用,以提供更高的可用性和安全性。
使用 NodePort 暴露 Nginx 服务的示例
以下是一个完整的示例,展示如何在 Kubernetes 中使用 NodePort Service 暴露一个 Nginx 服务。这个示例包括:
-
部署一个 Nginx Pod。
-
创建一个 NodePort Service 来暴露 Nginx 服务。
1. 创建 Nginx 部署
首先,创建一个 Deployment 来运行 Nginx Pod。以下是一个简单的 YAML 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment # 部署名称
labels:
app: nginx # 标签,用于 Service 选择
spec:
replicas: 3 # 副本数
selector:
matchLabels:
app: nginx # 选择器,匹配 Pod 标签
template:
metadata:
labels:
app: nginx # Pod 标签
spec:
containers:
- name: nginx # 容器名称
image: nginx:latest # 使用官方 Nginx 镜像
ports:
- containerPort: 80 # 容器监听的端口
将上述内容保存为 nginx-deployment.yaml
,然后使用以下命令创建 Deployment:
kubectl apply -f nginx-deployment.yaml
2. 创建 NodePort Service
接下来,创建一个 NodePort Service 来暴露 Nginx 服务。以下是一个简单的 YAML 文件:
apiVersion: v1
kind: Service
metadata:
name: nginx-service # Service 名称
spec:
type: NodePort # Service 类型
selector:
app: nginx # 选择标签为 app=nginx 的 Pod
ports:
- protocol: TCP # 协议类型
port: 80 # Service 暴露的端口
targetPort: 80 # 后端 Pod 的端口
nodePort: 30080 # 手动指定的 NodePort,范围为 30000-32767
将上述内容保存为 nginx-service.yaml
,然后使用以下命令创建 Service:
kubectl apply -f nginx-service.yaml
3. 验证部署和 Service
-
查看 Deployment 状态:
kubectl get deployments
输出示例:
-
查看 Pod 状态:
kubectl get pods
-
查看 Service 状态:
kubectl get svc nginx-service
4. 访问 Nginx 服务
-
获取节点的 IP 地址:
使用kubect get nodes -o wide获取节点信息-
输出示例:
- 可以发现节点ip
-
如果你在云环境或物理机中,可以使用节点的公网或内网 IP。
-
-
通过 NodePort 访问 Nginx:
-
打开浏览器,访问
http://<NodeIP>:30080
。 -
例如,如果节点 IP 是
192.168.30.130
,则访问http://192.168.30.130:30080
。 -
你应该会看到 Nginx 的默认欢迎页面。
-
可以在外部浏览器看到ngnix的页面
-
5. 清理资源
完成测试后,可以删除 Deployment 和 Service:
kubectl delete -f nginx-deployment.yaml kubectl delete -f nginx-service.yaml