使用服務公開應用程式

本頁說明如何在 Google Kubernetes Engine 叢集中建立 Kubernetes 服務。如需服務概念的相關說明和各種服務類型的討論,請參閱服務

簡介

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

服務有五種類型:

  • ClusterIP (預設)
  • NodePort
  • LoadBalancer
  • ExternalName
  • Headless

本主題附有幾項練習。在每項練習中,您會透過建立服務來建立部署,並公開該部署的 Pod,然後傳送 HTTP 要求至服務。

事前準備

如要準備這項工作,請執行下列步驟:

  • 確認您已啟用 Google Kubernetes Engine API。
  • 啟用 Google Kubernetes Engine API
  • 確認您已安裝 Cloud SDK
  • 設定預設的專案 ID
    gcloud config set project [PROJECT_ID]
  • 如果您使用區域叢集,請設定預設的運算區域
    gcloud config set compute/zone [COMPUTE_ZONE]
  • 如果您使用地區叢集,請設定預設的運算地區
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud 更新到最新版本:
    gcloud components update

建立 ClusterIP 類型的服務

kubectl apply

以下是部署的資訊清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"

將資訊清單複製到名為 my-deployment.yaml 的檔案,然後建立部署:

kubectl apply -f my-deployment.yaml

確認有三個 Pod 正在執行:

kubectl get pods

輸出會顯示三個執行中的 Pod:

NAME                              READY     STATUS    RESTARTS   AGE
service-how-to-76699757f9-h4xk4   1/1       Running   0          4s
service-how-to-76699757f9-tjcfq   1/1       Running   0          4s
service-how-to-76699757f9-wt9d8   1/1       Running   0          4s

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

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

該服務具有指定兩個標籤的選取器:

  • app: metrics
  • department: sales

在先前建立的部署中,每個 Pod 都會有這兩個標籤,因此部署中的 Pod 會成為這項服務的成員。

將資訊清單複製到名為 my-cip-service.yaml 的檔案,然後建立服務:

kubectl apply -f my-cip-service.yaml

請稍候幾分鐘,讓 Kubernetes 將穩定的內部位址指派給服務,並接著查看該服務:

kubectl get service my-cip-service --output yaml

輸出會顯示 clusterIP 的值。

spec:
  clusterIP: 10.59.241.241

請記下 clusterIP 的值,稍後將會用到。

主控台

建立部署

  1. 前往 GCP 主控台的「Google Kubernetes Engine 工作負載」選單。

    前往工作負載選單

  2. 按一下 [部署]

  3. 在「容器」方塊的「容器映像檔」中,輸入 gcr.io/google-samples/hello-app:2.0 並按一下 [完成]

  4. 在「應用程式名稱」中輸入 my-deployment

  5. 在「標籤」底下建立兩個標籤。將其中一個標籤的「鍵」設為 app,並將「值」設為 metrics;將另一個標籤的「鍵」設定為 department,並將「值」設定為 sales

  6. 從「叢集」下拉式選單中,選取需要的叢集。

  7. 按一下 [部署]

  8. 當您的部署就緒時,「部署作業詳細資料」頁面就會開啟,您可以看到您的部署具有一或多個執行中的 Pod。

建立服務來公開您的部署

  1. 在「部署詳細資料」頁面中,按一下 [公開]

  2. 在「新通訊埠對應」方塊中,將「通訊埠」設為 80,並將「目標通訊埠」設為 8080。將「通訊協定」的設定保留為 TCP。按一下 [完成]

  3. 在「服務類型」下拉式選單中,選取 [叢集 IP]

  4. 在「服務名稱」中輸入 my-cip-service

  5. 按一下 [公開]。

  6. 當您的服務就緒時,「服務詳細資料」頁面就會開啟,您可以看到服務的相關詳細資料。尤其是可以看到 Kubernetes 指派給服務的「叢集 IP」值,這是內部用戶端可以用來呼叫服務的 IP 位址。請記下「叢集 IP」的值,稍後將會用到。

存取您的服務

列出執行中的 Pod:

kubectl get pods

在輸出中,複製任何一個名稱開頭是 my-deployment 的 Pod。

NAME                               READY     STATUS    RESTARTS   AGE
my-deployment-6897d9577c-7z4fv     1/1       Running   0          5m

