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 的 Podports:- protocol: TCP # 協議類型,支持 TCP、UDP、SCTPport: 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 的 Podports:- 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