kubernetes / ingress-nginx

Ingress NGINX Controller for Kubernetes
https://kubernetes.github.io/ingress-nginx/
Apache License 2.0
17.53k stars 8.26k forks source link

Annotations for proxy-send-timeout not honored in upstream connection #10987

Open jurrehart opened 9 months ago

jurrehart commented 9 months ago

What happened:

Having web application that will close incomming connections after 5 seconds idle , without the possibility to change this setting in the app.

We set the following annotations on the ingress

nginx.ingress.kubernetes.io/proxy-send-timeout: "4"

But upstream connections to the pod are still kept open by nginx even after more than 4s have passed between write or read operations on the upstream connection. thus resulting in errors being logged and 502 in access logs

Error log:

recv() failed (104: Connection reset by peer) while reading response header from upstream, 

What you expected to happen: Having configured the annotations to close connections with no write or read operations for more than the set time I'd expect the upstream connection to be closed when that time is exceeded.

What do you think went wrong? In the upstream_balancer upstream block there's a keepalive-timeout 60s; thus instructing the upstream module to keep idle connections to the upstream server open for 60s.

While the annotations generate the configurations in the server block for the ingress they are only applied to the proxy_pass http://upstream_balancer; thus having no impact on the upstream connections.

NGINX Ingress controller version :

-------------------------------------------------------------------------------
NGINX Ingress controller
  Release:       v1.8.1
  Build:         dc88dce9ea5e700f3301d16f971fa17c6cfe757d
  Repository:    https://github.com/kubernetes/ingress-nginx
  nginx version: nginx/1.21.6

-------------------------------------------------------------------------------

also noticed same behavior on an EKS setup on which I have no admin access , but seems running v 1.5.1

Kubernetes version (use kubectl version):

Client Version: v1.28.2
Kustomize Version: v5.0.4-0.20230601165947-6ce0bf390ce3
Server Version: v1.27.2

Environment:


**How to reproduce this issue**:
- Create application single replica  with nginx ingress set annotations

nginx.ingress.kubernetes.io/proxy-send-timeout: "4"



- Run tcpdump on the application pod listening for HTTP traffic comming from ingress controller

- Make HTTP request  tot he applciation with interval >4s 

- Observe nginx open a connection to the pod and reuse that same connection even after more than 4s of no traffic on said connection.

**Anything else we need to know**:

While the above information is for a locally installed cluster I've obeserved same behaviour on EKS  running Kubernetes `v1.25.15-eks-e71965b` and nginx ingress-controller `registry.k8s.io/ingress-nginx/controller-chroot:v1.5.1` where I have no administraive access to the cluster or nginx-controller namespace

<!-- 
/kind documentation
/remove-kind bug
-->
k8s-ci-robot commented 9 months ago

This issue is currently awaiting triage.

If Ingress contributors determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md). If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
longwuyuan commented 9 months ago

/remove-kind bug

image

longwuyuan commented 9 months ago
longwuyuan commented 9 months ago

image

jurrehart commented 9 months ago

Beware that the issue is not regarding POD responding slow. So any test with httpbun and it's delay endpoint will not be a verification of the issue. The problem faced is that the POD will close incomming connections once they have been idle for 5 seconds. So the requirement is that the NGINX controller must close it's upstream connections to the POD when they have been idle for 5s or less.

The only way I currenlty found to have NGINX behave that way is to set the global

upstream-keepalive-timeout:  "4"

This will indeed have NGINX close it's upstream connections after 4 seconds of being idle. But by doing so I'm impacting all ingresses on the NGINX and that's not desired.

Now the documentation for annotations on the ingress regarding he various proxy-xxx-timeout states

Using the configuration configmap it is possible to set the default global timeout for connections to the upstream servers. In some scenarios is required to have different values. To allow this we provide annotations that allows this customization:

Reading the relative NGINX documention for the proxy_send_timeout the paramter set by the proxy-send-timeout annotation.

Sets a timeout for transmitting a request to the proxied server. The timeout is set only between two successive write operations, not for the transmission of the whole request. If the proxied server does not receive anything within this time, the connection is closed.

One would expect to see NGINX close the connection to the upstream once Nginx has not send any data on the upstream connection for the configured amount off time.

However if you obeserve the connetions to the upstream with tcpdump you'll see that NGINX will reuse any open connection that has not been idle for more than 60s (default value) or the value of configured upstream-keepalive-timeout.

longwuyuan commented 9 months ago

I agree with you.

longwuyuan commented 9 months ago

I am unable to figure out how to create a delay with the vanilla httpd:alpine image (or nginx:alpine image for that matter)

github-actions[bot] commented 8 months ago

This is stale, but we won't close it automatically, just bare in mind the maintainers may be busy with other tasks and will reach your issue ASAP. If you have any question or request to prioritize this, please reach #ingress-nginx-dev on Kubernetes Slack.