使用 Google Cloud Platform 服務代理程式存取 Cloud Pub/Sub

本教學課程示範如何使用 Kubernetes 服務目錄和 Google Cloud Platform (GCP) 服務代理程式將 GKE 上執行的應用程式連線到 Cloud Pub/Sub

為什麼要使用服務目錄?

服務目錄可讓應用程式在叢集上執行,不需要手動匯入憑證或端點等資訊,便能輕鬆找到外部服務並完成連線。系統會為外部服務依附元件建模,將元件視為 Kubernetes 資源,以便輕鬆將資源整合到現有部署程序。

在本教學課程中,我們將使用服務目錄的下列功能:

  • 透過服務目錄探索服務代理程式中的 Google Cloud Platform 服務。
  • 「佈建」一個「服務執行個體」以建立 Cloud 資源。
  • 「繫結」Kubernetes 應用程式中所佈建的「服務執行個體」,以將憑證插入叢集中。
  • 在應用程式中使用「服務繫結」,以存取指向 Cloud 資源的「服務執行個體」

如要深入瞭解服務目錄,請參閱 Kubernetes 服務目錄說明文件

目標

本教學課程包含下列步驟:

  1. 建立命名空間
  2. 建立身分與存取權管理 (IAM) 服務帳戶
  3. 建立 Pub/Sub 主題
  4. 為主題建立 Pub/Sub 訂閱項目
  5. 使用示範應用程式來測試 Pub/Sub 服務
  6. 清理

事前準備

請依照下列步驟啟用 Kubernetes Engine API:
  1. 造訪 Google Cloud Platform 主控台的 Kubernetes Engine 頁面
  2. 建立或選取專案。
  3. 等待 API 和相關服務完成啟用。這可能需要幾分鐘的時間。
  4. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

請安裝下列指令列工具,我們將在本教學課程中使用這些工具:

  • gcloud 可用於建立及刪除 Kubernetes Engine 叢集。gcloud 包含在 Google Cloud SDK 中。
  • kubectl 可用於管理 Kubernetes,這是 Kubernetes Engine 使用的叢集自動化調度管理系統。您可以使用 gcloud 來安裝 kubectl
    gcloud components install kubectl

設定 gcloud 指令列工具的預設設定

為了節省您在 gcloud 指令列工具中輸入專案 IDCompute Engine 區域選項的時間,建議您採用下列預設設定:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

設定服務目錄

  • 在您的 GKE 叢集中安裝服務目錄和服務代理程式。
  • 在指令列中使用 kubectl 列出所有服務目錄程序,驗證服務目錄是否正在執行:

    kubectl get deployment -n service-catalog

    所有部署都應回報為 AVAILABLE

  • (選用) 安裝 svcat CLI 工具,這可以改善服務目錄資源提供的使用者體驗。

步驟 1:建立命名空間

這是選用步驟,但建議您建立命名空間,以便更輕鬆地執行本教學課程的清理步驟。

將命名空間名稱的別名設為環境變數:

NAMESPACE=pubsub-app

為使用 Cloud Pub/Sub 的應用程式建立命名空間。請執行下列指令:

kubectl create namespace [NAMESPACE]

指令會輸出下列訊息:

namespace "pubsub-app" created

步驟 2:建立 IAM 服務帳戶

您必須具備 IAM 服務帳戶才能在應用程式中使用 GCP 服務。在本教學課程中,我們將建立 ID 為 pubsub-sa 的服務帳戶。

此外,您也可以使用服務目錄來建立 IAM 服務帳戶。這項作業可以透過佈建和繫結到 cloud-iam-service-account 服務類別的服務執行個體來完成。

佈建 IAM 服務帳戶執行個體

請使用下列指令將服務帳戶名稱儲存在環境變數中:

SERVICE_ACCOUNT_ID=pubsub-sa

svcat

請使用 svcat 指令來佈建服務帳戶執行個體:

svcat provision gcp-iam \
    --class cloud-iam-service-account \
    --plan beta \
    --namespace [NAMESPACE] \
    --param accountId=$SERVICE_ACCOUNT_ID

指令會輸出下列訊息:

  Name:        gcp-iam
  Namespace:   pubsub-app
  Status:
  Class:       cloud-iam-service-account
  Plan:        beta

Parameters: accountId: pubsub-sa

請使用下列指令來檢查服務執行個體的狀態:

svcat get instance gcp-iam --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

   NAME     NAMESPACE              CLASS             PLAN   STATUS
