本文首发自「慕课网」,想理解更多IT干货内容,程序员圈内热闻,欢送关注"慕课网"!
作者:一凡|慕课网讲师
集群内拜访
在k8s中创立的微服务,大部分都是在集群外部相互调用,这时候,应用DNS就能够很方面拜访。
比方:服务名是 my-service,端口号是8080,命名空间是yifan,那么就能够通过域名+端口 “my-service.yifan.svc.cluster.local:8080” 在集群内拜访。
当然,也能够间接用服务的ClusterIP+服务的端口号,只是这么应用的较少。
DNS解析到的IP也就是这个服务的ClusterIP,只是咱们不须要记住ClusterIP,记住服务名对应的域名更加容易。
编辑
如上图所示,就是k8s集群内的服务拜访流程。
客户端通过DNS服务的域名解析 my-service.yifan.svc.cluster.local 返回这个服务的ClusterIP。
而后创立TCP连贯到这个ClusterIP+端口号上。
网络申请通过Iptables/ipvs规定解决,通过负载平衡策略,把这个ClusterIP重定向到服务的后端实例,也就是这个服务的某一个Pod得PodIP。
这样TCP连贯胜利创立,客户端也就建设了与服务的后端实例的连贯,也就能够进行后续的申请了。
上面是Cluster类型的service的yaml文件示例:
这个YAML文件蕴含以下内容:
apiVersion: 指定Kubernetes API的版本。kind: 指定要创立的对象类型,此处为Service。metadata.name: 指定Service的名称,此处为“my-service”。spec.type: 指定Service的类型,此处为“ClusterIP”。spec.selector: 指定要为Service抉择的Pod或正本集的标签选择器。在这个例子中,标签选择器是“app=my-app”。spec.ports: 指定要公开的端口及其配置信息。在这个例子中,将公开端口80,名称为“http”,将流量转发到Pod中的端口8080。
要应用此YAML文件创建Service,请应用以下命令:
这是集群内拜访的流程,接下来,再来看看本文的核心内容,外网如何拜访。
集群外拜访
k8s集群的外网拜访形式有3种:
Ingress, NodePort和LoadBanlancer。
其中Ingress是k8s的一个形象层,有很多的IngressController和服务能够来实现这个Ingress服务,而后由这个Ingress服务把外网的申请转发到集群内的服务。
NodePort和LoadBanlancer是k8s中service的类型。下面讲到的集群内拜访,ClusterIP也是service的一种类型。
而LoadBanlancer类型须要各个云厂商本人来实现的CloudControllerManager,所以,采纳不同的云厂商,它们的LoadBanlancer也就会有一些区别,它们的性能以及应用办法也就不一样了。
接下里,咱们就独自来看看这3种外网拜访形式吧。
Ingress转发外网申请
先来看下Ingress配置的yaml文件:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: my-ingressspec: rules: - host: yifan-online.com http: paths: - path: /app1 pathType: Prefix backend: service: name: app1-service port: name: http - path: /app2 pathType: Prefix backend: service: name: app2-service port: name: http
此文件指定了一个名为“my-ingress”的Ingress,将传入的申请路由到两个不同的服务,其中一个服务名称为“app1-service”,另一个服务名称为“app2-service”。
请留神,此文件的标准局部中指定了两个规定,每个规定都蕴含一个主机名和一组门路规定。每个门路规定都指定了如何将传入申请路由到服务。
如要反对gRPC协定,配置的yaml文件如下:
apiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: grpc-ingress annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/backend-protocol: "GRPC"spec: rules: - host: yifan-online.com http: paths: - path: /grpc backend: serviceName: grpc-service servicePort: 9000
在这个示例中,咱们指定了Ingress类为nginx,并应用了nginx负载均衡器来反对gRPC协定。而后,咱们定义了一个名为“grpc-service”的gRPC服务,它将运行在端口9000上。
接下来,咱们定义了一个Ingress规定,它将传入的申请路由到主机“yifan-online.com”的“/grpc”门路。这个规定应用了咱们先前定义的gRPC服务,并将所有申请转发到端口9000上的gRPC服务。
请留神,在此示例中,咱们还应用了一个非凡的正文“nginx.ingress.kubernetes.io/backend-protocol: “GRPC””,它指定了gRPC作为后端协定。这个正文将通知nginx负载均衡器将申请路由到gRPC服务。
下面的yaml文件,咱们晓得如何通过Ingress服务来做申请转发,是通过host和path来辨认申请,而后转发到backend的servieName和servicePort。
那么,外网的客户端,要怎么申请到这个Ingress呢?
这时候,还是须要有一个外网可拜访LoadBanlancer来把外网申请接入进来,转发到Ingess上。
而下面的Ingress配置,只是一个配置转发的规定,还须要有一个实在存在的Ingress服务才能够实现下面的转发逻辑。
这时候,就须要例如:NginxIngress服务。
所以,还须要部署一个NginxIngress服务,当然也有很多其余类型的Ingress服务。
综上,咱们再来看下Ingress形式的外网申请,是怎么的一个解决流程吧。
编辑
下面的LoadBanlancer是云厂商提供的一个服务,所以也是要独自免费的。
Ingress服务须要在集群内部署一个Nginx服务(其余的Ingress服务也是相似)。
host+path是Ingress的转发规定,所有实现了IngressController的服务都是能够反对的。
那么再来看下LoadBanlancer吧。
LoadBanlancer接入外网申请
要配置Kubernetes中的LoadBalancer,能够编写一个LoadBalancer的Service YAML文件,其中蕴含无关如何将Kubernetes Service公开到内部的信息。
以下是一个根本的LoadBalancer Service YAML文件示例:
apiVersion: v1kind: Servicemetadata: name: my-loadbalancer-service annotations: service.beta.kubernetes.io/aws-load-balancer-type: nlbspec: type: LoadBalancer selector: app: my-app ports: - name: http port: 80 targetPort: 8080 protocol: TCP
在这个示例中,咱们定义了一个名为“my-loadbalancer-service”的Service,它将应用LoadBalancer来公开Kubernetes集群中的应用程序。其中的“type: LoadBalancer”申明将通知Kubernetes将此服务配置为应用LoadBalancer。
接下来,咱们定义了一个选择器,它将抉择具备标签“app: my-app”的Pod作为后端。咱们还指定了一个端口“80”,它将用于将传入申请路由到Pod的端口“8080”。
请留神,这个示例还蕴含一个名为“service.beta.kubernetes.io/aws-load-balancer-type”的正文,它指定了LoadBalancer的类型。在这个示例中,咱们应用了Amazon Web Services(AWS)的Network Load Balancer(NLB)类型。如果您应用的是其余云提供商或本人的LoadBalancer,您能够依据须要更改此正文。
实现了这个配置文件并且Service曾经创立时,Kubernetes将为您创立一个LoadBalancer,并为您的应用程序调配一个惟一的IP地址。您能够应用此IP地址来拜访您的应用程序。请留神,不同的云提供商可能会有不同的形式来拜访LoadBalancer的IP地址。
很多云厂商在实现LoadBanlancer的时候,还会用到NodePort服务类型,比方:腾讯云的CLB。
最初,再来看下LoadBanlancer的解决流程。
编辑
最初,咱们再来看下NodePort这种外网拜访形式吧。
NodePort接入外网申请
要配置一个Kubernetes的NodePort,您能够编写一个NodePort的Service YAML文件,其中蕴含无关如何裸露Kubernetes Service的信息。
以下是一个根本的NodePort Service YAML文件示例:
apiVersion: v1kind: Servicemetadata: name: my-nodeport-servicespec: type: NodePort selector: app: my-app ports: - name: http port: 80 targetPort: 8080 protocol: TCP nodePort: 30000
在这个示例中,咱们定义了一个名为“my-nodeport-service”的Service,它将会应用NodePort来裸露Kubernetes集群内的应用程序。其中的“type: NodePort”申明将通知Kubernetes将此服务配置为应用NodePort。
接下来,咱们定义了一个选择器,它将抉择具备标签“app: my-app”的Pod作为后端。咱们还指定了一个端口“80”,它将用于将传入申请路由到Pod的端口“8080”。
此外,咱们还指定了一个NodePort“30000”,这将是咱们将用来从集群外拜访Service的端口。Kubernetes将在集群节点上随机抉择此端口。
请留神,您能够通过将“nodePort”字段留空来让Kubernetes主动抉择端口。然而,为了防止端口抵触,倡议指定一个特定的端口号。
当您实现了这个配置文件并且Service曾经创立时,您能够应用集群节点的IP地址和NodePort来拜访Service。例如,在这个示例中,您能够应用节点的IP地址和端口“30000”来拜访应用程序。
K8S集群中的工作节点有外网IP,就能够通过这些外网IP+NodePort裸露的端口号来拜访到K8S集群外部的服务了。
在 Kubernetes 中,NodePort 的端口号范畴默认是从 30000 到 32767。这个范畴能够通过 kube-apiserver 的 --service-node-port-range 参数进行配置。
在理论应用中,须要留神端口号的抵触问题,也要防止滥用NodePort裸露了外网端口引发的平安问题。
那咱们再来看下NodePort的数据处理流程。
编辑
创立一个 NodePort 类型的 Service 时,Kubernetes 会在集群中的每个节点上凋谢一个指定的端口号,例如 30000。每个节点上的 kube-proxy 组件会监听该端口号,并将所有流量转发到后端 Pod 的相应端口上。
具体来说,kube-proxy 会在每个节点上启动一个代理服务器(即 iptables 或者 IPVS),并为每个 Service 调配一个惟一的虚构 IP 地址(即 ClusterIP)。当有申请达到 NodePort 时,kube-proxy 会依据负载平衡策略将申请转发到某个节点上,并应用该节点上的代理服务器将申请转发到相应的后端 Pod 上。后端 Pod 的响应将通过同样的形式返回给客户端。
看到这里,大家晓得如何配置和应用这些服务了吗?
当初,你能残缺的把一个外网申请,从LoadBanlancer到NodePort,再到Ingress,最初到服务实例的全副过程了吗?
总结和比照
Ingress、NodePort和LoadBalancer都是Kubernetes中用于将Service公开到内部的办法,但它们之间有一些区别和实用场景。以下是一些抉择的倡议:
Ingress:如果须要在同一IP地址和端口上公开多个服务,并依据申请门路或主机名进行路由,则能够应用Ingress。 Ingress是Kubernetes中的一个形象层,它能够将多个Service公开到同一个IP地址和端口上,并依据申请门路或主机名进行路由,非常适合用于Web应用程序。NodePort:如果您须要将一个Service公开到集群内部,但又不想应用负载均衡器,则能够应用NodePort。 NodePort将Service公开到所有节点的IP地址上,并将随机端口映射到指标端口。如果您只须要将一个Service公开到内部,并且您有一个动态IP地址或DNS名称来拜访它,则NodePort可能是一个不错的抉择。LoadBalancer:如果您须要将一个Service公开到内部,并且须要一个负载均衡器来解决流量,则能够应用LoadBalancer。 LoadBalancer能够将流量负载平衡到多个Pod之间,从而进步应用程序的可用性和可伸缩性。如果您正在运行在公共云环境中,例如AWS、Azure或GCP,那么您能够应用云提供商的负载均衡器服务,否则您能够应用Kubernetes自带的负载均衡器。
在云厂商的服务中,如果要应用Ingress裸露k8s集群内的服务到外网,实际上会用也到LoadBanlancer和NodePort类型,只是大家不用关怀它的外部实现细节而已。
Ingress和网关的区别
Ingress是Kubernetes中的一个形象层,它容许您公开多个服务到同一IP地址和端口,并依据申请门路或主机名进行路由。 Ingress通常用于HTTP/HTTPS流量,并且能够反对TLS endpoint、基于门路的路由和负载平衡等性能。能够应用Kubernetes Ingress Controller实现Ingress性能,例如Nginx Ingress Controller、Traefik Ingress Controller和Istio Ingress Gateway。
网关(Gateway)通常是一个独立的组件,用于提供对应用程序的访问控制、身份验证、安全性、流量治理和监督等性能。 网关通常能够反对多个协定和传输层,并且能够部署在Kubernetes集群之外,例如API网关、网络应用防火墙(WAF)和服务网格(Service Mesh)等。流量能够通过不同的形式路由到网关,例如DNS名、IP地址、负载均衡器和Ingress等。
简而言之,Ingress是Kubernetes中的一个形象层,用于将多个服务公开到同一IP地址和端口,并依据申请门路或主机名进行路由,而网关则是提供对应用程序的访问控制、身份验证、安全性、流量治理和监督等性能的组件,它能够与Kubernetes集群一起应用,但也能够独立于Kubernetes集群之外部署。
不晓得大家还有什么想要理解的,能够在评论区提出来,后续能够接着细聊。
欢送关注「慕课网」(www.imooc.com)官网帐号,咱们会始终保持内容原创,提供IT圈优质内容,分享干货常识,大家一起独特成长吧!
本文原创公布于慕课网 ,转载请注明出处,谢谢合作