5. K8S Service与Ingress
Kubernetes Service与Ingress
srevice概念
kubernetes Pod是短暂的,它们会被创建,也会死掉,并且是不可被复活的。
ReplicationControllers动态的创建和销毁Pods(比如规模扩大或者缩小,或者执行动态更新)。每个Pod都有自己的IP,这些IP随着时间的变换,也不能持续依赖,这样就引发一个问题:如果一些Pods(后台、后端)提供了一些功能共其他Pod使用(前台),再Kubernetes集群中是如何让这些前台能够持续的追踪到这些后台的。
答案是:==service==
Kubernetes Service是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些服务标记的Pod(一般)都是听过label Selector决定的。(下面会讲到为什么需要一个没有 label selector 的服务)
假设后台是一个图形处理器的后台,并且有3个副本。这些副本是可以相互代替的,并且,前台需要关心使用的哪一台Pod,当这个承载前台请求的Pod发生变化时,前台并不需要知道这些变换,或者追踪后台的这些副。service定义的抽象能够解耦这种关联。
对于Kubernetes 原生的应用,Kubernetes提供了一个简单的Endpoints API,这个Endpoints api 的作用就相当于一个服务中的Pod发生变化时,Endpoints API随之变化,对于那些不是原生的程序,Kubernetes提供了一个基于虚拟IP的网桥的服务,这个服务会将请求转发到对应的后台Pod。
Service对象的IP地址也成为ClusterIP,它位于为Kubernetes集群配置指定专用的IP地址范围之内,是一种虚拟的IP地址,它再Service对象创建之后保持不变,并且能够被同一集群中的Pod资源所访问。Service端口用于接收客户端请求,并将请求转发至后端的Pod应用端口,这样的代理机制,也称为端口代理,它基于TCP/IP协议栈的传输层。
Service存在的意义:
1、防止Pod失联(服务发现)
2、定义一组Pod的访问策略(负载均衡)
Pod与service的关系:
1、通过label-selector相关联
2、通过service实现Pod的负载均衡(TCP、UDP四层)
定义Service
使用kubectl explain svc查看更多关键字
service不会直接到pod,service是直接到endpoint资源,就是地址加端口,再由endpoint再关联到pod。
service只要创建完,就会再dns中添加一个资源记录进行解析,添加完成即可进行解析。资源记录的格式为:
| |
默认的集群service的A记录:
| |
my-service服务创建的A记录:
| |
Service类型
Kubernetes ServiceTypes 允许指定一个需要的类型的Service,默认是Cluster IP类型。
也可以使用Ingress来暴露自己的服务。Ingress不是一种服务类型,但它充当集群的入口点。它可以将路由规则整合到一个资源中,因为它可以在同一IP地址下公开多个服务。
Type的类型如下:
ClusterIP:
通过集群的内部 IP 暴露服务,选择该值时服务只能够在集群内部访问。 这也是默认的 ServiceType。
NodePort
通过每个节点上的 IP 和静态端口(NodePort)暴露服务。 NodePort 服务会路由到自动创建的 ClusterIP 服务。 通过请求 <节点 IP>:<节点端口>,你可以从集群的外部访问一个 NodePort 服务。
如果将type字段设置为NodePort,则Kubernetes控制平面将在--service-node-port-range标志指定的范围内分配端口(默认值:30000-32767)。每个节点将那个端口(每个节点上的相同端口号)代理到你的服务器中。你的服务在其.spec.port[*].nodePort字段中要求分配的端口。
如果你想指定特定的IP代理端口,则可以设置kube-proxy中的--nodeport-addresses参数或者将kube-porxy配置文件 中的等效nodePodrtAddresses字段设置为特定的IP快。该标志采用逗号分隔的IP块列表(例如:10.0.0.0/8、192.0.2.0/25)来指定kube-proxy应该认为是此节点本地的IP地址范围。
例如,如果你使用 --nodeport-addresses=127.0.0.0/8 标志启动 kube-proxy, 则 kube-proxy 仅选择 NodePort Services 的本地回路接口。 --nodeport-addresses 的默认值是一个空列表。 这意味着 kube-proxy 应该考虑 NodePort 的所有可用网络接口。 (这也与早期的 Kubernetes 版本兼容)。
如果需要特定的端口号,你可以在 nodePort 字段中指定一个值。 控制平面将为你分配该端口或报告 API 事务失败。 这意味着你需要自己注意可能发生的端口冲突。 你还必须使用有效的端口号,该端口号在配置用于 NodePort 的范围内。
使用 NodePort 可以让你自由设置自己的负载均衡解决方案, 配置 Kubernetes 不完全支持的环境, 甚至直接暴露一个或多个节点的 IP。
需要注意的是,Service 能够通过 <NodeIP>:spec.ports[*].nodePort 和 spec.clusterIp:spec.ports[*].port 而对外可见。 如果设置了 kube-proxy 的 --nodeport-addresses 参数或 kube-proxy 配置文件中的等效字段, <NodeIP> 将被过滤 NodeIP。
例如:
loadBalancer:
使用云提供商的负载均衡器向外部暴露服务。 外部负载均衡器可以将流量路由到自动创建的 NodePort 服务和 ClusterIP 服务上。
在使用支持外部负载均衡器的云提供商的服务时,设置 type 的值为 "LoadBalancer", 将为 Service 提供负载均衡器。 负载均衡器是异步创建的,关于被提供的负载均衡器的信息将会通过 Service 的 status.loadBalancer 字段发布出去。
例如:
来自外部负载均衡器的流量将直接重定向到后端 Pod 上,不过实际它们是如何工作的,这要依赖于云提供商。
某些云提供商允许设置 loadBalancerIP。 在这些情况下,将根据用户设置的 loadBalancerIP 来创建负载均衡器。 如果没有设置 loadBalancerIP 字段,将会给负载均衡器指派一个临时 IP。 如果设置了 loadBalancerIP,但云提供商并不支持这种特性,那么设置的 loadBalancerIP 值将会被忽略掉。
注意:
在 Azure 上,如果要使用用户指定的公共类型 loadBalancerIP,则 首先需要创建静态类型的公共 IP 地址资源。 此公共 IP 地址资源应与集群中其他自动创建的资源位于同一资源组中。 例如,MC_myResourceGroup_myAKSCluster_eastus。
将分配的 IP 地址设置为 loadBalancerIP。确保你已更新云提供程序配置文件中的 securityGroupName。 有关对 CreatingLoadBalancerFailed 权限问题进行故障排除的信息, 请参阅
与 Azure Kubernetes 服务(AKS)负载平衡器一起使用静态 IP 地址
或
在 AKS 集群上使用高级联网时出现 CreatingLoadBalancerFailed
。
详细内容: 服务 | Kubernetes
ExternalName:
通过返回 CNAME 和对应值,可以将服务映射到 externalName 字段的内容(例如,foo.bar.example.com)。 无需创建任何类型代理。
类型为 ExternalName 的服务将服务映射到 DNS 名称,而不是典型的选择器,例如 my-service 或者 cassandra。 你可以使用 spec.externalName 参数指定这些服务。
例如,以下 Service 定义将 prod 名称空间中的 my-service 服务映射到 my.database.example.com:
说明: ExternalName 服务接受 IPv4 地址字符串,但作为包含数字的 DNS 名称,而不是 IP 地址。 类似于 IPv4 地址的外部名称不能由 CoreDNS 或 ingress-nginx 解析,因为外部名称旨在指定规范的 DNS 名称。 要对 IP 地址进行硬编码,请考虑使用 headless Services 。
当查找主机 my-service.prod.svc.cluster.local 时,集群 DNS 服务返回 CNAME 记录, 其值为 my.database.example.com。 访问 my-service 的方式与其他服务的方式相同,但主要区别在于重定向发生在 DNS 级别,而不是通过代理或转发。 如果以后你决定将数据库移到集群中,则可以启动其 Pod,添加适当的选择器或端点以及更改服务的 type。