+---------+------------+---------------------------+------+--------+
  gcp-iam   pubsub-app   cloud-iam-service-account   beta   Ready

當服務執行個體的 STATUS 顯示為 Ready 時,代表已成功佈建。

kubectl

請使用下列規格來建立名為 iam_instance.yaml 的 ServiceInstance YAML 檔案。確認 serviceAccount 欄位的值與 echo $SERVICE_ACCOUNT_ID 相同:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: gcp-iam
  namespace: pubsub-app
spec:
  # This should match with a SERVICE EXTERNAL NAME
  # in the list of available services.
  clusterServiceClassExternalName: cloud-iam-service-account
  # This should match with a PLAN EXTERNAL NAME
  # in the list of available service plans.
  clusterServicePlanExternalName: beta
  parameters:
    accountId: pubsub-sa

請使用 kubectl 指令來佈建使用 YAML 檔案的服務帳戶執行個體:

kubectl apply -f iam_instance.yaml

指令會輸出下列訊息:

serviceinstance "gcp-iam" created

請使用下列指令來檢查服務執行個體的狀態:

kubectl get serviceinstances gcp-iam -n [NAMESPACE] -o 'custom-columns=INSTANCE-NAME:.metadata.name,SERVICE:.spec.clusterServiceClassExternalName,PLAN:.spec.clusterServicePlanExternalName,STATUS:.status.conditions[0].reason'

畫面會顯示類似以下的輸出內容:

INSTANCE-NAME   SERVICE                     PLAN      STATUS
gcp-iam         cloud-iam-service-account   beta      ProvisionedSuccessfully

服務執行個體佈建成功後,您也可以在 Cloud 主控台中查看相對應的 IAM 服務帳戶 pubsub-sa@[PROJECT_ID].iam.gserviceaccount.com

繫結到 IAM 服務帳戶執行個體

繫結到服務帳戶執行個體將會在相同的命名空間中建立一個密鑰。這個密鑰會包含服務帳戶名稱和私密金鑰,方便應用程式參照。

請使用下列指令將密鑰名稱儲存在環境變數中:

SA_SECRET_NAME=pubsub-credentials

svcat

請使用 svcat 指令來繫結到服務帳戶執行個體:

svcat bind gcp-iam --namespace [NAMESPACE] --secret-name $SA_SECRET_NAME

指令會輸出下列訊息:

  Name:        gcp-iam
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-iam

Parameters: {}

請使用下列指令來檢查服務繫結的狀態:

svcat get binding gcp-iam --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

   NAME     NAMESPACE    INSTANCE   STATUS
+---------+------------+----------+--------+
  gcp-iam   pubsub-app   gcp-iam    Ready

請先等待服務繫結的狀態顯示為 Ready,再繼續進行下一步。這可能需要一分鐘的時間。

kubectl

請使用下列規格來建立名為 iam_binding.yaml 的 ServiceBinding YAML 檔案:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-iam
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-iam
  secretName: pubsub-credentials

請執行下列指令來建立服務繫結:

kubectl apply -f iam_binding.yaml

請執行下列指令來檢查服務繫結的狀態:

kubectl get servicebindings gcp-iam -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

畫面會顯示類似以下的輸出內容:

BINDING-NAME      SERVICE-INSTANCE   STATUS               OUTPUT-SECRET
gcp-iam           gcp-iam            InjectedBindResult   gcp-iam

服務繫結成功建立後,請使用下列 kubectl 指令來確認現有密鑰:

kubectl get secrets $SA_SECRET_NAME --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

NAME                 TYPE      DATA      AGE
pubsub-credentials   Opaque    2         1m

您也可以查看包含服務帳戶憑證的密鑰:

kubectl get secrets $SA_SECRET_NAME --namespace [NAMESPACE] -o yaml

請注意,privateKeyData 值採用 Base64 編碼,且包含服務帳戶私密金鑰。

步驟 3:建立 Pub/Sub 主題

佈建 Pub/Sub 服務執行個體

現在我們將使用服務目錄來佈建 Pub/Sub 服務執行個體。這樣做會為應用程式建立 Pub/Sub 主題,以便發佈及讀取訊息。

svcat

請使用 svcat 指令來佈建 Pub/Sub 服務執行個體:

svcat provision gcp-pubsub \
    --class cloud-pubsub \
    --plan beta \
    --namespace [NAMESPACE] \
    --param topicId=pubsub-app

