Service代理模式分类
Service的概念
k8s service定义了这样一个抽象:一个Pod的逻辑文组,一个可以访问它们的策略-----通常称为微服务。这一组Pod能够被Service访问到,通常是通过Label Selector
Service能够提供负载均衡的能力,但是在使用上有以下限制:
·只提供4层负载均衡能力,而没有七层功能,但有时我们可能需要更多的匹配规则来转发请求,这点上4层负载均衡是不支持的。
Service的类型
Service在k8s中有以下四种类型
·ClusterIP:默认类型,自动分配一个仅Cluster内部可以访问的虚拟IP
·NodePort:在ClusterIP基础上为Service在每台机器上绑定一个端口,这样就可以通过<NodeIP>:NodePort来访问该服务
·LoadBalancer:在NodePort的基础上,借助cloud provider创建一个外部负载均衡器,并将请求转发到<NodeIP>:NodePort
·ExternalName:把集群外部的服务引入到集群内部来,在集群内部直接使用。没有任何类型代理被创建,这只有k8s1.7或更高版本的kube-dns才支持

VIP和Service代理
在k8s集群中,每个Node运行一个kube-proxy进程。kube-proxy负责为Service实现了一个VIP(虚拟IP)的形式,而不是ExternalName的形式。在k8s v1.0版本,代理完全在userspace。在k8s1.1版本,新增了iptables代理,但并不是默认的运行模式。从k8s v1.2起,默认就是iptables代理。在k8s v1.8.0-beta.0中,添加了ipvs代理
在k8s 1.14版本开始默认使用ipvs代理
在k8s v1.0版本,Service是4层(TCP/UDP over IP)概念。在K8S v1.1版本,新增了Ingress API(beta版),用来表示七层(HTTP)服务
代理模式的分类
Ⅰ、userspace代理模式

Ⅱ、iptables代理模式

Ⅲ、ipvs模式
这种模式,kube-proxy会监视Kubernetes Service对象和Endpoints,调用netlink接口以响应地创建ipvs规则并定期与Kubernetes Service对象和Endpoints对象同步ipvs规则,以确保ipvs状态与期望一致。访问服务时,流量将被重定向到其中一个后端Pod
与iptables类似,ipvs与netfilter的hook功能,但使用哈希表作为底层数据结构并在内核空间中工作。这意味着ipvs可以更快地重定向流量,并且在同步代理规则时具有更好地性能。此外,ipvs为负载均衡算法提供了更多选项,例如:
·rr:轮询调度
·lc:最小连接数
·dh:目标哈希
·sh:源哈希
·sed:最短期望延迟
·nq:不排队调度

ClusterIP
clusterIP主要在每个node节点使用ipvs(如果使用iptables那就是iptables),将发向clusterIP对应端口地数据,转发到kube-proxy中,然后kube-proxy自己内部实现由负载均衡的方法,并可以查询到这个service下对应pod的地址和端口,进而把数据抓发给对应的pod的地址和端口

为了实现图上的功能,主要需要以下几个组件的协同工作:
·apiserver用户通过kubelet命令向apiserver发送创建service的命令,apiserver接收到请求后将数据存储到etcd中
·kube-proxy kubernetes的每个节点中都有一个叫做kube-proxy的进程,这个进程负责感知service,pod的变化,并将变化的信息写入本地的ipvs(iptables)规则中
·ipvs(iptables)使用NAT等基数将virtualIP的流量转至endpoint中
创建myapp-deploy.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-deploy namespace: default spec: replicas: 3 selector: matchLabels: app: myapp release: stabel template: metadata: labels: app: myapp release: stabel env: test spec: containers: - name: myapp image: wangyanglinux/myapp:v2 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80
创建Service信息
vim myapp-service.yaml
apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: type: ClusterIP selector: app: myapp release: stabel ports: - name: http port: 80 targetPort: 80

Headless Service
有时不需要或不想要负载均衡,以及单独的Service IP。遇到这类情况,可以通过指定ClusterIP(spec.clusterIP)的值为“None”来创建Headless Service。这类Service并不会分配Cluster IP,kube-proxy不会处理它们,而且平台也不会为他们进行负载均衡和路由
vim myapp-svc-headless.yaml
apiVersion: v1 kind: Service metadata: name: myapp-headless namespace: default spec: selector: app: myapp clusterIP: "None" ports: - port: 80 targetPort: 80

NodePort
nodePort的原理在于在node上开了一个端口,将向该端口的流量导入到kube-proxy,然后由kube-proxy进一步到给对应的pod
vim myapp-service.yaml
apiVersion: v1 kind: Service metadata: name: myapp namespace: default spec: type: NodePort selector: app: myapp release: stabel ports: - port: 80 targetPort: 80
LoadBalancer
loadBalancer和nodePort其实是同一种方式,区别在于loadBalancer比nodePort多了一步,就是可以调用cloud provider去创建LB来向节点导流
ExternalName
这种类型的Service通过返回CNAME和它的值,可以将服务器映射到externameName字段的内容(例如:hub.atguigu.com)。ExternalName Service是Service的特例,它没有selector,也没有定义任何的端口和Endpoint。相反的,对于运行在集群外部的服务,它通过返回该外部服务的别名这种方式来提供服务。
vim externalname.yaml
apiVersion: v1 kind: Service metadata: name: my-service-1 namespace: default spec: type: ExternalName externalName: www.baidu.com
浙公网安备 33010602011771号