使用服务将前端连接到后端

此任务演示了如何创建**前端**和**后端**微服务。后端微服务是一个问候语服务。前端使用 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)