2.4.3 部署 Service 对象
简单来说,一个Service对象可视作通过其标签选择器过滤出的一组Pod对象,并能够为此组Pod对象监听的套接字提供端口代理及调度服务。
1. 创建 Service 对象
“kubectl expose”命令可用于创建Service对象已将应用程序“暴露”(expose)于网络中。例如,下面的命令即可将 myapp 创建的Pod对象使用“NodePort”类型的服务暴露到集群外面。
**[terminal]
**[delimiter $ ]**[command kubectl expose deployments/myapp --type="NodePort" --port=80 --name=myapp]
service/myapp exposed
上面的命令中,--type选项用于指定Service的类型,而 --port 则用于指定要暴露的容器端口,目标Service对象的名称为myapp。创建完成后,default 名称空间中的对象及其通信示意图如下所示:
下面通过运行于同一集群中的Pod对象中的客户端程序发起访问测试,来模拟图2-12中的源自myapp Client Pod对象的访问请求。首先,使用kubectl run 命令创建一个Pod对象,并直接接入其交互式接口,如下命令的-it组合选项即用于交互式打开并保持其shell命令行接口;而后通过wget命令对此前创建的Service对象的名称发起访问请求,如下命令中的 myapp 即 Service 对象名称,default即其所属的 Namespace 对象的名称:
**[terminal]
**[delimiter $ ]**[command kubectl run client --image=busybox --restart=Never -it -- /bin/sh]
If you don't see a command prompt, try pressing enter.
/ # wget -O - -q http://myapp.default:80
Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a>
/ #
创建时,Service对象名称及其ClientIP会由CoreDNS附件动态添加至明后才能解析库当中,因此,名称解析服务在对象创建后即可直接使用。
类似与列出 Deployment 控制器及 Pod 对象的方式,“kubectl get services” 命令能够列出 Service 对象的相关信息,例如下面的命令显示了 Service 对象 myapp 的简要状态信息:
**[terminal]
**[delimiter $ ]**[command kubectl get svv/myapp]
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
myapp NodePort 10.101.202.124 <none> 80:32204/TCP 20h
其中,“PORT(s)”字段表明,集群中各工作节点会捕获发往本地的目标端口为32204的流量,并将其代理至当前Service对象的80端口,于是,集群外部的用户可以使用当前集群中任一节点的此端口来请求Services对象上的服务。CLUSTER-IP字段为当前Service的IP地址,它是一个虚拟IP,并没有配置与集群中的任何主机的任何接口之上,但每个node之上的kube-proxy都会为CLUSTER-IP所在的网络创建用于转发的iptables或ipvs规则。此时,用户可用于集群外部任一浏览器请求集群任一节点的相关端口来进行访问测试。
创建Service对象的另一种方式是使用“kubectl create service”命令,对应于每个类似,它分别有一个专用的子命令,例如“kubectl create service clusterip” 和 “kubectl create service nodeport”等,各命令在使用方式也略有区别。
2. 查看 Service 资源对象的描述
“kubectl describe services” 命令用于打印 Service 对象的详细信息,它通常包括 Service 对象的 Cluster IP,关联 Pod 对象时使用的标签选择器及关联到的 Pod 资源的端点等,示例如下:
**[terminal]
**[delimiter $ ]**[command kubectl describe services]
Name: myapp
Namespace: default
Labels: run=myapp
Annotations: <none>
Selector: run=myapp
Type: NodePort
IP: 10.101.202.124
Port: <unset> 80/TCP
TargetPort: 80/TCP
NodePort: <unset> 32204/TCP
Endpoints: 10.244.3.3:80
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
上面命令的执行结果输出基本上可以做到见名而知义,此处需要特别说明的几个字段具体如下:
- Selector:当前Service对象使用的标签选择器,用于选择关联Pod对象。
- Type:即Sevices的类型,其值可以是ClusterIP、NodePort和LoadBalancer等其中之一。
- IP:当前Service对象的ClusterIP。
- Port:暴露的端口,即当前Service用于接受并响应请求的端口。
- TargetPort:容器中的用于暴露的目标端口,由 Service Port 路由请求至此端口。
- NodePort:当前 Service 的 NodePort,它是是否存在有效值与 Type 字段中的类型相关。
- EndPoints:后端端点,即被当前Service的Selector挑中的所有Pod的IP及其端口。
- Session Affinity:是否启用会话粘性。
- External Traffic Policy:外部流量的调度策略。