Kubernetes Service服务发布实践文档格式.docx
- 文档编号:17271219
- 上传时间:2022-11-30
- 格式:DOCX
- 页数:21
- 大小:1.02MB
Kubernetes Service服务发布实践文档格式.docx
《Kubernetes Service服务发布实践文档格式.docx》由会员分享,可在线阅读,更多相关《Kubernetes Service服务发布实践文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
服务发布
第一步:
定义你的服务
eBay很多应用都采用微服务架构,这使得在大多数情况下,作为服务所有者,除了实现业务逻辑以外,还需要考虑如何把服务发布到Kubernetes集群或者集群外部,使这些服务能够被Kubernetes应用,其他Kubernetes集群的应用以及外部应用使用。
这是一个业界的通用需求,因此Kubernetes提供了灵活的服务发布方式,用户可以通过ServiceType来指定如何来发布服务。
▪ClusterIP:
此类型是默认的,这种类型的服务只能在集群内部访问。
▪NodePort:
此类型同时会分配ClusterIP,并进一步在集群所有节点的同一端口上曝露服务,用户可以通过任意的<
NodeIP>
:
NodePort访问服务。
▪LoadBalancer:
此类型同时会分配ClusterIP,分配NodePort,并且通过CloudProvider来实现LB设备的配制,并且在LB设备中配置中,将<
NodePort作为poolmember,LB设备依据转发规则将流量转到节点的NodePort。
内部服务
ClusterIP
如果你的Service只服务于Cluster内部,那么ServiceType定义为ClusterIP就足够了。
Kube-proxy是运行在Kubernetes集群所有节点的组件,它的主要职责是实现服务的虚拟IP。
针对只面向集群内部的服务,我们建议用户使用ClusterIP作为服务类型,该类型比nodePort少占用节点端口,并比LoadBalancer类型减少对LB设备的访问,我们应该尽可能的避免不必要的LB设备的访问,因为任何外部依赖都有失败的可能性。
外部服务
NodePort
针对类型是”NodePort”的服务,KubernetesMaster会从与定义的端口范围内请求一个端口号(默认范围:
30000-32767),每个节点会把该端口的流量转发到对应的服务,端口号会先是在服务的spec.ports[*].nodePort。
如果你希望指定端口,你可以通过nodePort来定义端口号,系统会检查该端口是否可用,如果可用就分配该指定端口。
指定端口时需要考虑端口冲突,并且端口需要在预定义的范围内。
这为开发者提供了自由度,他们可以配制自己的LB设备,配制未被Kubernetes完全支持的云环境,直接开放一个或者多个节点的IP供用户访问服务。
eBay的Kubernetes集群架设在OpenStack环境之上,采用OpenStackVM作为KubernetesNode,这些Node在隔离的VPC,无法直接访问,因此对外不采用nodePort方式发布服务。
LoadBalancer
针对支持外部LB设备的CloudProvider的情况,将Type字段设置为LoadBalancer会为服务通过异步调用生成负载均衡配制,负载均衡配制会体现在服务的status.loadBalancer字段。
实际上,当此类型的服务进行LoadBalancer配置时,nodeip:
nodeport作为LBPool的member,最终的traffic还是转到某node的nodePort上的。
因为eBay有OpenStack作为IaaS层架构,每个OpenStackAZ有专属的负载均衡设备,负载均衡设备与虚拟机(即KubernetesNode)的连通性在OpenStackAZ创建的时候就已经设置好,并且OpenStack的LBaaS已经把针对LB设备的操作做了抽象,这让Kubernetes和LB设备的通信变得非常简单。
eBay直接采用社区版本的OpenStackProvider作为CloudProvider,该Provider会调用OpenStackLBaaSAPI来进行LB设备的配制,无需订制即可实现与LB设备的集成。
ServiceController:
服务是如何被发布到集群外部的
Kubernetescontrollermanager的主要作用是watchkube-apiserver的相关对象,在有新对象事件如创建,更新和删除发生时,进行相应的配制,如ServiceController的主要作用是为Service配制负载均衡,ReplicaSetController主要作用是管理Replicaset中定义的Pod,保证Pod与Replicas一致。
如果你对Kubernetes代码比较熟悉,你会发现ServiceController是其中职责相对清晰,代码相对简单的一个控制器。
通过解读ServiceController的源码,我们可以了解到ServiceController同时监控Service和Node两种对象的变化,针对任何新创建或者更新的服务,ServiceController调用LoadBalancerProvider的接口来实现LoadBalancer的配制。
因为LoadBalancer的member是Cluster中所有的ReadyNode,所以当有任何Node的变化时,我们需要重新配制所有的LoadBalancerPool以体现这种变化,这也就是ServiceController要同时监控Node对象的原因。
下图展示的是当ServiceController调用OpenStackLBProvider时所做的操作的时序图。
所以最终的配置结果是针对每个Service的Port,在LB设备上会创建一个LoadBalancerPool,VIP可以接受外部请求,PoolMember是节点IP加nodePort。
LB设备和Node(即OpenStackVM)处于同一个AvailabilityZone和VPC,其连通性在AvailabilityZone创建时即得到保证。
物理上,LB设备和虚拟机所在的物理机通过路由连接,路由规则保证LB设备对特定IP段的VM可见。
这样的配制结果保证VIP接受到的所有traffic,能够根据LB设备的规则,跳转到KubernetesNode的nodePort。
为什么用NodeIP:
nodePort作为LBmember,如果一个Cluster规模较大,如几千个Node,LBpool会不会很大,为什么不用PodIP作为LB?
1.LB和VM之间的路由规则配制只包含VMIP段,在AZ部署的时候创建。
PodIP在通常情况下是不同的range,与LB之间无法直接相通。
采用NodeIP作为Poolmember使得底层架构OpenStack的配制和Kubernetes的配制分离开来,不用考虑Pod的IP范围划定。
2.Node的变化相对Pod而言较少,这样可以减少对LB设备的访问,LB可能会出错。
3.LBServiceType是基于NodePortType的,Service同时提供两种访问方式。
4.集群中每个节点被轮询到的机会均等,这使得每个节点需要解析iptables的机会一致,进而使iptables解析在每台机器的资源需求一致,避免某些节点因为iptablerules解析导致压力过大的可能性。
(与谷歌首席软件工程师TimHockin面对面讨论过此事)
kube-proxy:
接好最后一棒,从Node到Pod
我们知道,Kubernetes服务只是把应用对外提供服务的方式做了抽象,真正的应用跑在Pod的成员Container里,我们通过LB设备已经把提交至VIP的请求转到KubernetesNodes对应的nodePort上,那么nodePort上的请求是如何进一步转到提供后台服务的Pod的呢?
Kube-proxyisthesecretsauce,我们来看看kube-proxy都做了什么。
目前kube-proxy支持两种模式,userspace和iptables,iptables模式因为不需要userspace和kernelspace的切换,在数据转发上有更高的效率。
所以从1.2版本开始,iptables是默认模式,只有当kernel版本不支持iptables时,userspace模式才需要被启用。
Kubernetes只操作了Filter和Nat表。
Filter
在该表中,一个基本原则是只过滤数据包而不修改他们。
filtertable的优势是小而快,可以hook到input,output和forward。
这意味着针对任何给定的数据包,只有可能有一个地方可以过滤它。
NAT
此表的主要作用是在PREROUTING和POSTROUNTING的钩子中,修改目标地址和原地址。
与filter表稍有不同的是,该表中只有新连接的第一个包会被修改,修改的结果会自动apply到同一连接的后续包中。
下面是基于iptableschain的数据包流向图
基于iptables的kube-proxy的实现代码在pkg/proxy/iptables/proxier.go,其主要职责包括两大块,一块是侦听Service更新事件,并更新Service相关的iptables规则,一块是侦听Endpoint更新事件,更新Endpoint相关的iptables规则,将包请求转入Endpoint对应的Pod,如果某个Service尚没有Pod创建,那么针对此Service的请求将会被drop掉。
kube-proxy对iptables的链进行了扩充,自定义了KUBE-SERVICES,KUBE-NODEPORTS,KUBE-POSTROUTING,KUBE-MARK-MASQ和KUBE-MARK-DROP五个链,并主要通过为KUBE-SERVICESchain增加rule来配制RoutingTraffic规则。
我们可以通过对照源码和iptables规则表,来分析针对下面的Service信息,Kubernetes做了怎么样的iptables配制。
kubectlgetsvces1-oyaml
apiVersion:
v1
kind:
Service
metadata:
creationTimestamp:
2016-08-26T05:
03:
38Z
labels:
component:
elasticsearch
name:
es1
namespace:
default
resourceVersion:
"
7514"
selfLink:
/api/v1/namespaces/default/services/es1
uid:
72f28428-6b4a-11e6-887a-42010af00002
spec:
clusterIP:
10.0.147.93
ports:
-name:
http
nodePort:
32135
port:
9200
protocol:
TCP
targetPort:
selector:
sessionAffinity:
None
type:
LoadBalancer
status:
loadBalancer:
ingress:
-ip:
104.197.138.206
kubectlgetendpointses1
NAME
ENDPOINTS
AGE
es1
10.180.2.11:
9200
11d
在iptables表中,通过iptables-save可以看到在Nat表中创建好的这些链。
KUBE-MARK-DROP-[0:
0]/*对于未能匹配到跳转规则的trafficsetmark0x8000,有此标记的数据包会在filter表drop掉*/
KUBE-MARK-MASQ-[0:
0]/*对于符合条件的包setmark0x4000,有此标记的数据包会在KUBE-POSTROUTING
chain中统一做MASQUERADE*/
KUBE-NODEPORTS-[0:
0]/*针对通过nodeport访问的package做的操作*/
KUBE-POSTROUTING-[0:
0]
KUBE-SERVICES-[0:
0]/*操作跳转规则的主要chain*/
为默认的PREROUTING,Output和POSTROUTINGchain增加规则,跳转至Kubernetes自定义的新chain。
-APREROUTING-mcomment--comment"
kubernetesserviceportals"
-jKUBE-SERVICES
-AOUTPUT-mcomment--comment"
-APOSTROUTING-mcomment--comment"
kubernetespostrouting
rules"
-jKUBE-POSTROUTING
对于KUBE-MARK-MASQ链中所有规则设置了Kubernetes独有MARK标记,在KUBE-POSTROUTING链中对NODE节点上匹配Kubernetes独有MARK标记的数据包,进行SNAT处理。
-AKUBE-MARK-MASQ-jMARK--set-xmark0x4000/0x4000
Kube-proxy接着对每个服务创建“KUBE-SVC-”链,并在Nat表中将KUBE-SERVICES链中每个目标地址是Service的数据包导入这个“KUBE-SVC-”链,如果Endpoint尚未创建,KUBE-SVC-链中没有规则,任何IncomingPackets在规则匹配失败后会被KUBE-MARK-DROP。
-AKUBE-SERVICES!
-s10.180.0.0/14-d10.0.147.93/32-p
tcp-mcomment--comment"
default/es1:
httpclusterIP"
-mtcp--dport9200-jKUBE-MARK-MASQ
/*非Pod内部,针对clusterIP的请求,做snat操作*/
-AKUBE-SERVICES-d10.0.147.93/32-ptcp-mcomment--comment
-mtcp--dport9200-jKUBE-SVC-LAS23QA33HXV7KBL
/*针对clusterIP的请求*/
-AKUBE-SERVICES-d104.197.138.206/32-ptcp-mcomment
--comment"
httploadbalancerIP"
-mtcp--dport9200-jKUBE-FW-LAS23QA33HXV7KBL/*针对LBIP的请求,直接交由iptables转发,防止来自cluster内部的请求给LB设备造成压力*/
-AKUBE-FW-LAS23QA33HXV7KBL-mcomment--comment"
http
loadbalancerIP"
-jKUBE-MARK-MASQ
-jKUBE-SVC-LAS23QA33HXV7KBL
-jKUBE-MARK-DROP
调用openLocalPort侦听ServicenodePort,增加KUBE-NODEPORTSchain,并添加跳转规则将此端口收到的Packets转到KUBE-SVC-LAS23QA33HXV7KBL链。
-AKUBE-SERVICES-mcomment--comment"
kubernetesservice
nodeports;
NOTE:
thismustbethelastruleinthischain"
-maddrtype--dst-typeLOCAL-jKUBE-NODEPORTS/*来自集群外部,通过NodePort或者LoadBalancer访问的请求*/
-AKUBE-NODEPORTS-ptcp-mcomment--comment"
http"
-mtcp--dport32135-jKUBE-MARK-MASQ
-mtcp--dport32135-jKUBE-SVC-LAS23QA33HXV7KBL
EndpointChain,当接收到的ServiceInfo中包含Endpoint信息时,为Endpoint创建跳转规则。
-jKUBE-SEP-G4AX7RHRQVIX7P25
-AKUBE-SEP-G4AX7RHRQVIX7P25-s10.180.2.11/32-mcomment
-AKUBE-SEP-G4AX7RHRQVIX7P25-ptcp-mcomment--comment
-mtcp-jDNAT--to-destination10.180.2.11:
9200
如果Service类型为nodePort,(从LB转发至Node的数据包均属此类)那么将KUBE-NODEPORTS链中每个目的地址是Node节点端口的数据包导入这个“KUBE-SVC-”链。
-maddrtype--dst-typeLOCAL-jKUBE-NODEPORTS
如果一个Service对应的Pod有多个Replicas,在iptables中会有多条记录,并通过-mstatistic--moderandom--probability来控制比率。
-AKUBE-SVC-7BB4GED2QYDGC4GN-mcomment--comment"
kube-system/elasticsearch-logging:
"
-mstatistic--moderandom--probability0.50000000000-jKUBE-SEP-I7ND2XAHQESZGFZQ
-jKUBE-SEP-OECUK2RLRF65RRGG
Iptableschain支持嵌套并因为依据不同的匹配条件可支持多种分支,比较难用标准的流程图来体现调用关系,为进一步归纳iptables的跳转流程,上面的PREROUTINGchain的最终跳转规则,抽象为下图,仅供参考。
针对通过ClusterLB转发进来的外部请求,因为LB设备的memeber是nodeIP:
nodePort,所以针对这类请求,在iptables层走的是KUBE-N
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Kubernetes Service服务发布实践 Service 服务 发布 实践