2017-11-17 61 views
1

TL负载平衡器; DR:nginx-ingress-controller影响在不同的域一次,每5〜请求另一个LoadBalancer服务。K8S入口影响在不同的域

我对GCE上的Kubernetes有一个奇怪的情况,我被卡住了。我不知道我是否有配置,或者是否已经偶然发现k8s中的一个(非常严重)错误。

我有两个LoadBalancer服务,每个服务都有自己的静态IP和指向它们的DNS记录。

一个LoadBalancer通过它的选择器直接指向运行我的API网络服务器的部署,这是api.domain.com。由于复杂的客户端证书认证方案,这个API不能位于入口控制器后面,这对于nginx入口来说是不可能的。

其他LoadBalancer服务指向NGINX入口控制器。这服务于我的网站site.domain.com。我使用标准nginx-default-backend来为入口控制器提供404服务。

问题是,当我在浏览器中加载API(在api.domain.com),每3或4次我刷新404从nginx-default-backend服务。

所以每一次的5倍左右,从一个完全不同的域的网页(site.domain.com234.234.234.234)送达我的API域(api.domain.com123.123.123.123)。我不明白这是怎么发生的。

一旦我删除nginx-ingress-controller,API将正常工作。我真的很困惑。

对于API:

apiVersion: v1 
kind: Service 
metadata: 
    name: api 
spec: 
    type: LoadBalancer 
    loadBalancerIP: 123.123.123.123 
    selector: 
    app: api 
    ports: 
    - port: 443 

而对于网站:

apiVersion: v1 
kind: Service 
metadata: 
    name: nginx-ingress-lb 
    labels: 
    app: nginx-ingress-lb 
spec: 
    type: LoadBalancer 
    loadBalancerIP: 234.234.234.234 
    ports: 
    - port: 443 
    name: https 
    selector: 
    # Selects nginx-ingress-controller pods 
    app: nginx-ingress-controller 
--- 
apiVersion: extensions/v1beta1 
kind: Deployment 
metadata: 
    name: nginx-ingress-controller 
    labels: 
    app: nginx-ingress-controller 
spec: 
    replicas: 1 
    template: 
    metadata: 
     name: nginx-ingress-controller 
     labels: 
     app: nginx-ingress-controller 
    spec: 
     terminationGracePeriodSeconds: 60 
     containers: 
     - image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.9.0-beta.17 
     name: nginx-ingress-controller 
     readinessProbe: 
      httpGet: 
      path: /healthz 
      port: 10254 
      scheme: HTTP 
     livenessProbe: 
      httpGet: 
      path: /healthz 
      port: 10254 
      scheme: HTTP 
      initialDelaySeconds: 10 
      timeoutSeconds: 1 
     ports: 
     - containerPort: 443 
      hostPort: 443 
     env: 
      - name: POD_NAME 
      valueFrom: 
       fieldRef: 
       fieldPath: metadata.name 
      - name: POD_NAMESPACE 
      valueFrom: 
       fieldRef: 
       fieldPath: metadata.namespace 
     args: 
     - /nginx-ingress-controller 
     - --default-backend-service=$(POD_NAMESPACE)/nginx-default-backend 
     - --publish-service=$(POD_NAMESPACE)/nginx-ingress-lb 
--- 
apiVersion: extensions/v1beta1 
kind: Ingress 
metadata: 
    name: ingress 
    namespace: development 
spec: 
    tls: 
    - hosts: 
    - site.domain.com 
    secretName: "site.domain.com-tls" 
    rules: 
    - host: "site.domain.com" 
    http: 
     paths: 
     - backend: 
      serviceName: website 
      servicePort: http 

我迄今检查:

我检查使用host -a我的DNS记录,他们都是正确。我使用kubectl get po -l app=website检查了选择器中的名称冲突,没有发现冲突。我已检查绑定的IP地址:

> kubectl get svc 
NAME     TYPE   CLUSTER-IP  EXTERNAL-IP  PORT(S) 
api      LoadBalancer 10.3.240.197 123.123.123.123 443:32126/TCP 
nginx-default-backend ClusterIP  10.3.253.16 <none>   80/TCP 
nginx-ingress-lb  LoadBalancer 10.3.245.191 234.234.234.234 443:31051/TCP 
website     ClusterIP  10.3.254.180 <none>   80/TCP 

> kubectl get ingress 
NAME   HOSTS    ADDRESS   PORTS 
ingress  site.domain.com 234.234.234.234 80, 443 

> host api.domain.com 
api.domain.com has address 123.123.123.123 
> host site.domain.com 
site.domain.com has address 234.234.234.234 

对我来说都很好看。

我做错了什么,或者是有什么严重错误的K8S或Nginx的入口?

回答

0

这是一个有趣的。
我花了一些时间画图和hypothesising为什么错误是存在的,但最好的答案来自于GLBC README

不要在一个集群启动控制器2分的情况下,他们将 打对方

编辑

我认为这种行为是由于GCE负载均衡器转发规则是如何工作的相互冲突与nginx-ingress-controller(或反之亦然:))

从我可以告诉GCE负载均衡器转发规则接受转发给群集主机的同一端口号上的流量,即在您的示例中为:443

nginx-ingress-controller定义:

ports: 
     - containerPort: 443 
      hostPort: 443 

我们看到,Nginx的,进入舱体上的主机在:443听。
但GCE负载均衡器也转发给主机:443

全部放在一起

想象一下你的API荚部署在集群节点的某个子集说3/4。
然后,GCE负载平衡器的3/4时间将流量引导至具有侦听API窗口的主机 - 成功!

但是,第4个请求路由到端口443上没有运行API pod的节点。但是nginx-ingress-controller吊舱正在侦听,因此以404响应请求。

所以这个问题并不是真正的DNS解析之一,因为它可能会出现。


参考

以下引自K8S服务shortcomings似乎支持我的理论,为NodePort值未用,因此,端口转发是发生在同一端口上。

这是没有严格要求所有的云服务提供商(如谷歌 计算引擎并不需要分配一个NodePort使 负载平衡器的工作,但AWS一样)

GCE转发规则创建
https://github.com/kubernetes/kubernetes/blob/master/pkg/cloudprovider/providers/gce/gce_loadbalancer_external.go

+0

我正在运行[NGINX入口](https://github.com/kubernetes/ingress-nginx),而不是GCE入口。另外,我只有一个入口控制器正在运行。根据nginx入口的文档,只要您定义了类,就可以一起运行GCE和NGINX入口:'注意:部署多个入口控制器并且不指定注释将导致两个控制器争相满足入口。 。 –