如何在 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。