Kubernetes基础(三)-Service外部网络访问方式

1 概述

NodePort、LoadBalancer 和 Ingress 都是将集群外部流量导入到集群内的方式,只是实现方式不同。以下是三种方式的工作原理

注意:这里说的每一点都基于Google Kubernetes Engine。如果用 minikube 或其它工具,以预置型模式(om prem)运行在其它云上,对应的操作可能有点区别。

2 ClusterIP

ClusterIP 服务是 Kubernetes 的默认服务。它提供一个集群内的服务,集群内的其它应用都可以访问该服务。集群外部无法访问ClusterIP。

ClusterIP 服务的 YAML 文件类似如下:

apiVersion: v1 
kind: Service 
metadata:   
  name: my-internal-service 
selector:     
  app: my-app 
spec: 
  type: ClusterIP 
  ports:   
  - name: http 
    port: 80 
    targetPort: 80 
    protocol: TCP

从集群外是没法访问 ClusterIP 服务,那如何可以在集群外访问集群数据呢?可以通过 Kubernetes 的 proxy 模式来访问该服务,其链路如下:

proxy设置方式:

kubectl proxy --port=8080

2.1 访问方式

  • 启动 Kubernetes proxy后就可以使用http://localhost:8080/api/v1/proxy/namespaces//services/:/通过 Kubernetes API 访问 service。
  • 也可以使用http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/这个地址,访问上面定义的 service。

2.2 使用场景

  • 调试service,或直接从笔记本电脑连接到 service;
  • 允许内部流量访问,显示内部 dashboards 

由于此方法要求将 kubectl 作为认证用户运行,因此不能使用这个方法将service 暴露在公网上或将其用于生产环境下。

3 NodePort

NodePort 类型的 service 是让外部流量可以访问集群内部服务最基本的方式。NodePort是在所有 Node(VM)上打开一个特定的 port,任何发送到此 port 的流量都将转发到 service 上。

从技术上看,这也许不是最准确的图表,但它表明了 NodePort 的工作方式。

NodePort 类型的 service 的 YAML 如下所示:

apiVersion: v1 
kind: Service 
metadata:   
  name: my-nodeport-service 
selector:     
  app: my-app 
spec: 
  type: NodePort 
  ports:   
  - name: http 
    port: 80 
    targetPort: 80

    nodePort:30036
    protocol: TCP

3.1 与clusterip的区别

NodePort 类型的 service 与普通的 “ClusterIP” 类型的 service 有两点区别:

  • 类型是 “NodePort”;
  • 它有一个被称为 nodePort 的附加 port,可以在 node 上指定打开哪个 port 。如果不指定一个 port,NodePort 类型的 service 就会随机选择一个。大多数时候应该让 Kubernetes 来选择 port;

3.2 使用场景

  • 运行的服务不用保持始终可用;
  • 适用于一个演示应用程序或其他临时的东西

3.3 缺点

  • 每个端口只能绑定一个 service;
  • 可使用端口号只能是 30000 到 32767;
  • 如果节点/VM 的 IP 地址发生变化,需要做处理。

4 LoadBalancer

LoadBalancer (负载均衡器)类型的 service 是在公网上暴露服务的标准方式。在 GKE 上将启动一个网络LoadBalancer,该网络LoadBalancer将为svc提供一个 IP 地址,用来将所有流量转发到kubernetes service 上。

在云提供商上运行的Kubernetes集群通常支持从云基础架构自动提供负载平衡器。 所有需要做的就是设置服务的类型为Load Badancer而不是NodePort。 负载均衡器拥有自己独一无二的可公开访问的 IP 地址, 并将所有连接重定向到服务。可以通过负载均衡器的 IP 地址访问服务。如果Kubemetes在不支持Load Badancer服务的环境中运行, 则不会调配负载平衡器, 但该服务仍将表现得像 一 个NodePort服 务。 这是因为LoadBadancer服务是NodePort服务的扩展。 

Yaml文件: 

apiVersion: v1
kind: Service
metadata:
  name: kubia-loadbalancer
spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  selector:
    app: kubia

可以路由到 NodePort 服务和 ClusterIP 服务,这个需要结合具体的云厂商进行操作。 

4.1 使用场景

  • 需要直接暴露service到外部的应用。

4.2 缺点

  • 没有过滤条件,没有路由等。这意味着几乎可以发送任何种类的流量到该服务,像 HTTP,TCP,UDP,Websocket,gRPC 或其它任意种类。
  • 每一个用 LoadBalancer 暴露的服务都会有它自己的 IP 地址,每个用的 LoadBalancer 都需要付费,成本高;

5 Ingress

Ingress 实际上不是 service 的一个类型。其架构侧位于多个 service 之前,充当集群中的“智能路由器”或入口点。用户可以使用 Ingress 做很多不同的事情。现在市面上有许多不同类型的 Ingress 控制器,不同类型的ingress具有不同的功能。

默认的 GKE ingress 控制器将为k8s集群启动一个 HTTP(S)LoadBalancer。帮助用户用来执行基于路径和子域的路由到后端服务。例如:用户可以将http://a.baidu.com上的所有内容发送到 对应 service 上,将http://b.baiud.com/test 路径下所有内容发送到对应service 上。

GKE 上 Ingress 对象的 YAML 如下所示(带有 L7 HTTPLoadBalancer):

apiVersion: extensions/v1beta1 
kind: Ingress 
metadata: 
  name: my-ingress 
spec: 
  backend: 
    serviceName: other 
    servicePort: 8080 
  rules: 
  - host: foo.mydomain.com 
    http: 
      paths: 
      - backend: 
          serviceName: foo 
          servicePort: 8080 
  - host: mydomain.com 
    http: 
      paths: 
      - path: /bar/* 
        backend: 
          serviceName: bar 
          servicePort: 8080

 5.1 使用场景

Ingress 是暴露 service 最强大的方式,但也是最复杂的。其实,Ingress 控制器有很多类型,像来自 Google Cloud 的LoadBalancer,Nginx,Contour,Istio 等。还有用于 Ingress 控制器的插件,如 cert-manager,均可以为用户的 service 自动提供 SSL 证书。

如果业务需要在相同的 IP 地址下暴露多个 service,并且这些 service 都使用相同的 L7 协议(通常是 HTTP),此刻Ingress 是最适用的。如果业务需要使用GCP 集成,那么只需使用一台负载均衡器。由于 Ingress 是“智能的”,用户可以获得许多“开箱即用”的功能,如 SSL,Auth,路由等。

猜你喜欢

转载自blog.csdn.net/ygq13572549874/article/details/130982980