k8s的Service详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k8s的Service详解相关的知识,希望对你有一定的参考价值。

参考技术A

Pod是非永久性资源,会动态创建和销毁,pod的ip会变化。这会导致一类Pod(业务1)访问另一类Pod(业务2)需要找出并跟踪Pod(业务2)的IP地址,再者Pod(业务2)是多个的,如何提供负载均衡呢?虽然Pod1通过轮询一组Pod的ip可以实现,但会Pod就需要增加负载均衡的逻辑,Pod就变得不纯粹了,不符合单一设计原则。于是有了Service,把一类Pods上的应用程序抽象成服务,并提供可以访问他们的策略。

有两种方式: 选择算符的Service 没有选择算符的Service

这是最常见的方式,指定 spec.selector 即通过打标签的方式,主要是针对集群内部同命名空间的Pod

创建上面的Service,会自动创建相应的 Endpoint 对象

查看自动创建的Endpoint对象

主要是针对希望服务指向另一个名字空间或者其他集群中的服务,比如外部的ES集群

此服务没有选择算符,因此不会自动创建相应的 Endpoint 对象, 需要手动动添加 Endpoint 对象,将服务手动映射到运行该服务的网络地址和端口

该模式下,节点上kube-proxy 持续监听 Service 以及 Endpoints 对象的变化,并设置进本地节点iptables,请求反向代理全部交给 iptables 来实现。每个Node节点都会配置所有Service进iptables,当捕获到Service的clusterIP和端口请求,利用注入的iptables,将请求重定向到Service的对应的Pod,v1.2版本之后的默认模式。

通过查看iptables规则可以看到:

kube-proxy 在 iptables 模式下随机选择一个后端Pod,利用Pod 就绪探测器验证Pod是否正常,kube-proxy只会把正常的Pod写入iptables,避免流量进入不正常的Pod。

kube-proxy 会监视 Kubernetes 控制平面对 Service 对象和 Endpoints 对象的添加和移除操作。 对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。请求先经过iptables规则,当捕获到达Service 的 clusterIP和 Port 的请求,并重定向到代理端口(kube-proxy),再由代理端口再代理请求到后端Pod(v1.2版本之前的默认模式)

IPVS模式是利用linux的IPVS模块实现,同样是由kube-proxy实时监视集群的service和endpoint,调用netlink接口相应的创建ipvs规则,由ipvs实现负载均衡访问。IPVS 专为负载平衡而设计,并基于内核内哈希表,有更高的网络流量吞吐量(iptables 模式在大规模集群 比如10000 个服务中性能下降显著),并且具有更复杂的负载均衡算法(最小连接、局部性、 加权、持久性)。(v1.8以后新支持的)

上面讲的Pod之间调用,采用Service进行抽象,服务之间可以通过clusterIP 进行访问调用,不用担心Pod的销毁重建带来IP变动,同时还能实现负载均衡。但是clusterIP也是有可能变动,况且采用IP访问始终不是一种好的方式。通过 DNS 环境变量 可以实现通过服务名现在访问。

k8s采用附加组件(CoreDNS)为集群提供DNS服务,会为每个服务创建DNS记录,CoreDNS只为Service和Pod创建DNS记录。kubernetes强烈推荐采用DNS方式.

例如,如果你在 Kubernetes 命名空间 my-ns 中有一个名为 my-service 的服务, 则控制平面和 DNS 服务共同为 my-service.my-ns 创建 DNS 记录。 my-ns 命名空间中的 Pod 应该能够通过按名检索 my-service 来找到服务,其他命名空间中的 Pod 必须将名称限定为 my-service.my-ns 。 这些名称将解析为为服务分配的集群 IP。

Kubernetes 还支持命名端口的 DNS SRV(服务)记录。 如果 my-service.my-ns 服务具有名为 http 的端口,且协议设置为 TCP, 则可以对 _http._tcp.my-service.my-ns 执行 DNS SRV 查询查询以发现该端口号, "http" 以及 IP 地址

当 Pod 运行在 Node上,kubelet 会为每个活跃的 Service 添加一组环境变量。 简单的 SVCNAME_SERVICE_HOST 和 SVCNAME_SERVICE_PORT 变量。 这里 Service 的名称需大写,横线被转换成下划线。

举个例子,一个名称为 nginx-svc 的 Service 暴露了 TCP 端口 8080, 同时给它分配了 Cluster IP 地址 10.0.0.11,这个 Service 生成了如下环境变量:

进入example容器,env打印环境变量:

访问Nginx服务可以使用

以上是关于k8s的Service详解的主要内容,如果未能解决你的问题,请参考以下文章

K8s——Service详解

Python3 - k8s创建Service服务实例详解

Python3 - k8s创建Service服务实例详解

Python3 - k8s创建Service服务实例详解

k8s service使用详解

k8s之service详解