服務

本頁面說明 Kubernetes 服務及其在 Google Kubernetes Engine 中的用途。如要瞭解如何建立服務,請參閱使用服務公開應用程式

什麼是服務?

服務的概念是將一組 Pod 端點組成單一資源。 您可以設定以各種方式存取這組 Pod 端點。根據預設,您會獲得穩定的叢集 IP 位址,讓位於叢集內的用戶端用來聯絡服務中的 Pod。用戶端會將要求傳送至穩定的 IP 位址,而要求會轉送至服務中的一個 Pod。

服務會透過選取器識別其成員 Pod。如要讓 Pod 成為服務的成員,Pod 必須具有選取器中指定的所有標籤。 標籤是附加在物件上的任意鍵/值組合。

以下服務資訊清單有指定兩個標籤的選取器。selector 欄位表示同時具有 app: metrics 標籤與 department:engineering 標籤的任何 Pod 都是這個服務的成員。

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: engineering
  ports:
  ...

為什麼要使用服務?

在 Kubernetes 叢集中,每個 Pod 都有內部 IP 位址。但部署中的 Pod 會變動,其 IP 位址也會變更。因此,直接使用 Pod IP 位址並不合理。透過服務,您可獲得一個在服務生命週期內持續存在的穩定 IP 位址,甚至在成員 Pod 的 IP 位址變更時仍不會改變。

服務也能提供負載平衡。用戶端呼叫單一穩定的 IP 位址,而用戶端的要求會平均分配到屬於服務成員的 Pod 之間。

服務類型

服務有五種類型:

  • ClusterIP (預設):內部用戶端將要求傳送至穩定的內部 IP 位址。

  • NodePort:用戶端針對服務指定的一或多個 nodePort 值,將要求傳送至節點的 IP 位址。

  • LoadBalancer:用戶端將要求傳送至網路負載平衡器的 IP 位址。

  • ExternalName:內部用戶端使用服務的 DNS 名稱做為外部 DNS 名稱的別名。

  • 無介面:若您想要將 Pod 組成資源,但不需要穩定的 IP 位址,您可以使用無介面服務

NodePort 類型是 ClusterIP 類型的擴充功能。因此,NodePort 類型的服務具有一個叢集 IP 位址。

LoadBalancer 類型是 NodePort 類型的擴充功能。因此,LoadBalancer 類型的服務具有一個叢集 IP 位址及一或多個 nodePort 值。

ClusterIP 服務類型

建立 ClusterIP 服務類型時,Kubernetes 會建立可從叢集中的節點存取的穩定 IP 位址。

以下是 ClusterIP 服務類型的資訊清單:

apiVersion: v1
kind: Service
metadata:
  name: my-cip-service
spec:
  selector:
    app: metrics
    department: sales
  type: ClusterIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

您可以使用 kubectl apply -f [MANIFEST_FILE] 建立服務。建立服務之後,您可使用 kubectl get service 查看穩定的 IP 位址:

NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)
my-cip-service   ClusterIP   10.11.247.213   none          80/TCP

叢集中的用戶端會使用叢集 IP 位址以及服務資訊清單的 port 欄位中指定的 TCP 通訊埠來呼叫服務。要求會轉送至 targetPort 欄位指定的 TCP 通訊埠上其中一個成員 Pod。因此,在上述範例中,用戶端會在 TCP 通訊埠 80 上,從 10.11.247.213 呼叫服務。要求會轉送至 TCP 通訊埠 8080 上的其中一個成員 Pod。請注意,成員 Pod 必須有監聽 TCP 通訊埠 8080 的容器。如果沒有任何監聽通訊埠 8080 的容器,用戶端會看到類似「無法連接」或「無法連上這個網站」的訊息。

NodePort 服務類型

建立 NodePort 服務類型時,Kubernetes 會提供 nodePort 值。接著,您可使用任何節點的 IP 位址搭配 nodePort 值來存取服務。

以下是 NodePort 服務類型的資訊清單:

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  selector:
    app: products
    department: sales
  type: NodePort
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

建立服務之後,您可以使用 kubectl get service -o yaml 查看其規格,並查看 nodePort 值。

spec:
  clusterIP: 10.11.254.114
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 32675
    port: 80
    protocol: TCP
    targetPort: 8080

外部用戶端會使用節點的外部 IP 位址搭配 nodePort 指定的 TCP 通訊埠來呼叫服務。要求會轉送至 targetPort 欄位指定的 TCP 通訊埠上的其中一個成員 Pod。

舉例來說,假設其中一個叢集節點的外部 IP 位址為 203.0.113.2,那麼在上述範例中,外部用戶端會在 TCP 通訊埠 32675 上,從 203.0.113.2 呼叫服務。要求會轉送至 TCP 通訊埠 8080 上的其中一個成員 Pod。成員 Pod 必須有監聽 TCP 通訊埠 8080 的容器。

NodePort 服務類型是 ClusterIP 服務類型的擴充功能。因此,內部用戶端可透過兩種方式呼叫服務:

  • 使用 clusterIPport
  • 使用節點的內部 IP 位址和 nodePort

在某些叢集配置中, Google Cloud HTTP(S) 負載平衡器 會使用 NodePort 服務類型。詳情請參閱使用輸入設定 HTTP 負載平衡

請注意,HTTP(S) 負載平衡器是一種 Proxy 伺服器,與網路負載平衡器全不同。詳情請參閱本主題 LoadBalancer 服務類型底下的說明。

