我在k8s集群中有一个nginx
部署,它可以代理我的api/
呼叫,如下所示:
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html =404;
}
location /api {
proxy_pass http://backend-dev/api;
}
}
这在大多数情况下都有效,但是有时api
吊舱尚未准备就绪时,nginx会因错误而失败:
nginx: [emerg] host not found in upstream "backend-dev" in /etc/nginx/conf.d/default.conf:12
在浏览互联网几个小时后,我发现article几乎是同一问题。我已经尝试过了:
location /api {
set $upstreamName backend-dev;
proxy_pass http://$upstreamName/api;
}
现在nginx返回 502 。 这:
location /api {
resolver 10.0.0.10 valid=10s;
set $upstreamName backend-dev;
proxy_pass http://$upstreamName/api;
}
Nginx返回 503 。
在k8s上修复它的正确方法是什么?
答案 0 :(得分:2)
如果您的API容器尚未准备好,Nginx将无法将流量路由到它们。
来自Kubernetes documentation:
kubelet使用就绪性探测器来了解何时Container准备开始接受流量。当Pod的所有容器都准备就绪时,即视为准备就绪。此信号的一种用法是控制将哪些Pod用作服务的后端。当Pod尚未就绪时,会将其从服务负载平衡器中删除。
如果您不使用活动或就绪探测器,那么即使您在容器内运行的应用程序尚未完成启动过程并准备接受流量,您的Pod也将被标记为“就绪”。
有关Pod和DNS记录的相关部分,请参见here
由于未为Pod名称创建A记录,因此要创建Pod的A记录需要主机名。没有主机名但带有子域的Pod只会为无头服务创建A记录(default-subdomain.my-namespace.svc.cluster-domain.example),指向Pod的IP地址。另外,除非在服务上设置了publishNotReadyAddresses = True,否则Pod需要准备就绪才能有记录。
更新:我建议使用NGINX作为ingress controller。
将NGINX用作入口控制器时,NGINX服务会成功启动,并且每部署ingress rule时,NGINX的配置便是reloaded on the fly。
这将帮助您避免NGINX Pod重新启动。