有没有办法不使用GKE的标准负载均衡器?

时间:2018-04-08 09:53:57

标签: kubernetes google-compute-engine traefik

我正在尝试使用Kubernetes来明确定义配置和部署,我也喜欢Kubernetes的pod调度机制。 (现在)只有2个应用程序在3个节点上的2个副本上运行。但谷歌的Kubernetes Engine的负载均衡器对于像我们这样的小型应用程序来说是非常昂贵的(至少在目前),同时我不愿意改变容器上的单实例托管解决方案或在Docker swarm上部署应用程序等。

使用节点的IP似乎是一个黑客,我认为它可能会暴露集群内部的一些安全问题。因此,我配置了一个Træfik入口和一个入口控制器,以克服谷歌昂贵的负载平衡率,但结果是一个外向的入口旋转了一个标准的负载平衡器,或者我错过了什么。

我希望自己错过了这个价格(每月16美元)我无法从启动时使用kubernetes合理化这个应用程序。

有没有办法在不使用Google的负载均衡器的情况下使用GKE?

4 个答案:

答案 0 :(得分:2)

一种选择是在GKE集群上完全禁用此功能。在加载项下创建群集(在console.cloud.google.com上)时,禁用 HTTP负载平衡。如果您使用的是gcloud,则可以使用gcloud beta container clusters create ... --disable-addons=HttpLoadBalancing

或者,您也可以通过向Ingress资源添加注释kubernetes.io/ingress.class=somerandomstring来禁止GCP负载均衡器。

对于新创建的入口,您可以将其放在yaml文档中:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: somerandomstring
...

如果您想为所有Ingress 执行此操作,可以使用此示例代码段(小心!):

kubectl get ingress --all-namespaces \
  -o jsonpath='{range .items[*]}{"kubectl annotate ingress -n "}{.metadata.namespace}{" "}{.metadata.name}{" kubernetes.io/ingress.class=somerandomstring\n"}{end}' \
  | sh -x

现在使用Ingresses对Kubernetes非常有用,所以我建议您查看nginx ingress controller并在部署后相应地注释您的Ingresses。

答案 1 :(得分:2)

Ingress只是一组规则,它们告诉集群如何路由到您的服务,而Service是另一组规则,可以在一组Pod上达到并实现负载均衡,基于选择器。服务可以使用3种不同的路由类型:

  • ClusterIP-这为服务提供了IP,该IP仅在路由到Pod的群集内可用。
  • NodePort-这将设置ClusterIP,然后在集群中的每个单个节点上创建一个外部可访问的端口。到这些端口的流量先路由到内部服务IP,再路由到Pod。
  • LoadBalancer-这将设置一个ClusterIP,然后设置一个NodePort,然后从提供程序(如果在GKE上可用)提供一个负载均衡器,以使流量到达负载均衡器,然后到达一个节点上的端口,然后是内部ip,最后是一个pod。

这些不同类型的服务不是互斥的,而是实际上彼此构建的,它解释了为什么任何公共场所都必须使用NodePort。考虑一下-流量将如何到达您的集群?云负载平衡器仅将请求定向到您的节点并指向NodePort端口之一。如果您不希望使用GKE负载平衡器,则可以跳过它并直接访问那些端口。

缺点是端口限制在30000-32767之间。如果您需要标准的HTTP端口80/443,则无法使用Service完成此操作,而必须直接在Deployment中指定端口。使用hostPort设置将容器直接绑定到节点上的端口80:

containers:
  - name: yourapp
    image: yourimage
    ports:
      - name: http
        containerPort: 80
        hostPort: 80 ### this will bind to port 80 on the actual node

这可能对您有用,并且将流量直接路由到容器,而没有任何负载平衡,但是如果节点出现问题或应用程序停止在节点上运行,则它将不可用。

如果您仍然想要负载平衡,则可以运行DaemonSet(以便在每个节点上都可以使用),并使Nginx(或任何其他代理)通过hostPort公开,然后路由到您的内部服务。一种简单的运行方法是使用标准nginx-ingress软件包,但是跳过为其创建LoadBalancer服务并使用hostPort设置。可以为此配置Helm图表:

https://github.com/helm/charts/tree/master/stable/nginx-ingress

答案 2 :(得分:0)

您可以使用NodePort模式部署nginx入口控制器(例如,如果使用helm chart设置controller.service.typeNodePort),然后使用DNS在您的实例之间进行负载平衡。只需确保您拥有节点的静态IP,或者您甚至可以创建DaemonSet以某种方式更新您的DNS与每个节点的IP。

Traefik似乎支持类似的配置(例如,通过helm chart中的serviceType

答案 3 :(得分:0)

如果将Ingress类指定为Ingress对象的注释

kubernetes.io/ingress.class: traefik

Traefik会在Google Load Balancer忽略它的同时接听它。还有a bit of Traefik documentation on this part