service的作用体现在两个方面:
在Kubernetes中,Pod的IP地址和service的ClusterIP仅可以在集群网络内部做用,对于集群外的应用是不可见的。为了使外部的应用能够访问集群内的服务,Kubernetes目前提供了以下几种方案:
Ingress解决的是新的服务加入后,域名和服务的对应问题,基本上是一个ingress的对象,通过yaml进行创建和更新进行加载。工作机制大致可以用下图表示:
实际上,ingress相当于一个7层的负载均衡器,是k8s对反向代理的一个抽象。大概的工作原理也确实类似于Nginx,可以理解成在 Ingress 里建立一个个映射规则 , ingress Controller 通过监听 Ingress这个api对象里的配置规则并转化成 Nginx 的配置(kubernetes声明式API和控制循环) , 然后对外部提供服务。
Ingress包含了两大组件Ingress Controller和Ingress。
ingress是一个API对象,通过yaml文件来配置,ingress对象的作用是定义请求如何转发到service的规则,可以理解为配置模板。 ingress通过http或https暴露集群内部service,给service提供外部URI、负载均衡、SSL/TLS能力以及基于域名的反向代理。ingress要依靠ingress-controiler来具体实现以上功能。
简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。
Ingress 格式示例:
- apiVersion: extensions/v1beta1
- kind: Ingress
- metadata:
- name: test-ingress
- spec:
- rules:
- - http:
- paths:
- - path: /testpath
- backend:
- serviceName: test
- servicePort: 80
每个 Ingress 都需要配置 rules,目前 Kubernetes 仅支持 http 规则。上面的示例表示请求 /testpath 时转发到服务 test 的 80 端口。
ingress-controller是具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。 ingress-controller并不是k8s自带的组件,实际上ingess-controller只是一个统称,用户可以选择不同的ingress-controller实现,目前,由k8s维护的ingress-controller只有google云的GCE与ingress-nginx两个,其他还有很多第三方维护的ingress-controller,比如Contour, Haproxy, trafik, Istio,具体可以参考官方文档。 但是不管哪一种ingress-controller,实现的机制都大同小异,只是在具体配置上有差异,ingress controller核心是一个deployment,需要编写的yaml有:Deployment, Service, ConfigMap, ServiceAccount(Auth),其中service的类型可以是NodePort或者LoadBalancer。 一般来说,ingress-controller的形式都是一个pod,里面跑着demon程序和反向代理程序。daemon负责不断监控集群的变化,根据ingress对象生成配置并应用新配置到反向代理,比如ingress-nginx就是动态生成nginx配置,动态更新upstreanm,并在需要的时候reload程序应用新配置。为了方便,后面的例子都以k8s官方维护的ingress-nginx为例。 Ingress-Nginx github 地址: GitHub - kubernetes/ingress-nginx: Ingress-NGINX Controller for Kubernetes
Ingress-Nginx 官方网站: Welcome - NGINX Ingress Controller
Ingress Controller是将Ingress这种变化生成一段Nginx的配置,然后将这个配置通过Kubernetes API写到Nginx的Pod中,然后reload.(注意:写入 nginx.conf 的不是service的地址,而是service backend 的 pod 的地址,避免在 service 在增加一层负载均衡转发)。
从上图中可以很清晰的看到,实际上请求进来还是被负载均衡器拦截,比如 nginx,然后 Ingress Controller 通过跟 Ingress 交互得知某个域名对应哪个 service,再通过跟 kubernetes API 交互得知 service 地址等信息;综合以后生成配置文件,实时写入负载均衡器,然后负载均衡器 reload 该规则便可实现服务发现,即动态映射:
客户端一般会把请求发送到负载均衡器上由负载均衡器转发到ingress控制所在的node节点上目的减小Node节点的负载压力。ingress控制器会根据ingress资源对象的配置转发请求到对应的service;service会根据端点,把请求转发到关联的Pod。
在使用普通的Service时,集群中每个节点的kube-proxy在监听到Service和Endpoints的变化时,会动态的修改相关的iptables的转发规则。 客户端在访问时通过iptables设置的规则进行路由转发达到访问服务的目的。
而Ingress则跳过了kube-proxy这一层,通过Ingress Controller中的代理配置进行路由转发达到访问目标服务的目的。实际上可以把IngressController看做一个拥有默认处理后端的代理,根据Ingress资源的配置动态修改代理的配置文件,以实现按照规则转发请求的功能。
k8s ingress原理及ingress-nginx部署测试_个人文章 - SegmentFault 思否
K8S对外服务之Ingress_51CTO博客_k8s ingress
K8S中的ingress_84岁带头冲锋的博客-CSDN博客_k8s的ingress
k8s 对外服务之ingress_新是一切的根源的博客-CSDN博客_ingress k8s
《重识云原生系列》专题索引:
第六章容器基础6.4.10.4节——StatefulSet实操案例-使用 StatefulSet 部署Cassandra