將殼層放入其中一個執行中的容器:

kubectl exec -it [YOUR_POD_NAME] -- sh

其中 [YOUR_POD_NAME]my-deployment 內其中一個 Pod 的名稱。

在您的殼層中安裝 curl

apk add --no-cache curl

在容器中,使用叢集 IP 位址和通訊埠 80 向您的服務發出要求。請注意,80 是您服務的 port 欄位值,您會使用這個通訊埠做為服務的用戶端。

curl [CLUSTER_IP]:80

其中 [CLUSTER_IP] 是服務中的 clusterIP 值。

您的要求會轉送至 TCP 通訊埠 8080 上其中一個成員 Pod,也就是 targetPort 欄位的值。請注意,服務的每個成員 Pod 都必須有監聽通訊埠 8080 的容器。

回應會顯示 hello-app 的輸出:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-76699757f9-hsb5x

若要結束殼層以返回容器,請輸入 exit

建立 NodePort 類型的服務

kubectl apply

以下是部署的資訊清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50000
spec:
  selector:
    matchLabels:
      app: metrics
      department: engineering
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: engineering
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50000"

請留意資訊清單中的 env 物件,env 物件會將執行中容器的 PORT 環境變數值指定為 50000hello-app 應用程式會監聽 PORT 環境變數指定的通訊埠,因此在本練習中,您會告知容器監聽通訊埠 50000。

將資訊清單複製到名為 my-deployment-50000.yaml 的檔案,然後建立部署:

kubectl apply -f my-deployment-50000.yaml

確認有三個 Pod 正在執行:

kubectl get pods

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

apiVersion: v1
kind: Service
metadata:
  name: my-np-service
spec:
  type: NodePort
  selector:
    app: metrics
    department: engineering
  ports:
  - protocol: TCP
    port: 80
    targetPort: 50000

將資訊清單複製到名為 my-np-service.yaml 的檔案,然後建立服務:

kubectl apply -f my-np-service.yaml

查看服務:

kubectl get service my-np-service --output yaml

輸出會顯示 nodePort 的值。

...
  spec:
    ...
    ports:
    - nodePort: 30876
      port: 80
      protocol: TCP
      targetPort: 50000
    selector:
      app: metrics
      department: engineering
    sessionAffinity: None
    type: NodePort
...

如果叢集中的節點具有外部 IP 位址,請找出其中一個節點的外部 IP 位址:

kubectl get nodes --output wide

輸出會顯示節點的外部 IP 位址:

NAME          STATUS    ROLES     AGE    VERSION        EXTERNAL-IP
gke-svc-...   Ready     none      1h     v1.9.7-gke.6   203.0.113.1

並非所有叢集的節點都有外部 IP 位址,像是私人叢集中的節點就沒有外部 IP 位址。

建立防火牆規則來允許節點通訊埠上的 TCP 流量:

gcloud compute firewall-rules create test-node-port --allow tcp:[NODE_PORT]

其中:[NODE_PORT] 是服務的 nodePort 欄位值。

主控台

建立部署

  1. 前往 GCP 主控台的「Google Kubernetes Engine 工作負載」選單。

    前往工作負載選單

  2. 按一下 [部署]

  3. 在「容器」方塊的「容器映像檔」中,輸入 gcr.io/google-samples/hello-app:2.0。按一下 [新增環境變數],並在「鍵」中輸入 PORT,以及在「值」中輸入 50000。按一下 [完成]

  4. 在「配置」區段的「應用程式名稱」 中輸入 my-deployment-50000

  5. 在「標籤」底下建立兩個標籤。將其中一個標籤的「鍵」設為 app,並將「值」設為 metrics;將另一個標籤的「鍵」設定為 department,並將「值」設定為 engineering

  6. 從「叢集」下拉式選單中,選取需要的叢集。

  7. 按一下 [部署]

  8. 當您的部署就緒時,「部署作業詳細資料」頁面就會開啟,您可以看到您的部署具有一或多個執行中的 Pod。

