2

nginx在 k8s 集群中有一个部署,它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;
  }
}

这在大多数情况下都有效,但是有时当apipod 未准备好时,nginx 会失败并出现错误:

nginx: [emerg] host not found in upstream "backend-dev" in /etc/nginx/conf.d/default.conf:12

经过几个小时的互联网探索,我发现了几乎相同问题的文章。我试过这个:

  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 上修复它的正确方法是什么?

4

1 回答 1

2

如果您的 API pod 尚未准备好,Nginx 将无法将流量路由到它们。

来自 Kubernetes文档

kubelet 使用就绪探测来了解容器何时准备好开始接受流量。当 Pod 的所有 Container 都准备好时,就认为 Pod 准备好了。此信号的一种用途是控制哪些 Pod 用作服务的后端。当 Pod 未准备好时,它会从服务负载均衡器中移除。

如果您没有使用 liveness 或 readiness 探针,那么即使您在容器内运行的应用程序尚未完成启动过程并准备好接受流量,您的 pod 也会被标记为“就绪”。

可以在此处找到有关 Pod 和 DNS 记录的相关部分

因为没有为 Pod 名称创建 A 记录,所以要创建 Pod 的 A 记录需要 hostname。没有主机名但有子域的 Pod 只会为无头服务创建 A 记录(default-subdomain.my-namespace.svc.cluster-domain.example),指向 Pod 的 IP 地址。此外,除非在 Service 上设置了 publishNotReadyAddresses=True,否则 Pod 需要准备好才能有记录。

更新:我建议使用 NGINX 作为入口控制器

当您使用 NGINX 作为入口控制器时,NGINX 服务会成功启动,并且每当部署入口规则时,NGINX 配置都会即时重新加载

这将帮助您避免 NGINX pod 重启。

于 2019-07-17T20:54:15.907 回答