LoadBalancer 服務類型

當您建立 LoadBalancer 服務類型時,系統會喚醒 Google Cloud 控制器,並在您的專案中設定網路負載平衡器。負載平衡器具有可從專案外部存取的穩定 IP 位址。

請注意,網路負載平衡器並非 Proxy 伺服器。它會轉送封包,但不會變更來源和目的地 IP 位址。

以下是 LoadBalancer 服務類型的資訊清單:

apiVersion: v1
kind: Service
metadata:
  name: my-nlb-service
spec:
  selector:
    app: metrics
    department: engineering
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080

建立服務之後,您可以使用 kubectl get service -o yaml 查看服務規格,並查看穩定的外部 IP 位址:

spec:
  clusterIP: 10.11.242.115
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 32676
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: engineering
  sessionAffinity: None
  type: LoadBalancer
  status:
    loadBalancer:
      ingress:
      - ip: 203.0.113.100

在輸出中,網路負載平衡器的 IP 位址會顯示在 loadBalancer:ingress: 底下。外部用戶端會使用負載平衡器的 IP 位址和 port 指定的 TCP 通訊埠來呼叫服務。要求會轉遞至 targetPort 指定的 TCP 通訊埠上的其中一個成員 Pod。 因此,在上述範例中,用戶端會在 TCP 通訊埠 80 上從 203.0.113.100 呼叫服務。要求會轉送至 TCP 通訊埠 8080 上的其中一個成員 Pod。 成員 Pod 必須有監聽 TCP 通訊埠 8080 的容器。

LoadBalancer 服務類型是 NodePort 類型的擴充功能,它是 ClusterIP 類型的擴充功能。

ExternalName 服務類型

ExternalName 服務類型可針對外部 DNS 名稱提供內部別名。內部用戶端會使用內部 DNS 名稱提出要求,要求會重新導向至外部名稱。

以下是 ExternalName 服務類型的資訊清單:

apiVersion: v1
kind: Service
metadata:
  name: my-xn-service
spec:
  type: ExternalName
  externalName: example.com

建立服務時,Kubernetes 會建立內部用戶端可用來呼叫服務的 DNS 名稱。在上述範例中,DNS 名稱為 my-xn-service.default.svc.cluster.local。內部用戶端向 my-xn-service.default.svc.cluster.local 提出要求時,要求會重新導向至 example.com。

ExternalName 服務類型與其他服務類型完全不同。事實上,ExternalName 服務類型並不符合本主題開頭所述的服務定義。ExternalName 服務類型與一組 Pod 無關,也沒有穩定的 IP 位址。相反地,ExternalName 服務類型是從內部 DNS 名稱到外部 DNS 名稱的對應。

服務抽象層

服務是抽象層,而不是監聽某個網路介面的程序。抽象層有一部分會在叢集節點的 iptables 規則中實作。視服務類型而定,抽象層的其他部分會透過 網路負載平衡HTTP(S) 負載平衡實作。

任意服務通訊埠

服務資訊清單中 port 欄位的值可隨意更改。但 targetPort 的值無法隨意更改。每個成員 Pod 都必須有一個監聽 targetPort 的容器。

以下是 port 值為 50000 的 LoadBalancer 服務類型:

apiVersion: v1
kind: Service
metadata:
  name: my-ap-service
spec:
  clusterIP: 10.11.241.93
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30641
    port: 50000
    protocol: TCP
    targetPort: 8080
  selector:
    app: parts
    department: engineering
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.200

用戶端會在 TCP 通訊埠 50000 上從 203.0.113.200 呼叫服務。要求會轉送至 TCP 通訊埠 8080 上的其中一個成員 Pod。

多個通訊埠

服務的 ports 欄位是 ServicePort 物件的陣列。ServicePort 物件有以下欄位:

  • name
  • protocol
  • port
  • targetPort
  • nodePort

如果您有多個 ServicePort,每個 ServicePort 的名稱均不得重複。

以下是具有兩個 ServicePort 物件的 LoadBalancer 服務類型:

apiVersion: v1
kind: Service
metadata:
  name: my-tp-service
spec:
  clusterIP: 10.11.242.196
  externalTrafficPolicy: Cluster
  ports:
  - name: my-first-service-port
    nodePort: 31233
    port: 60000
    protocol: TCP
    targetPort: 50000
  - name: my-second-service-port
    nodePort: 31081
    port: 60001
    protocol: TCP
    targetPort: 8080
  selector:
    app: tests
    department: engineering
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.201

在上述範例中,如果用戶端在 TCP 通訊埠 60000 上從 203.0.113.201 呼叫服務,要求會轉送至 TCP 通訊埠 50000 上的成員 Pod。不過,如果用戶端在 TCP 通訊埠 60001 上從 203.0.113.201 呼叫服務,要求則會轉送至 TCP 通訊埠 8080 上的成員 Pod。

每個成員 Pod 都必須有一個監聽 TCP 通訊埠 50000 的容器,以及一個監聽 TCP 通訊埠 8080 的容器。這可以是具有兩個執行緒的單一容器,或在同一個 Pod 中執行的兩個容器。

服務端點

建立服務時,Kubernetes 會建立端點物件,其名稱與您的服務名稱相同。Kubernetes 會使用端點物件來追蹤哪些 Pod 是服務的成員。

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Kubernetes Engine 說明文件