摘要:前言最近在产品新版本的服务发现和负载均衡方案上遇到了一个问题,在尽量不改动原生使用方式和代码前提下,对又重新复习了一遍,略有体会。所有访问该的请求,都会被转发到后端的中。使用这种方案的原因,不外乎是外部无法访问容器服务。
前言
最近在产品新版本的服务发现和负载均衡方案上遇到了一个问题,在尽量不改动原生k8s使用方式和代码前提下,对service又重新复习了一遍,略有体会。
Servicek8s中service是一个面向微服务架构的设计,它从k8s本身解决了容器集群的负载均衡,并开放式地支持了用户所需要的各种负载均衡方案和使用场景。
通常,一个service被创建后会在集群中创建相应的endpoints,随后,controller-manager中的endpointsController会去检查并向该endpoints填入关于这个service,符合下述所有条件的后端端点(即pod):
相同的namespace;
pod的labels能满足service.Spec.selector(除非service.Spec.selector为空,这种情况下不会自动创建endpoints);
如果service开放了port,且是以字符串名字的形式(targetPort=[字符串]),则相应的pod的某个container中必须有配置同名的port;
当endpoints被更新后,kube-proxy会感知,并根据更新后的endpoints,在宿主机上做转发规则的配置,kube-proxy目前支持iptables、ipvs两种负载均衡方式,默认是iptables。
DNS绝大部分使用k8s的人都会使用kubedns做服务发现和service domain的解析。kubedns会建立长连接即时检查service的变化,一旦发现有service被创建,会根据service的类型,在数据库中构建service domain 到指定的CNAME或IP(cluster-IP)的映射,作为对该service domain 的dns解析结果。
service 的类型 ClusterIP最普遍的service类型,也是默认类型。ClusterIP类型的service创建时,k8s会通过etcd从可分配的IP池中分配一个IP,该IP全局唯一,且不可修改。所有访问该IP的请求,都会被iptables转发到后端的endpoints中。
该类型下,service的cluster-ip会作为kube-dns的解析结果,返回给客户端。基本上这是私有云中服务内部常用的方案,但是也只能集群内服务互相访问。
NodePort通过node的IP进行地址转换实现服务的可访问性,外部访问集群中任意一个node:port即可以访问服务。
举个例子:一个单副本的deployment,其pod运行在node2上,通过nodePort方式开放服务,外部client访问node1_ip:port即可访问到容器服务。这个过程中原理是:
client访问node1_ip:port
node1对数据包做SNAT,将来源地址改成node1_ip
node1对数据包做DNAT,将目的地址改成node2_ip
node2收到数据包,根据port查找自身的端口,这个端口在service创建时就会与自身运行的port做映射,所以这里数据包会被转发到真实的容器中
数据响应由容器发给node1,node1再返回给client
这种方案下,node上会产生端口的占用,所以要确保端口可用性。
另外,通过指定service.spec.externalTrafficPolicy=Local可以设置node上kube-proxy不转发到其他node,参照上面的例子,由于node1没有响应的pod在运行,所以node1上会直接drop数据包。
使用这种方案的原因,不外乎是:外部无法访问容器服务。
LoadBalancer需要外部支持(GCP and Azure),用户访问service.spec.external-ip,该IP对应到一个外部负载均衡的vip,外部服务对这个vip的请求,会被loadbalancer通过健康检查和转发,发送到一个运行着该服务pod的node上,并同样通过nodePort里的端口映射,发送给容器。
上述是几种比较普遍的service,随着社区发展,又出现了一些新的类型,可以做更灵活的适配。
ExternalName用户可以指定一个任意的名字,作为该service被解析的CNAME,这种类型的servcie不用指定clusterIP,因此kube-proxy不会管理这类service,这类service需要使用1.7版本以上的kubedns。比如用户想创建一个service,但要让所有容器访问该service的请求都引导到用户自己定义的外部域名服务,就可以通过这个方式实现。可以说这个是最自由的一个方式:你希望服务被如何解析,服务就能被如何解析。你甚至可以给多个service配置同一个externalName。
headless serviceheadless service是一个特殊的ClusterIP类service,这种service创建时不指定clusterIP(--cluster-ip=None),因为这点,kube-proxy不会管这种service,于是node上不会有相关的iptables规则。
当headless service有配置selector时,其对应的所有后端节点,会被记录到dns中,在访问service domain时kube-dns会将所有endpoints返回,选择哪个进行访问则是系统自己决定;
当selector设置为空时,headless service会去寻找相同namespace下与自己同名的pod作为endpoints。这一点被应用到statefulset中,当一个三副本的statefulset(mysql1,mysql2,mysql3)运行在不同节点时,我们可以通过域名的方式对他们分别访问。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/32648.html
摘要:与已运行相关的过滤规则负责检查待调度与上已有之间的亲和性关系。并且每个打分函数都可以配置对应的权重值,下面介绍调度器策略配置时,也会涉及权重值的配置。默认权重值是,如果觉得某个打分函数特别重要,便可以加大该权重值。 一、概述 Kubernetes 是 Google 开源的容器集群管理系统(谷歌内部:Borg),而今天要介绍的 kube-scheduler 是 k8s 系统的核心组件之一...
摘要:本文将主要分析原生的网络策略。笔者认为这个问题主要是因为使用者不了解网络策略的省缺行为。可选字段,字符串,策略规则类型,表示该网络策略中包含哪些类型的策略,可选为或。互相间为或的关系,满足其中一条则放行。标准,除了指定的放行外其他都禁止。 k8s中的网络策略主要分为原生 NetworkPolicy 和第三方网络插件提供的网络策略。本文将主要分析原生Networkpolicy的网络策略。...
摘要:简称,是在年发布的一个开源项目。网络要能够通信,必须部署网络,是其中一个可选方案。最常使用,可以管理多个副本,并确保按照期望的状态运行,底层调用。用于每个最多只运行一个副本的场景。 Kubernetes 简称 k8s,是 google 在 2014 年发布的一个开源项目。 Kubernetes 解决了哪些问题? 真实的生产环境应用会包含多个容器,而这些容器还很可能会跨越多个服务器主机部...
摘要:年月的华为大会上,两人开始了对的讨论。联合创始人及梁胜在月上海中,联合华为布道华为云和以下简称的合作由来已久。这一观点与梁胜的看法不谋而合。甫一见面,方璞便向梁胜抛出了一个重磅问题:在K8S之后,你觉得未来最有前途的容器技术是什么呢?方璞是华为云容器服务域的产品总监,主要负责华为云容器的构建和部署。我觉得是Istio。方璞说。2016年9月的华为CONNECT大会上,两人开始了对Istio的...
摘要:组件会给每个分配一个,则替代了的来实现服务发现,在的容器内部依然可以访问服务来获取元数据信息。的需要在中实现一个,目前只有,而则维护了自己的版本在其中提供了。 在Rancher 1.0版本开始,Rancher逐步增加了Kubernetes、Swarm、Mesos等多编排引擎的支持,很多朋友就此产生了疑惑,诸如Cattle引擎和这几个之间到底什么关系?每种引擎是如何支持的?自家的业务环境...
阅读 2163·2021-11-15 11:38
阅读 1128·2021-09-06 15:02
阅读 3346·2021-08-27 13:12
阅读 1259·2019-08-30 14:20
阅读 2361·2019-08-29 15:08
阅读 613·2019-08-29 14:08
阅读 1704·2019-08-29 13:43
阅读 1431·2019-08-26 12:11