K8s的Service资源是一种为一组功能相同的Pod提供统一不变的流量入口的资源。这里介绍两种典型的Service类型:ClusterIP Service、NodePort Service
ClusterIP Service
ClusterIP Service通过集群的内部IP暴露服务,使得服务只能够在集群内部被访问。这也是默认Service类型。下面我们通过RS创建一组Pod,然后通过ClusterIP Service统一流量入口。使得无论RS的Pod无论怎么变化,都可以被访问到
1 | # API组、版本 |
效果如下所示
由于集群内各Pod之间的网络是互通的,故我们可以先通过Pod的IP、Port来访问验证下Pod是否可以正常工作。效果如下所示
现在我们尝试通过服务的IP、Port进行访问,效果如下所示。不难看出服务同时具有负载均衡的功能了
此外,还可以通过sessionAffinity配置服务的会话亲和性。当配置为ClientIP时,其可以保证将来自相同客户端IP的请求总是转发至同一个Pod中
1 | apiVersion: v1 |
需要注意的是,当Service暴露多个端口时,需要给每个端口指定名字。如下所示
1 | apiVersion: v1 |
NodePort Service
该类型的服务类似于ClusterIP Service,集群内部的Pod可以直接通过该服务的IP、Port来访问服务。不同之处在于该NodePort Service还会在K8s集群中每个节点打开一个端口,同时将节点上该端口的流量进行转发重定向到该服务当中。这也是该服务类型名称的由来。此时一方面,Pod就可以通过任意节点的IP、NodePort Service在集群该节点打开的端口来访问访问服务;另一方面,如果K8s集群外的客户端可以访问K8s集群节点的话,就可以实现将K8s中的服务暴露给外部客户端了。而不仅仅是集群内的Pod才能访问了。示例配置文件如下所示
1 | # API组、版本 |
效果如下所示,我们可以直接通过服务的集群IP、端口访问服务。这点与ClusterIP Service并无二异
现在我们尝试通过集群节点IP、NodePort Service在节点上打开的端口来访问服务。效果如下所示
服务发现
环境变量
当服务先创建、Pod后创建时,在创建Pod过程中会把活跃Service的IP、Port信息写入该Pod的环境变量当中。具体地,服务IP、Port的环境变量名分别为{ServiceName}_SERVICE_HOST、{ServiceName}_SERVICE_PORT。其中,ServiceName是服务名称的大写,服务名称中的横线被转换成下划线
1 | # 查看指定Pod中的环境变量 |
效果如下所示。这样集群内的Pod就可以通过环境变量获取服务的IP、Port。但如果先创建Pod、再创建服务的话,此时Pod当中就不会存在后续所创建服务的环境变量了
DNS
集群中的Pod还可以通过服务FQDN全限定域名作为服务的IP进行访问。FQDN的名称规则为
Note
Service的集群IP是一个虚拟IP,故无法ping通是正常的
参考文献
- Kubernetes in Action中文版 Marko Luksa著
- 深入剖析Kubernetes 张磊著