关于kubernetes:一文读懂k8s的外网访问方式IngressNodePortLoadBanlancer

43次阅读

共计 6634 个字符,预计需要花费 17 分钟才能阅读完成。

​ 本文首发自「慕课网」,想理解更多 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/v1
kind: Ingress
metadata:
  name: my-ingress
spec:
  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/v1
kind: Ingress
metadata:
  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: v1
kind: Service
metadata:
  name: my-loadbalancer-service
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: nlb
spec:
  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: v1
kind: Service
metadata:
  name: my-nodeport-service
spec:
  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 圈优质内容,分享干货常识,大家一起独特成长吧!
本文原创公布于慕课网,转载请注明出处,谢谢合作

正文完
 0