k8s群集中的每个节点都运行一个kube-proxy的组件,kube-proxy其实是一个代理层负责实现service
userspace模式
客户端访问ServiceIP(clusterIP)请求会先从用户空间到内核中的iptables,然后回到用户空间kube-proxy,kube-proxy负责代理工作。
具体细节:
请求到达service后,其被转发到内核,经由套接字送往用户空间的kube-proxy,而后经由kube-proxy送回内核空间,并调度至后端POD,其传输方式效率太低。在1.1 版本之前,其是默认的转发策略。
iptables模式
客户端访问ServiceIP(clusterIP)请求会由iptables直接重定向到后端
具体细节:
客户端IP请求时,直接请求本地内核service ip,根据iptables的规则直接将请求转发到到各pod上,因为使用iptable NAT来完成转发,也存在不可忽视的性能损耗。另外,如果集群中存在上万的Service/Endpoint,那么Node上的iptables rules将会非常庞大,性能还会再打折扣
Kubernetes v1.2之前默认是userspace之后是iptables模式,iptables模式性能和可靠性更好,但是iptables模式依赖健康检查,在没有健康检查的情况下如果一个pod不响应,iptables模式不会切换另一个pod上
ipvs模型
此模型跟踪API service上的service和endpoints对象的变动,据此来调用netlink接口创建IPVS规则,并确保API server中的变动保持同步,其流量调度策略在IPVS中实现,其余的在iptables中实现。
ipvs 支持众多调度算法,如rr、lc、dh、sh、sed和nq 等。
集群外部访问
我们如何在集群外访问service呢?k8s提供了几种方式
NodePort
通过每个 Node 上的 IP 和静态端口(NodePort)暴露服务。NodePort 服务会路由到 ClusterIP 服务,这个 Cluster
IP 服务会自动创建。通过请求 NodeIP:Port,可以从集群的外部访问一个 NodePort 服务。
这时要访问这个Service的话,只需要通过访问
<任何一台宿主机器的IP>:Port
LoadBalancer
在NodePort基础上,Kubernetes可以请求底层云平台cloud provider 创建一个外部的负载均衡器,并将请求转发到每个Node作为后端,进行服务分发。
该模式需要底层云平台(例如GCE、亚马孙AWS)支持。
ExternalName
创建一个dns别名指到service name上,主要是防止service name发生变化,要配合dns插件使用。通过返回 CNAME 和它的值,可以将服务映射到 externalName 字段的内容。
这只有 Kubernetes 1.7 或更高版本的 kube-dns 才支持
Ingress
上面我们提到几种方式,但是当集群服务很多的时候,NodePort方式最大的缺点是会占用很多集群机器的端口;LB方式最大的缺点则是每个service一个LB又有点浪费和麻烦,并且需要k8s之外的支持; 而ingress则只需要一个NodePort或者一个LB就可以满足所有service对外服务的需求。工作机制大致可以用下图表示:
Ingress是基于service实现7层路由转发能力的
总结
K8S中的概念还是比较多的,老顾只是抛砖引玉,小伙伴需要了解更多详细的可以查看更多详细的资料。今天老顾就介绍到这里了,谢谢!!!
念还是比较多的,老顾只是抛砖引玉,小伙伴需要了解更多详细的可以查看更多详细的资料。今天老顾就介绍到这里了,谢谢!!!