建立服務來公開您的部署

  1. 在「部署作業詳細資料」頁面的「服務」下方,按一下 [公開]

  2. 在「新通訊埠對應」方塊中,將「通訊埠」設為 80,並將「目標通訊埠」設為 50000。將「通訊協定」的設定保留為 TCP。按一下 [完成]

  3. 在「服務類型」下拉式選單中,選取 [節點通訊埠]

  4. 在「服務名稱」中輸入 my-np-service

  5. 按一下 [公開]。

  6. 當您的服務就緒時,「服務詳細資料」頁面就會開啟,您可以看到服務的相關詳細資料。尤其在「通訊埠」底下,可以看到 Kubernetes 指派給服務的「節點通訊埠」值。請記下「節點通訊埠」的值,稍後將會用到。

建立節點通訊埠的防火牆規則

  1. 前往 GCP 主控台的「防火牆規則」選單。

    前往防火牆規則選單

  2. 按一下 [建立防火牆規則]

  3. 在「名稱」中輸入 test-node-port

  4. 從「目標」下拉式選單中,選取 [網路中的所有執行個體]

  5. 在「來源 IP 範圍」中輸入 0.0.0.0/0

  6. 在「指定的通訊協定和通訊埠」底下,選取 [tcp] 並輸入您的節點通訊埠值。

  7. 按一下 [建立]。

找出您其中一個叢集節點的外部 IP 位址。

  1. 前往 GCP 主控台的 Google Kubernetes Engine 選單。

    前往 Google Kubernetes Engine 選單

  2. 按一下您要在本練習使用的叢集名稱。

  3. 在「節點集區」底下,按一下執行個體群組的名稱即可顯示節點清單。記下其中一個節點的外部 IP 位址。

存取您的服務

在瀏覽器的網址列中,輸入 [NODE_IP_ADDRESS]:[NODE_PORT]

其中:

  • [NODE_IP_ADDRESS] 是您其中一個節點的外部 IP 位址。
  • [NODE_PORT] 是您的節點通訊埠值。

回應會顯示 hello-app 的輸出:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50000-695955857d-q76pb

建立 LoadBalancer 類型的服務

kubectl apply

以下是部署的資訊清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment-50001
spec:
  selector:
    matchLabels:
      app: products
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: products
        department: sales
    spec:
      containers:
      - name: hello
        image: "gcr.io/google-samples/hello-app:2.0"
        env:
        - name: "PORT"
          value: "50001"

請注意,這個部署中的容器將會監聽通訊埠 50001。

將資訊清單複製到名為 my-deployment-50001.yaml 的檔案,然後建立部署:

kubectl apply -f my-deployment-50001.yaml

確認有三個 Pod 正在執行:

kubectl get pods

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

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  selector:
    app: products
    department: sales
  ports:
  - protocol: TCP
    port: 60000
    targetPort: 50001

將資訊清單複製到名為 my-lb-service.yaml, 的檔案,然後建立服務:

kubectl apply -f my-lb-service.yaml

建立 LoadBalancer 類型的服務時,Google Cloud 控制器會喚醒並設定網路負載平衡器。請稍候幾分鐘,讓控制器設定網路負載平衡器並產生穩定的 IP 位址。

查看服務:

kubectl get service my-lb-service --output yaml

輸出會在 loadBalancer:ingress: 底下顯示穩定的外部 IP 位址。

...
spec:
  ...
  ports:
  - ...
    port: 60000
    protocol: TCP
    targetPort: 50001
  selector:
    app: products
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.10

主控台

建立部署

  1. 前往 GCP 主控台的「Google Kubernetes Engine 工作負載」選單。

    前往工作負載選單

  2. 按一下 [部署]

  3. 在「容器」方塊的「容器映像檔」中,輸入 gcr.io/google-samples/hello-app:2.0。按一下 [新增環境變數],並在「鍵」中輸入 PORT,以及在「值」中輸入 50001。然後按一下 [完成]

  4. 在「應用程式名稱」中輸入 my-deployment-50001

  5. 在「標籤」底下建立兩個標籤。將其中一個標籤的「鍵」設為 app,並將「值」設為 products;將另一個標籤的「鍵」設定為 department,並將「值」設定為 sales

  6. 從「叢集」下拉式選單中,選取需要的叢集。

  7. 按一下 [部署]

  8. 當您的部署就緒時,「部署作業詳細資料」頁面就會開啟,您可以看到您的部署具有一或多個執行中的 Pod。

