Kubernetes服务(Service )
Kubernetes集群中也有类似于反向代理的概念,在Kubernetes中被称为Service。
虽然Kubernetes中的Service可以提供类似于nginx那样的反向代理功能,但是也是有区别的,Service是一个抽象的概念,同时Service的路由和传统的反向代理到后端的路由是不一样的,在Kubernetes中Service将流量反向路由到后端的pod,是通过Selector和Labels机制来实现的。Labels是一种打标签机制,可以给每个Pod贴上一个标签,这个标签就是键值对,比如app: petclinic,Selector是一种路由选择机制,如果Selector上的标签和Pod上的标签匹配上,那么流量经过Selector会流向与之所匹配的Labels上,从而实现路由功能。
对比Nginx中的静态路由,Kubernetes中的Service这种路由机制要灵活很多。
除了路由转发功能,Service还有负载均衡功能,能够给一组Pod组成的集群提供负载功能,还可以屏蔽后端Pod Ip的变化,实现稳定的访问。
Service 介绍
我们通过Pod、Deployment等可以将应用发布到Kubernetes平台中,但是如果我们如何才能访问我们部署的应用呢?有一个办法就是通过节点的IP加上节点的端口来访问这个节点上的容器应用,但是如果我们有多个跨节点的相通应用时该怎么办呢?特别是应用发生扩容、缩容时应该如何处理,这时我们就需要利用Service
来实现。
在Kubernetes中,Service是一种资源,提供了我们访问单个或多个容器应用的能力。每个服务在其生命周期内,都拥有一个固定的IP地址和端口。每个服务对应了后台的一个或多个Pod,通过这种方式,客户端就不需要关心Pod所在的位置,方便后端进行方便的Pod扩容、缩容等操作。
Service的类型
Service中有几种类型,如下:
1. ClusterIP:默认, 分配一个集群内部可以访问的虚拟IP(VIP),用于Kubernetes内部一个反向代理。微服务应用之间使用这种方式
2. NodePort:在每个Node上分配一个端口作为外部访问入口,相当于在Kubernetes边缘上的一个反向代理,通过NodePort可以让Kubernetes集群外部的访问者来访问Kubernetes集群内部Pod应用。
3. LoadBalancer:工作在特定的Cloud Provider上,适合运行在公有云环境中,例如Google Cloud,AWS,OpenStack。支持对接公有云提供的负载均衡,可以将Kubernetes内部的服务暴露在公网上,它的底层也是依赖于NodePort。
Selector和Labels
Selector和Label是Kubernetes系列中核心概念。Label是一组绑定到K8s资源对象上的key/value对。同一个对象的labels属性的key必须唯一。label可以附加到各种资源对象上,如Node,Pod,Service,RC等。
Selector和Label共同组成标签选择器,可以使Kubernetes实现分组机制,通过Selector和Label能够识别一组有共同特征或属性的资源对象。
查看Service官方样例规范
https://kubernetes.io/docs/reference/kubernetes-api/services-resources/service-v1/
kind:Service表示部署的是一个Service代理。
metadata表示给Service起一个名字。
selector表示要匹配后台的标签,相当于路由映射配置。
type表示Service的类型。对于本地我们不能选择LoadBalancer。
如果你将 type
字段设置为 NodePort
,则 Kubernetes 控制平面将在 --service-node-port-range
标志指定的范围内分配端口(默认值:30000-32767)。 每个节点将那个端口(每个节点上的相同端口号)代理到你的服务中。 你的服务在其 .spec.ports[*].nodePort
字段中要求分配的端口。
如果你想指定特定的 IP 代理端口,则可以将 kube-proxy 中的 --nodeport-addresses
标志设置为特定的 IP 块。从 Kubernetes v1.10 开始支持此功能。 该标志采用逗号分隔的 IP 块列表(例如,10.0.0.0/8
、192.0.2.0/25
)来指定 kube-proxy 应该认为是此节点本地的 IP 地址范围。
petclinic-pod.yml
apiVersion: v1 kind: Pod metadata: name: petclinic labels: app: petclinic spec: containers: - name: petclinic image: spring2go/spring-petclinic:1.0.0.RELEASE
petclinic-service.yml
apiVersion: v1 kind: Service metadata: name: petclinic spec: ports: - name: http port: 8080 #Service暴露的端口 集群内部访问服务的端口 targetPort: 8080 #容器内部向外暴露的端口 nodePort: 31080 #外网访问对外暴露的端口 selector: app: petclinic type: NodePort
编辑好上面两个文件,在文件所在目录下发布service。
查看service详情
可以看到Selector是Selector: app=petclinic,对外暴露的端口是31080,在浏览器上输入就可以访问应用。
Service实现原理