使用服務連接前端到後端

這個任務示範如何建立前端和後端微服務。後端微服務是一個 hello 問候語服務。前端使用 nginx 和 Kubernetes 服務 (Service) 物件公開後端。

目標

  • 使用 Deployment 物件建立並執行範例 hello 後端微服務。
  • 使用 Service 物件將流量傳送到後端微服務的多個副本。
  • 也使用 Deployment 物件建立並執行 nginx 前端微服務。
  • 設定前端微服務將流量傳送到後端微服務。
  • 使用類型為 LoadBalancer 的 Service 物件,將前端微服務公開於叢集外部。

開始之前

您需要有一個 Kubernetes 叢集,並且必須設定 kubectl 命令列工具以與您的叢集通訊。建議在至少有兩個節點且節點不充當控制平面主機的叢集上執行本教學。如果您還沒有叢集,可以使用 minikube 建立一個,或者您可以使用以下 Kubernetes playground 之一

若要檢查版本,請輸入 kubectl version

這個任務使用具有外部負載平衡器的服務 (Service),這需要支援的環境。如果您的環境不支援,您可以改用 NodePort 類型的服務 (Service)。

使用 Deployment 建立後端

後端是一個簡單的 hello 問候語微服務。以下是後端 Deployment 的組態檔

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: hello
      tier: backend
      track: stable
  replicas: 3
  template:
    metadata:
      labels:
        app: hello
        tier: backend
        track: stable
    spec:
      containers:
        - name: hello
          image: "gcr.io/google-samples/hello-go-gke:1.0"
          ports:
            - name: http
              containerPort: 80
...

建立後端 Deployment

kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml

檢視關於後端 Deployment 的資訊

kubectl describe deployment backend

輸出結果類似於此

Name:                           backend
Namespace:                      default
CreationTimestamp:              Mon, 24 Oct 2016 14:21:02 -0700
Labels:                         app=hello
                                tier=backend
                                track=stable
Annotations:                    deployment.kubernetes.io/revision=1
Selector:                       app=hello,tier=backend,track=stable
Replicas:                       3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:                   RollingUpdate
MinReadySeconds:                0
RollingUpdateStrategy:          1 max unavailable, 1 max surge
Pod Template:
  Labels:       app=hello
                tier=backend
                track=stable
  Containers:
   hello:
    Image:              "gcr.io/google-samples/hello-go-gke:1.0"
    Port:               80/TCP
    Environment:        <none>
    Mounts:             <none>
  Volumes:              <none>
Conditions:
  Type          Status  Reason
  ----          ------  ------
  Available     True    MinimumReplicasAvailable
  Progressing   True    NewReplicaSetAvailable
OldReplicaSets:                 <none>
NewReplicaSet:                  hello-3621623197 (3/3 replicas created)
Events:
...

建立 hello 服務 (Service) 物件

從前端向後端發送請求的關鍵是後端服務 (Service)。服務 (Service) 會建立一個持久的 IP 位址和 DNS 名稱項目,以便始終可以存取後端微服務。服務 (Service) 使用選擇器來尋找它將流量路由到的 Pod。

首先,探索服務 (Service) 組態檔

---
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  selector:
    app: hello
    tier: backend
  ports:
  - protocol: TCP
    port: 80
    targetPort: http
...

在組態檔中,您可以看到名為 hello 的服務 (Service) 將流量路由到具有標籤 app: hellotier: backend 的 Pod。

建立後端服務 (Service)

kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml

在此時,您有一個後端 Deployment 正在執行您的 hello 應用程式的三個副本,並且您有一個可以將流量路由到它們的服務 (Service)。但是,此服務在叢集外部既不可用也無法解析。

建立前端

現在您已經讓後端執行起來,您可以建立一個可從叢集外部存取的前端,並透過代理請求連接到後端。

前端透過使用給予後端服務 (Service) 的 DNS 名稱,將請求傳送到後端工作 Pod。DNS 名稱是 hello,這是 examples/service/access/backend-service.yaml 組態檔中 name 欄位的值。

前端 Deployment 中的 Pod 執行一個 nginx 映像檔,該映像檔設定為將請求代理到 hello 後端服務 (Service)。以下是 nginx 組態檔

# The identifier Backend is internal to nginx, and used to name this specific upstream
upstream Backend {
    # hello is the internal DNS name used by the backend Service inside Kubernetes
    server hello;
}

server { listen 80;

location / {
    # The following statement will proxy traffic to the upstream named Backend
    proxy_pass http://Backend;
}

}

與後端類似,前端也有一個 Deployment 和一個服務 (Service)。後端和前端服務之間需要注意的一個重要差異是,前端服務 (Service) 的組態具有 type: LoadBalancer,這表示服務 (Service) 使用由您的雲端提供者佈建的負載平衡器,並且可以從叢集外部存取。

---
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    app: hello
    tier: frontend
  ports:
  - protocol: "TCP"
    port: 80
    targetPort: 80
  type: LoadBalancer
...
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      app: hello
      tier: frontend
      track: stable
  replicas: 1
  template:
    metadata:
      labels:
        app: hello
        tier: frontend
        track: stable
    spec:
      containers:
        - name: nginx
          image: "gcr.io/google-samples/hello-frontend:1.0"
          lifecycle:
            preStop:
              exec:
                command: ["/usr/sbin/nginx","-s","quit"]
...

建立前端 Deployment 和服務 (Service)

kubectl apply -f https://k8s.io/examples/service/access/frontend-deployment.yaml
kubectl apply -f https://k8s.io/examples/service/access/frontend-service.yaml

輸出結果驗證了兩個資源都已建立

deployment.apps/frontend created
service/frontend created

與前端服務 (Service) 互動

一旦您建立了 LoadBalancer 類型的服務 (Service),您可以使用此命令來尋找外部 IP

kubectl get service frontend --watch

這會顯示前端服務 (Service) 的組態並監看變更。最初,外部 IP 列為 <pending>

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)  AGE
frontend   LoadBalancer   10.51.252.116   <pending>     80/TCP   10s

但是,一旦佈建了外部 IP,組態就會更新,以在 EXTERNAL-IP 標題下包含新的 IP

NAME       TYPE           CLUSTER-IP      EXTERNAL-IP        PORT(S)  AGE
frontend   LoadBalancer   10.51.252.116   XXX.XXX.XXX.XXX    80/TCP   1m

現在可以使用該 IP 從叢集外部與前端服務 (Service) 互動。

透過前端發送流量

前端和後端現在已連接。您可以使用 frontend Service 的外部 IP,透過 curl 命令來連線端點。

curl http://${EXTERNAL_IP} # replace this with the EXTERNAL-IP you saw earlier

輸出顯示後端產生的訊息

{"message":"Hello"}

清除

若要刪除 Services,請輸入此命令

kubectl delete services frontend backend

若要刪除 Deployments、ReplicaSets 以及執行後端和前端應用程式的 Pods,請輸入此命令

kubectl delete deployment frontend backend

下一步

上次修改時間為 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample shortcode 取代 code shortcode (e8b136c3b3)