建立服務來公開您的部署

  1. 在「部署詳細資料」頁面中,按一下 [公開]

  2. 在「新通訊埠對應」方塊中,將「通訊埠」設為 60000,並將「目標通訊埠」設為 50001。將「通訊協定」的設定保留為 TCP。按一下 [完成]

  3. 在「服務類型」下拉式選單中,選取 [負載平衡器]

  4. 在「服務名稱」中輸入 my-lb-service

  5. 按一下 [公開]。

  6. 當您的服務就緒時,「服務詳細資料」頁面就會開啟,您可以看到服務的相關詳細資料。尤其是可以看到負載平衡器的外部 IP 位址。請記下負載平衡器的 IP 位址,稍後將會使用。

存取您的服務

請稍候幾分鐘,讓 GKE 設定負載平衡器。

在瀏覽器的網址列中,輸入 [LOAD_BALANCER_ADDRESS]:60000

其中,[LOAD_BALANCER_ADDRESS] 是負載平衡器的外部 IP 位址。

回應會顯示 hello-app 的輸出:

Hello, world!
Version: 2.0.0
Hostname: service-how-to-50001-644f8857c7-xxdwg

請注意,服務中的 port 值為任意值,上述範例使用 60000 的 port 值來示範這點。

建立 ExternalName 類型的服務

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

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

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

在上述範例中,DNS 名稱為 my-xn-service.default.svc.cluster.local。內部用戶端向 my-xn-service.default.svc.cluster.local 發出要求時,系統會將要求重新導向至 example.com。

使用 kubectl expose 建立服務

除了編寫服務資訊清單以外,您也可以使用 kubectl expose 建立服務來公開部署。

如要公開本主題前面所述的 my-deployment,您可以輸入這個指令:

kubectl expose deployment my-deployment --name my-cip-service \
    --type ClusterIP --protocol TCP --port 80 --target-port 8080

如要公開本主題前面所述的 my-deployment-50000,您可以輸入這個指令:

kubectl expose deployment my-deployment-50000 --name my-np-service \
    --type NodePort --protocol TCP --port 80 --target-port 50000

如要公開本主題前面所述的 my-deployment-50001,您可以輸入這個指令:

kubectl expose deployment my-deployment-50001 --name my-lb-service \
    --type LoadBalancer --port 60000 --target-port 50001

清除所用資源

完成本頁的練習後,請按照下列步驟移除資源,以免您的帳戶產生不必要的費用:

kubectl apply

刪除您的服務

kubectl delete services my-cip-service my-np-service my-lb-service

刪除您的部署

kubectl delete deployments my-deployment my-deployment-50000 my-deployment-50001

刪除您的防火牆規則

gcloud compute firewall-rules delete test-node-port

主控台

刪除您的服務

  1. 前往 GCP 主控台的「Google Kubernetes Engine 服務」選單。

    前往服務選單

  2. 依序按一下 [my-cip-service] 和 [刪除]

  3. 依序按一下 [my-np-service] 和 [刪除]

  4. 依序按一下 [my-lb-service] 和 [刪除]

刪除您的部署

  1. 前往 GCP 主控台的「Google Kubernetes Engine 工作負載」選單。

    前往工作負載選單

  2. 依序按一下 [my-deployment] 和 [刪除]。讓「刪除水平 Pod 自動配置器 my-deployment-hpa」方塊保持已選取的狀態,然後按一下 [刪除]

  3. 依序按一下 [my-deployment-50000] 和 [刪除]。讓「刪除水平 Pod 自動配置器 my-deployment-50000-hpa」方塊保持已選取的狀態,然後按一下 [刪除]

  4. 依序按一下 [my-deployment-50001] 和 [刪除]。讓「刪除水平 Pod 自動配置器 my-deployment-50001-hpa」方塊保持已選取的狀態,然後按一下 [刪除]

刪除您的防火牆規則

  1. 前往 GCP 主控台的「防火牆規則」選單。

    前往防火牆規則選單

  2. 依序按一下 [test-node-port] 和 [刪除]

後續步驟

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

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

這個網頁
Kubernetes Engine 說明文件