指令會輸出下列訊息:

  Name:        gcp-pubsub
  Namespace:   pubsub-app
  Status:
  Class:       cloud-pubsub
  Plan:        beta

Parameters: topicId: pubsub-app

請使用下列指令來檢查服務執行個體的狀態:

svcat get instance gcp-pubsub --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

     NAME      NAMESPACE       CLASS       PLAN   STATUS
+------------+------------+--------------+------+--------+
  gcp-pubsub   pubsub-app   cloud-pubsub   beta   Ready

當服務執行個體的 STATUS 顯示為 Ready 時,代表已成功佈建。

kubectl

請使用下列規格來建立名為 pubsub_instance.yaml 的 ServiceInstance YAML 檔案:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceInstance
metadata:
  name: gcp-pubsub
  namespace: pubsub-app
spec:
  clusterServiceClassExternalName: cloud-pubsub
  # This should match with a PLAN EXTERNAL NAME
  # in the list of available service plans for Pub/Sub.
  clusterServicePlanExternalName: beta
  parameters:
    topicId: pubsub-app

請使用下列指令來佈建 Pub/Sub 服務執行個體:

kubectl create -f pubsub_instance.yaml

指令會輸出下列訊息:

serviceinstance "gcp-pubsub" created

請使用下列指令來檢查 Pub/Sub 服務執行個體的狀態:

kubectl get serviceinstances gcp-pubsub -n [NAMESPACE] -o 'custom-columns=INSTANCE-NAME:.metadata.name,SERVICE:.spec.clusterServiceClassExternalName,PLAN:.spec.clusterServicePlanExternalName,STATUS:.status.conditions[0].reason'

指令會輸出類似以下的狀態訊息:

INSTANCE-NAME   SERVICE        PLAN      STATUS
gcp-pubsub      cloud-pubsub   beta      ProvisionedSuccessfully

Pub/Sub 服務執行個體佈建成功後,您也可以在 Cloud Console 中查看相對應的 Pub/Sub 主題 projects/[PROJECT_ID]/topics/pubsub-app

繫結到 Pub/Sub 服務執行個體

繫結到 Pub/Sub 服務執行個體可以執行下列動作:

  • 授予特定 IAM 服務帳戶存取 Pub/Sub 服務的適當權限。
  • 將存取服務執行個體的必要資訊以 Kubernetes 密鑰形式提供給 Kubernetes 應用程式。
  • (選用) 為 Pub/Sub 主題建立訂閱項目。

這是示範應用程式的必要條件,因為應用程式必須獲准存取服務,才能以服務帳戶的假設身分執行作業,發佈訊息到 Pub/Sub 主題。

Pub/Sub 服務類別具有多種服務繫結類型。首先,我們會建立類型為 publisher 的服務繫結,其中包含兩個角色:roles/pubsub.publisherroles/pubsub.viewer。這個繫結會允許我們的服務帳戶發佈訊息到這個主題,以及查看訊息。

提示:如要深入瞭解 Cloud Pub/Sub 的 IAM 角色與權限,請參閱 Cloud Pub/Sub 的 [存取權控管說明文件](/pubsub/docs/access-control#tbl_roles)。

svcat

請使用 svcat 指令以 publisher 的角色繫結到 Pub/Sub 主題:

svcat bind gcp-pubsub --namespace [NAMESPACE] --params-json '{
  "serviceAccount": "'${SERVICE_ACCOUNT_ID}'",
  "roles": [
    "roles/pubsub.publisher",
    "roles/pubsub.viewer"
  ]
}'

指令會輸出下列訊息 (serviceAccount 值可能是您之前建立的服務帳戶名稱):

  Name:        gcp-pubsub
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-pubsub

Parameters: roles:

  • roles/pubsub.publisher
  • roles/pubsub.viewer serviceAccount: pubsub-sa

請使用下列指令來檢查服務繫結的狀態:

svcat get binding gcp-pubsub --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

     NAME      NAMESPACE     INSTANCE    STATUS
+------------+------------+------------+--------+
  gcp-pubsub   pubsub-app   gcp-pubsub   Ready

請先等待服務繫結的狀態顯示為 Ready,再繼續進行下一步。這可能需要一分鐘的時間。

kubectl

請使用下列規格來建立名為 pubsub_binding.yaml 的 ServiceBinding YAML 檔案,並以 publisher 的角色繫結到 Pub/Sub 主題。確認 serviceAccount 欄位的值與 echo $SERVICE_ACCOUNT_ID 相同:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-pubsub
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-pubsub
  parameters:
    serviceAccount: pubsub-sa
    roles:
    - roles/pubsub.publisher
    - roles/pubsub.viewer

