使用 Service 将前端连接到后端
此任务展示如何创建前端和后端微服务。后端微服务是一个 hello 问候程序。前端使用 nginx 和 Kubernetes Service(服务) 对象来暴露后端。
目标
- 使用 Deployment(部署) 对象创建并运行一个示例 `hello` 后端微服务。
- 使用 Service 对象将流量发送到后端微服务的多个副本。
- 也使用 Deployment 对象创建并运行 `nginx` 前端微服务。
- 配置前端微服务以将流量发送到后端微服务。
- 使用 `type=LoadBalancer` 的 Service 对象将前端微服务暴露到集群外部。
准备工作
您需要有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议在本教程中使用一个至少有两个节点且不充当控制平面主机的集群。如果您还没有集群,可以使用 minikube 创建一个,或者您可以使用以下 Kubernetes 游乐场之一:
要检查版本,请输入 `kubectl version`。此任务使用具有外部负载均衡器的服务,这需要受支持的环境。如果您的环境不支持此功能,则可以使用类型为 NodePort(节点端口) 的服务。
使用 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: hello` 和 `tier: backend` 的 Pod。
创建后端 Service
kubectl apply -f https://k8s.io/examples/service/access/backend-service.yaml
此时,您有一个 `backend` 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
这将显示 `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 的外部 IP 上的 curl 命令来访问端点。
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
后续步骤
- 详细了解 Service(服务)
- 详细了解 ConfigMap(配置映射)
- 详细了解 Service 和 Pod 的 DNS