k8s Ingress影响不同域

时间:2017-11-17 22:25:37

标签: kubernetes

TL; DR: {@ 1}}每5次请求就会影响另一个域上的另一个nginx-ingress-controller服务。

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

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

一个LoadBalancer(通过它的选择器)直接指向部署,并在其上运行我的API网络服务器,这是LoadBalancer。由于复杂的客户端证书身份验证方案,此API不能位于入口控制器后面,而nginx入口无法实现这一点。

另一个LoadBalancer服务指向NGINX入口控制器。在api.domain.com为我的网站提供服务。我使用标准site.domain.com从入口控制器为404服务。

问题在于,当我在浏览器中加载API(nginx-default-backend)时,每3或4次点击刷新后,404就会从api.domain.com投放。

因此,每隔5次左右,我的API域(nginx-default-backendsite.domain.com)会提供来自完全不同的域(234.234.234.234api.domain.com)的页面。我不明白这是怎么发生的。

删除123.123.123.123后,API会再次正常运行。我真的很困惑。

对于API:

nginx-ingress-controller

对于网站:

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 检查了我的DNS记录,它们都是正确的。我使用host -a检查选择器中的名称冲突,没有冲突。我检查了绑定的IP地址:

kubectl get po -l app=website

一切看起来都不错。

我做错了什么或者k8s或nginx-ingress有什么严重错误?

1 个答案:

答案 0 :(得分:0)

这是一个有趣的 我花了一些时间绘制图表并假设错误发生的原因,但最好的答案来自GLBC README

  

不要在单个集群中启动控制器的2个实例   会互相争斗   

修改

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

据我所知,GCE负载均衡器转发规则接受转发到群集主机的同一端口号上的流量,例如示例中的:443

nginx-ingress-controller定义中:

ports:
        - containerPort: 443
          hostPort: 443

我们看到nginx-ingress pod正在:443的主机上收听 但GCE负载均衡器也转发到:443的主机。

全部放在一起

想象一下,您的API pod部署在群集节点的某个子集上,例如3/4 然后3/4倍的GCE负载均衡器将流量引导到具有监听API pod的主机 - 成功!

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

所以这个问题实际上并不像DNS解析那样。

参考

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

  

并非所有云提供商(例如Google)都严格要求这样做   Compute Engine不需要分配NodePort来进行   LoadBalancer工作,但AWS确实如此)

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