繫結到 Cloud Pub/Sub 服務執行個體:

kubectl create -f pubsub_binding.yaml

請執行下列指令來檢查服務繫結的狀態:

kubectl get servicebindings gcp-pubsub -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

指令會顯示 InjectedBindResult 狀態。

建立為繫結結果的 gcp-pubsub 密鑰會包含專案 (projectId)、服務帳戶 (serviceAccount) 和主題 ID (topicId)。執行下列指令可檢查密鑰:

kubectl get secrets gcp-pubsub --namespace [NAMESPACE] -o yaml

步驟 4:為主題建立 Pub/Sub 訂閱項目

繫結到 Pub/Sub 服務執行個體才能發佈到主題一樣,示範應用程式也需要服務繫結才能訂閱及讀取主題的訊息。

現在我們要為 Pub/Sub 服務執行個體建立另一個服務繫結,這次的類型為 subscriber,其中包含一個訂閱項目和兩個角色:roles/pubsub.subscriberroles/pubsub.viewer。這會為本主題建立 Pub/Sub 訂閱項目,並允許我們的服務帳戶提取及查看這個訂閱項目中的訊息。

svcat

請使用 svcat 指令以 subscriber 的角色繫結到 Pub/Sub 主題:

svcat bind gcp-pubsub \
    --name gcp-pubsub-subscription \
    --namespace [NAMESPACE] \
    --params-json '{
      "serviceAccount": "'${SERVICE_ACCOUNT_ID}'",
      "roles": [
        "roles/pubsub.subscriber",
        "roles/pubsub.viewer"
      ],
      "subscription": {
        "subscriptionId": "pubsub-app"
      }
    }'

指令會輸出下列訊息 (serviceAccount 值可能是您之前建立的服務帳戶名稱):

  Name:        gcp-pubsub-subscription
  Namespace:   pubsub-app
  Status:
  Instance:    gcp-pubsub

Parameters: roles:

  • roles/pubsub.subscriber
  • roles/pubsub.viewer serviceAccount: pubsub-sa subscription: subscriptionId: pubsub-app

請使用下列指令來檢查服務繫結的狀態:

svcat get binding gcp-pubsub-subscription --namespace [NAMESPACE]

畫面會顯示類似以下的輸出內容:

           NAME             NAMESPACE     INSTANCE    STATUS
+-------------------------+------------+------------+--------+
  gcp-pubsub-subscription   pubsub-app   gcp-pubsub   Ready

請先等待服務繫結的狀態顯示為 Ready,再繼續進行下一步。這可能需要一分鐘的時間。

kubectl

請建立名為 pubsub_subscription_binding.yaml 的 ServiceBinding YAML 檔案,並以 subscriber 的角色繫結到 Pub/Sub 主題。確認 serviceAccount 欄位的值與 echo $SERVICE_ACCOUNT_ID 相同:

apiVersion: servicecatalog.k8s.io/v1beta1
kind: ServiceBinding
metadata:
  name: gcp-pubsub-subscription
  namespace: pubsub-app
spec:
  instanceRef:
    name: gcp-pubsub
  parameters:
    serviceAccount: pubsub-sa
    roles:
    - roles/pubsub.subscriber
    - roles/pubsub.viewer
    subscription:
      subscriptionId: pubsub-app

繫結到 Cloud Pub/Sub 服務執行個體:

kubectl create -f pubsub_subscription_binding.yaml

請執行下列指令來檢查服務繫結的狀態:

kubectl get servicebindings gcp-pubsub-subscription -n [NAMESPACE] -o 'custom-columns=BINDING-NAME:.metadata.name,SERVICE-INSTANCE:.spec.instanceRef.name,STATUS:.status.conditions[0].reason,OUTPUT-SECRET:.spec.secretName'

指令會顯示 InjectedBindResult 狀態。

您可以在 Cloud 指控台中找到新的訂閱項目 projects/[PROJECT_ID]/subscriptions/pubsub-app。建立為繫結結果的 gcp-pubsub-subscription 密鑰會包含專案 (projectId)、服務帳戶 (serviceAccount)、主題 ID (topicId) 和訂閱 ID (subscriptionId)。執行下列指令可檢查密鑰:

kubectl get secrets gcp-pubsub-subscription --namespace [NAMESPACE] -o yaml

