使用服務將前端連線到後端

此任務演示瞭如何建立**前端**和**後端**微服務。後端微服務是一個問候語服務。前端使用 nginx 和 Kubernetes Service 物件來暴露後端。

目標

  • 使用 Deployment 物件建立並執行一個示例 hello 後端微服務。
  • 使用 Service 物件將流量傳送到後端微服務的多個副本。
  • 同樣使用 Deployment 物件建立並執行一個 nginx 前端微服務。
  • 配置前端微服務以將流量傳送到後端微服務。
  • 使用 type=LoadBalancer 的 Service 物件將前端微服務暴露到叢集外部。

準備工作

你首先需要有一個 Kubernetes 叢集,並且 kubectl 命令列工具已配置為與你的叢集通訊。建議在至少有兩個不充當控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用以下 Kubernetes 演練場之一。

要檢查版本,請輸入 kubectl version

此任務使用帶有外部負載均衡器的 Service,這需要一個受支援的環境。如果你的環境不支援此功能,可以使用 NodePort 型別的 Service 代替。

使用 Deployment 建立後端

後端是一個簡單的問候語微服務。這是後端 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

此時,你有一個執行著三個 hello 應用程式副本的 backend Deployment,並且你有一個可以向它們路由流量的 Service。然而,這個 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 之間的一個重要區別是,前端 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

這將顯示 frontend 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 從叢集外部與 frontend 服務進行互動。

透過前端傳送流量

前端和後端現在已連線。你可以使用 curl 命令透過前端 Service 的外部 IP 訪問端點。

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

輸出顯示後端生成的訊息:

{"message":"Hello"}

清理

要刪除 Service,輸入以下命令:

kubectl delete services frontend backend

要刪除正在執行後端和前端應用程式的 Deployment、ReplicaSet 和 Pod,輸入此命令:

kubectl delete deployment frontend backend

下一步

最後修改於 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 簡碼代替 code 簡碼 (e8b136c3b3)