-
Service基本背景知识
1.1 基本概念
Service可以看作是一组提供相同服务的Pod对外的访问接口。借助Service,应用可以方便地实现服务发现和负载均衡。 service默认只支持4层负载均衡能力,没有7层功能。(可以通过Ingress实现)
service的类型:
• ClusterIP:默认值,k8s系统给service自动分配的虚拟IP,只能在集群内部访问。
• NodePort:将Service通过指定的Node上的端口暴露给外部,访问任意一个 NodeIP:nodePort都将路由到ClusterIP。
• LoadBalancer:在 NodePort 的基础上,借助 cloud provider 创建一个外部的负 载均衡器,并将请求转发到 :NodePort,此模式只能在云服务器上使用。
• ExternalName:将服务通过 DNS CNAME 记录方式转发到指定的域名(通过 spec.externlName 设定)。
Service 是由 kube-proxy 组件,加上 iptables 来共同实现的.
• kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables 规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的 CPU资源。
• IPVS模式的service,可以使K8s集群支持更多量级的Pod。
1.2 服务访问
1.2.1 集群内
Service 的 ClusterIP 是 Kubernetes 内部的虚拟 IP 地址,集群内POD调用service,通常是使用Cluster IP,也就是10.104.68.121。
但因为该Service是LoadBalancer类型,所以其实也可以调用集群外LB(IP:10.42.162.216(公有云地址))反向代理到nodeport,同样可以访问到集群内的Service。
所以,我们在观察k8s service iptables规则的时候,可以分析2种访问路径:
- 集群内发起调用,通过cluster ip访问到service。
- 集群外发起调用,通过nodeport访问到service。
现在我们登录到任意node,因为k8s会把完整的iptables规则下发到每一个node。
1.2.2 集群外部访问服务
Service 的 ClusterIP 是 Kubernetes 内部的虚拟 IP 地址,无法直接从外部直接访问。但如果需要从外部访问这些服务该怎么办呢,有多种方法
1.2.2.1 NodePort
使用 NodePort 服务在每台机器上绑定一个端口,这样就可以通过 <NodeIP>:NodePort 来访问该服务。如:
1.2.2.2 LoadBalancer
使用 LoadBalancer 服务借助 Cloud Provider 创建一个外部的负载均衡器,并将请求转发到 <NodeIP>:NodePort。该方法仅适用于运行在云平台之中的 Kubernetes 集群。对于物理机部署的集群,可以使用 MetalLB 实现类似的功能。
从外部访问 Service 的第二种方式,适用于公有云上的 Kubernetes 服务。这时候,你可以指定一个 LoadBalancer 类型的 Service。
在service提交后,Kubernetes就会调用 CloudProvider 在公有云上创建一个负载均衡服务,并且把被代理的 Pod 的 IP地址配置给负载均衡服务做后端Endpoint。
[kubeadm@server1 mainfest]$ cat service.yml
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: myapp
type: LoadBalancer
[kubeadm@server1 mainfest]$ kubectl apply -f service.yml
service/myservice created
[kubeadm@server1 mainfest]$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 7d11h
myservice LoadBalancer 10.104.173.144 <pending> 80:32646/TCP 5s