# nodePort clusterIP Loadblance 公開service 方式差異 ## 名詞解釋 nodeport: * 特性 * 在每個node都開放一個指定的port * 且可以以下列兩種方式訪問pod 1. cluster IP 2. node IP(前提是Node 具有 EXTERNAL-IP) clusterIP: * 預設的service 公開服務的方式,只有在集群內部可以訪問 ## 不知道要用什麼service type? ```plantuml start if (只需要pod與pod之間通訊不需要對外?) then (yes) :service type: clusterIP; (需要對外)elseif (需要使用node EXTERNAL-IP對特定的node訪問? ) then (yes) :service type: nodePort; (no)elseif (在prod環境?) then (no) :service type: clusterIP; (yes)elseif (此環境有架ingress?) then (yes \n基於成本考量) :service type: nodePort; else (no) :service type: loadblancer; endif stop ``` ## Example: 下載k8s template repo `git clone https://gitlab.data.gamania.com/backend/k8s-template` ``` # 到 Demo資料夾路徑 cd templates/api/demo # 建立一個Deployment與ingress kubectl apply -f deployment.yaml kubectl apply -f ingress.yaml ``` --- 以上步驟完成後,會看到目前有三個pod ``` $ kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE hello-web-bd954bb4d-gt97d 1/1 Running 0 11s 10.96.2.96 gke-gke-tw-general-purpose-001-1788f9f6-2djn hello-web-bd954bb4d-r2j9j 1/1 Running 0 11s 10.96.2.38 gke-gke-tw-general-purpose-001-70825c81-nlpx hello-web-bd954bb4d-rkq7t 1/1 Running 0 11s 10.96.1.146 gke-gke-tw-general-purpose-001-0e30daf8-gk3n ``` 目前環境有三個node (都是private cluster, 故沒有**EXTERNAL-IP**) ``` $ kubectl get node -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP gke-gke-tw-general-purpose-001-1788f9f6-2djn Ready <none> 38h v1.24.12-gke.1000 10.96.132.237 gke-gke-tw-general-purpose-001-70825c81-nlpx Ready <none> 4d12h v1.24.12-gke.1000 10.96.132.12 gke-gke-tw-general-purpose-001-0e30daf8-gk3n Ready <none> 38h v1.24.12-gke.1000 10.96.132.18 ``` 執行下面的指令,來建立一個 curl 的 pod 並進入 shell(運行完會自動刪除) `kubectl run curl --image=curlimages/curl -it --rm -- sh` ### 公開 service 使用 cluster ip 形式 建立以cluster ip 公開service方式的yaml `kubectl apply -f service-clusterIP.yaml` ``` $ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web-clusterip ClusterIP 10.96.128.107 <none> 8080/TCP 80m ``` 以 `kubectl get svc` 取得的CLUSTER-IP 進行連線 ``` $ curl {{ CLUSTER-IP }}:8080 Hello, world! Version: 1.0.0 Hostname: hello-web-bd954bb4d-rkq7t ``` 以`kubectl get node -o wide`取得的 EXTERNAL-IP 無法訪問 pod ``` $ curl {{ EXTERNAL-IP }}:8080 curl: (7) Failed to connect to 10.96.132.12 port 8080 after 1 ms: Couldn't connect to server ``` ### 公開 service 使用 Node port 的方式 建立以 Node port形式公開service方式的yaml `kubectl apply -f service-nodeport.yaml` ``` ❯ kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE hello-web-nodeport NodePort 10.96.128.133 <none> 8080:32053/TCP 20s ``` 以 kubectl get svc 取得的CLUSTER-IP 進行連線 ``` ~ $ curl {{ CLUSTER-IP }}:8080 Hello, world! Version: 1.0.0 Hostname: hello-web-bd954bb4d-rkq7t ``` > 前提 如果場景是**public cluster**,每個node都會分配**EXTERNAL-IP** 但目前公司的GKE Node屬於Private cluster 故沒有開放EXTERNAL-IP ![](https://hackmd.io/_uploads/BJCAHx_D2.png) 以`kubectl get node -o wide`取得的 EXTERNAL-IP 可以訪問 pod ``` ~ $ curl {{ EXTERNAL-IP }}:8080 Hello, world! Version: 1.0.0 Hostname: hello-web-bd954bb4d-rkq7t ```