2017-11-17 60 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入口:'注意:部署多個入口控制器並且不指定註釋將導致兩個控制器爭相滿足入口。 。 –