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-backend
,site.domain.com
)会提供来自完全不同的域(234.234.234.234
,api.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有什么严重错误?
答案 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确实如此)