如何在 Kubernetes 中尋找服務的 URL
1. 概述
網路是 Kubernetes 不可或缺的一部分, Service是其原始網路物件之一。 Kubernetes Service讓我們可以向外部世界公開網路應用程式。然而,要存取它,我們必須知道它的 URL。
在本實作教程中,我們將討論如何尋找並使用 Kubernetes 服務的 URL 作為可靠的網路端點。
2. 設定範例
我們需要建立一些 Kubernetes 物件作為範例。首先,讓我們建立Namespace物件。
2.1.建立 Kubernetes 命名空間
Kubernetes 命名空間讓我們可以隔離同一叢集內的資源。因此,讓我們使用create命令創建兩個命名空間 - dev和stg :
$ kubectl create ns dev
namespace/dev created
$ kubectl create ns stg
namespace/stg created
2.2.建立 Kubernetes 部署
在上一步中,我們創建了兩個命名空間。現在,讓我們將Redis pod 部署到這些命名空間:
$ kubectl create deploy redis-dev --image=redis:alpine -n dev
deployment.apps/redis-dev created
$ kubectl create deploy redis-stg --image=redis:alpine -n stg
deployment.apps/redis-stg created
接下來,我們驗證 pod 是否已建立並且處於健康狀態:
$ kubectl get pods -n dev
NAME READY STATUS RESTARTS AGE
redis-dev-7b647c797c-c2mmg 1/1 Running 0 16s
$ kubectl get pods -n stg
NAME READY STATUS RESTARTS AGE
redis-stg-d66978466-plfpv 1/1 Running 0 9s
在這裡,我們可以觀察到兩個 Pod 的狀態都是Running 。
現在,所需的設定已準備就緒。在接下來的部分中,我們將建立一些Service物件來與這些 pod 建立通訊。
3. 尋找ClusterIP服務的URL
在 Kubernetes 中,預設的服務類型是ClusterIP 。對於ClusterIP服務,我們可以使用服務名稱或其 IP 位址作為其 URL 。這允許我們將通訊限制為僅在叢集內。讓我們透過一個簡單的例子來理解這一點。
3.1.創建ClusterIP服務
首先,我們在兩個命名空間中建立ClusterIP Service物件:
$ kubectl expose deploy redis-dev --port 6379 --type ClusterIP -n dev
service/redis-dev exposed
$ kubectl expose deploy redis-stg --port 6379 --type ClusterIP -n stg
service/redis-stg exposed
在此範例中,我們使用expose命令來建立Service物件。 expose命令使用Deployment物件的選擇器並使用相同的選擇器建立Service 。
在以下部分中,我們將討論如何尋找這些服務的名稱並將其用作 URL。
3.2.在同一命名空間中使用ClusterIP服務的 URL
首先,我們使用[get](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#get)指令從dev命名空間中尋找服務名稱:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev ClusterIP 10.100.18.154 <none> 6379/TCP 9s
在輸出中,第一列顯示服務名稱。在我們的例子中,它是redis-dev 。
現在,讓我們exec在dev命名空間中的 Redis pod,使用redis-dev作為主機名稱連接到 Redis 伺服器,並執行PING命令:
$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-dev PING
PONG
/data # exit
在這裡,我們可以看到 Redis 伺服器回應了PONG訊息。
最後,我們執行exit指令退出pod。
3.3.從另一個命名空間使用ClusterIP服務的 URL
讓我們檢查一下ClusterIP服務 URL 的格式:
<service-name>.<namespace>.<cluster-name>:<service-port>
在上一個範例中,我們沒有使用namespace和cluster-name ,因為我們從相同的命名空間和叢集執行命令。除此之外,我們還跳過了service-port ,因為Service是使用預設的 Redis 連接埠6379公開的。
但是,我們需要指定一個命名空間名稱才能使用另一個命名空間的ClusterIP服務。讓我們透過一個例子來理解這一點。
首先,讓我們找出stg命名空間中的服務名稱:
$ kubectl get svc -n stg
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-stg ClusterIP 10.110.213.51 <none> 6379/TCP 9s
現在,讓我們執行exec在dev命名空間中的 Redis pod,使用redis-stg.stg作為主機名稱連接到 Redis 伺服器,並執行PING命令:
$ kubectl exec -it redis-dev-7b647c797c-c2mmg -n dev -- sh
/data # redis-cli -h redis-stg.stg PING
PONG
/data # exit
在此範例中,我們可以看到 Redis 伺服器發送了PONG回覆。
需要注意的重要一點是,我們使用了redis-stg.stg作為主機名,其中redis-stg是服務名稱, stg是建立Service物件的命名空間名稱。
3.4.打掃乾淨
在前面的範例中,我們了解如何使用Service名稱作為 URL。
現在,讓我們使用[delete](https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#delete)命令來清理dev和stg命名空間中的服務:
$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted
$ kubectl delete svc redis-stg -n stg
service "redis-stg" deleted
4. 尋找NodePort服務的URL
NodePort服務允許使用 Kubernetes 節點的 IP 位址和連接埠與應用程式進行外部連接。讓我們透過創建NodePort服務來理解這一點。
4.1.創建NodePort服務
首先,讓我們使用expose命令建立類型為NodePort Service :
$ kubectl expose deploy redis-dev --port 6379 --type NodePort -n dev
service/redis-dev exposed
接下來,我們驗證Service是否已建立:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev NodePort 10.111.147.176 <none> 6379:30243/TCP 2s
在這裡,我們可以看到Service類型是NodePort 。在倒數第二列中,它顯示 Kubernetes 節點的連接埠30243對應到 pod 的連接埠6379 。
現在,我們可以從叢集外部使用Kubernetes節點的IP位址和連接埠30243來存取Redis伺服器。讓我們看看實際情況。
4.2.使用NodePort服務的 URL
首先,我們找到 Kubernetes 節點的 IP 位址:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
baeldung Ready control-plane 24h v1.28.3 192.168.49.2 <none> Ubuntu 22.04.3 LTS 5.15.0-41-generic docker://24.0.7
在這裡,我們將-o wide選項與Node物件一起使用來顯示附加欄位。
在上面的輸出中,標題為INTERNAL-IP欄位顯示 Kubernetes 節點的 IP 位址。
現在,從外部計算機,使用192.168.49.2作為主機名, 30243作為連接埠號碼連接到 Redis 伺服器,並執行PING命令:
$ redis-cli -h 192.168.49.2 -p 30243 PING
PONG
在這裡,我們可以看到 Redis 伺服器回應了一則PONG訊息。
4.3.打掃乾淨
在下一節中,我們將看到LoadBalancer服務的用法。但在此之前,讓我們先從dev命名空間中清理NodePort服務:
$ kubectl delete svc redis-dev -n dev
service "redis-dev" deleted
5. 尋找LoadBalancer服務的URL
就像NodePort服務一樣, LoadBalancer服務也允許使用負載平衡器的 IP 位址與應用程式進行外部連接。為了理解這一點,讓我們創建一個LoadBalancer服務:
5.1.建立LoadBalancer服務
讓我們使用expose指令在dev命名空間中建立一個LoadBalancer服務:
$ kubectl expose deploy redis-dev --port 6379 --type LoadBalancer -n dev
service/redis-dev exposed
5.2.使用LoadBalancer服務的 URL
接下來,我們使用get命令來尋找負載平衡器的 IP 位址:
$ kubectl get svc -n dev
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
redis-dev LoadBalancer 10.111.167.249 192.168.49.10 6379:32637/TCP 7s
在此範例中,標題為EXTERNAL-IP欄位表示LoadBalancer服務的 IP 位址。
在我們的範例中,負載平衡器的 IP 位址是192.168.49.10 。
現在,從外部計算機,使用192.168.49.10作為主機名稱連接到 Redis 伺服器並執行PING命令:
$ redis-cli -h 192.168.49.10 PING
PONG
在輸出中,我們可以看到 Redis 伺服器回覆了一則PONG訊息。
6. 清理
刪除所有不需要的物件來整理叢集是一個很好的做法。這有助於我們透過減少硬體消耗來降低成本。
因此,讓我們使用delete命令來刪除dev和stg命名空間:
$ kubectl delete ns dev
namespace "dev" deleted
$ kubectl delete ns stg
namespace "stg" deleted
此指令刪除命名空間本身以及該命名空間中存在的所有物件。
在這裡,我們直接刪除了命名空間,因為這是測試設定。但是,我們在生產環境中執行刪除操作時應該非常小心。
七、結論
在本文中,我們討論如何在 Kubernetes 中尋找和使用服務的 URL。
首先,我們了解如何使用ClusterIP服務名稱作為來自相同命名空間和另一個命名空間的 URL。然後,我們討論如何尋找和使用NodePort服務的 URL。
最後,我們討論了使用負載平衡器的 IP 位址作為服務 URL。