如何在不使用 LoadBalancer 类型的情况下发布 Kubernetes 服务(在 GCP 上)

How can you publish a Kubernetes Service without using the type LoadBalancer (on GCP)

我想避免对某个 Kubernetes 服务使用 type: "LoadBalancer",但仍然能够将其发布到互联网上。我正在使用 Google 云平台 (GCP) 来 运行 Kubernetes 集群,目前 运行 在单个节点上。

我尝试向我们提供 externalIPs 服务配置并轮流提供以下 IP:

None 以上帮助我使用具有 externalIPs 配置的 Kubernetes 服务访问我的应用程序。

那么,如何在不使用 LoadBalancer 类型的 Kubernetes 服务的情况下在 Internet 上发布服务。

如果您不想使用 LoadBalancer 服务,公开您的服务的其他选项 public 有:

类型NodePort

创建您的服务,将 type 设置为 NodePort,Kubernetes 将在您的服务将在其上公开的所有节点 VM 上分配一个端口 (docs)。例如。如果你有 2 个节点,w/ public IPs 12.34.56.7823.45.67.89,并且 Kubernetes 分配你的服务端口 31234,那么该服务将 public 仅在两个 12.34.56.78:31234 & 23.45.67.89:31234

指定externalIPs

如果你有能力将 public IP 路由到你的节点,你可以在你的服务中指定 externalIPs 来告诉 Kubernetes "If you see something come in destined for that IP w/ my service port, route it to me." (docs)

集群端点不适用于此,因为那只是您的 Kubernetes 主节点的 IP。另一个 LoadBalancer 服务的 public IP 将不起作用,因为 LoadBalancer 仅配置为路由该原始服务的端口。我希望节点 IP 可以工作,但如果您的服务端口是特权端口,它可能会发生冲突。

使用 /proxy/ 端点

Kubernetes API 包含一个 /proxy/ 端点,允许您访问集群端点 IP 上的服务。例如。如果您的集群端点是 1.2.3.4,您可以通过使用集群凭据访问 https://1.2.3.4/api/v1/proxy/namespaces/my-ns/services/my-service 来访问命名空间 my-ns 中的 my-service。这实际上应该只用于 testing/debugging,因为它会在到达服务的途中通过 Kubernetes master 处理所有流量(额外的跃点、SPOF 等)。

有几种惯用的方法可以在 Kubernetes 中向外部公开服务(参见注释#1):

  1. Service.Type=LoadBalancer,正如 OP 指出的那样。
  2. Service.Type=NodePort,这会暴露节点的IP。
  3. Service.Type=ExternalName,通过返回CNAME记录将Service映射到externalName字段的内容(需要CoreDNS 1.7或更高版本才能使用ExternalName类型。)
  4. 入口。这是一个新概念,将永恒的 HTTP and/or HTTPS 路由暴露给 Kubernetes 集群内的服务,您甚至可以将一个路由映射到多个服务。但是,这仅映射 HTTP and/or HTTPS 路由。 (见注释#2

还有另一种选择:在您的广告连播中设置 hostNetwork 标志。

比如你可以使用helm3这样安装nginx:

 helm install --set controller.hostNetwork=true nginx-ingress nginx-stable/nginx-ingress

nginx 然后在运行 pod 的节点的 IP 地址上的端口 80 和 443 可用。您可以使用节点选择器或亲和力或其他工具来影响此选择。