步驟 5:使用示範應用程式來測試 Pub/Sub 服務

在 GKE 叢集中執行示範應用程式來測試與 Cloud Pub/Sub 服務之間的連線。

請使用下列規格來建立名為 hello_pubsub_world.yaml 的 Kubernetes 工作檔案 (如果您手動建立了儲存服務帳戶私密金鑰的密鑰,請將 secretName 的值取代為 [SA_SECRET_NAME]):

apiVersion: batch/v1
kind: Job
metadata:
  name: hello-pubsub-world
  namespace: pubsub-app
spec:
  template:
    spec:
      volumes:
        # Make the 'pubsub-credentials' secret available as volume
        # 'google-cloud-key'.
        - name: google-cloud-key
          secret:
            secretName: pubsub-credentials
      restartPolicy: OnFailure
      containers:
        - name: hello-pubsub-world
          image: gcr.io/gcp-services/samples/hello-pubsub-world
          volumeMounts:
            # Mount the 'google-cloud-key' volume into the container file
            # system.
            - name: google-cloud-key
              mountPath: /var/secrets/google
          env:
            # Pass the path to the private key JSON file from the mounted volume
            # to the environment variable.
            - name: "GOOGLE_APPLICATION_CREDENTIALS"
              value: /var/secrets/google/privateKeyData

            # The two environment variables below come from the 'gcp-pubsub'
            # secret and, together, point at the Cloud Pub/Sub topic to use.
            - name: "GOOGLE_CLOUD_PROJECT_ID"
              valueFrom:
                secretKeyRef:
                  # Use the projectId value from the 'gcp-pubsub' secret created
                  # as a result of binding to the Pub/Sub service instance.
                  name: gcp-pubsub
                  key: projectId
            - name: "GOOGLE_CLOUD_PUBSUB_TOPIC"
              valueFrom:
                secretKeyRef:
                  # Use the topicId value from the 'gcp-pubsub' secret created
                  # as a result of binding to the Pub/Sub service instance.
                  name: gcp-pubsub
                  key: topicId

            # The environment variable below come from the
            # 'gcp-pubsub-subscription' secret and, together with the
            # GOOGLE_CLOUD_PROJECT_ID above, point at the Cloud Pub/Sub
            # subscription to use.
            - name: "GOOGLE_CLOUD_PUBSUB_SUBSCRIPTION"
              valueFrom:
                secretKeyRef:
                  # Use the subscriptionId value from the
                  # 'gcp-pubsub-subscription' secret created as a result of the
                  # subscription binding to the Pub/Sub service instance.
                  name: gcp-pubsub-subscription
                  key: subscriptionId

請注意以下值的使用方式:[SA_SECRET_NAME] (如果您建立新的 IAM 服務帳戶,則應該為 pubsub-credentials)、gcp-pubsubgcp-pubsub-subscription 密鑰,這些值會透過繫結到 IAM 服務帳戶和 Pub/Sub 服務執行個體來建立。

建立工作:

kubectl apply -f hello_pubsub_world.yaml

指令會輸出下列訊息:

job "hello-pubsub-world" created

查看 pod 清單:

kubectl get pods --namespace [NAMESPACE] --show-all

指令會顯示在該命名空間中執行的 pod 詳細資料,類似下列所示:

NAME                       READY     STATUS      RESTARTS   AGE
hello-pubsub-world-zh8hm   0/1       Completed   0          1m

等到 pod 的狀態顯示為 Completed 後,再使用下列指令來檢查該 pod 的記錄:

kubectl -n [NAMESPACE] logs [POD_NAME]

您應該會看到幾行包含項目的內容,類似下列所示:

Publishing 10 messages.
Publishing done.
Subscribing 10 messages.
Got message: "hello world #9"
Got message: "hello world #0"
Got message: "hello world #1"
Got message: "hello world #2"
Got message: "hello world #3"
Got message: "hello world #4"
Got message: "hello world #5"
Got message: "hello world #6"
Got message: "hello world #7"
Got message: "hello world #8"
Subscription done.

清理

如何避免系統向您的 Google Cloud Platform 帳戶收取在本教學課程中使用資源的相關費用:

  1. 刪除示範命名空間,這會一併刪除應用程式、服務繫結和服務執行個體:

    kubectl delete namespace [NAMESPACE]
  2. 如要深入瞭解如何清理服務目錄,請參閱這份指南

後續步驟

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

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

這個網頁
Kubernetes Engine 說明文件