使用服务连接前端到后端
本任务演示了如何创建 frontend 和 backend 微服务。backend 微服务是一个 hello 问候服务。frontend 使用 nginx 和 Kubernetes Service 对象暴露 backend。
目标
- 使用 Deployment 对象创建并运行示例
hello
backend 微服务。 - 使用 Service 对象将流量发送到 backend 微服务的多个副本。
- 创建并运行
nginx
frontend 微服务,同样使用 Deployment 对象。 - 配置 frontend 微服务以将流量发送到 backend 微服务。
- 使用
type=LoadBalancer
的 Service 对象将 frontend 微服务暴露到集群外部。
准备工作
你需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与集群通信。建议在至少有两个非控制平面节点的集群上运行本教程。如果还没有集群,可以使用 minikube 创建一个,或者使用以下某个 Kubernetes 演练场:
要检查版本,输入命令 kubectl version
。
本任务使用带外部负载均衡器的 Service,这需要支持的环境。如果你的环境不支持此特性,可以使用 NodePort 类型的 Service 代替。
使用 Deployment 创建 backend
backend 是一个简单的 hello 问候微服务。这是 backend 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
...
创建 backend Deployment
kubectl apply -f https://k8s.io/examples/service/access/backend-deployment.yaml
查看 backend 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 对象
从 frontend 发送请求到 backend 的关键在于 backend Service。Service 创建了一个持久的 IP 地址和 DNS 名称条目,以便 backend 微服务始终可以被访问到。Service 使用选择器(selector)来查找它要路由流量的 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: hello
和 tier: backend
的 Pods。
创建 backend Service
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
至此,你拥有一个运行 hello
应用三个副本的 backend
Deployment,以及一个可以将流量路由到它们的 Service。然而,这个 Service 在集群外部既不可用也不可解析。
创建 frontend
现在 backend 已经运行起来了,你可以创建一个从集群外部可访问的 frontend,并通过代理请求连接到 backend。
frontend 使用分配给 backend Service 的 DNS 名称向 backend worker Pods 发送请求。DNS 名称是 hello
,这是 examples/service/access/backend-service.yaml
配置文件中 name
字段的值。
frontend Deployment 中的 Pods 运行着一个 nginx 镜像,它被配置为将请求代理到 hello
backend 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; }
}
与 backend 类似,frontend 也有一个 Deployment 和一个 Service。backend 和 frontend 的 Service 的一个重要区别在于,frontend 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"]
...
创建 frontend 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
与 frontend 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
Service 进行交互。
通过 frontend 发送流量
frontend 和 backend 现在已连接。你可以使用 curl 命令访问 frontend Service 的外部 IP 上的端点。
curl http://${EXTERNAL_IP} # replace this with the EXTERNAL-IP you saw earlier
输出显示 backend 生成的消息:
{"message":"Hello"}
清理
要删除 Services,输入以下命令:
kubectl delete services frontend backend
要删除运行 backend 和 frontend 应用的 Deployments、ReplicaSets 和 Pods,输入以下命令:
kubectl delete deployment frontend backend
接下来
- 了解更多关于Services的信息
- 了解更多关于ConfigMaps的信息
- 了解更多关于Service 和 Pod 的 DNS的信息