<p>The backend endpoint works using k8s-client to watch POD logs with the following code.</p>
<pre><code>    @RequestMapping(value = &quot;/{podName}/log&quot;, method = RequestMethod.GET)
    public void queryLog(HttpServletResponse response, @PathVariable(name = &quot;podName&quot;, required = true) String podName,
                         @RequestParam(name = &quot;container&quot;, required = true) String container,
                         @RequestParam(name = &quot;tailLines&quot;, required = false) Integer tailLines,
                         @RequestParam(name = &quot;timestamps&quot;, required = false) boolean timestamps,
                         @RequestParam(name = &quot;follow&quot;, required = false) boolean follow) {
        try {
            PodLogs logs = new PodLogs();
            InputStream is = logs.streamNamespacedPodLog(namespace, podName, container, null, tailLines, timestamps, follow);
            copy(is, response.getOutputStream());

        } catch (Exception ex) {
            logger.error(&quot;exception&quot;, ex);
        }
    }

    public static void copy(InputStream in, OutputStream out) throws IOException {

        try {
            byte[] buffer = new byte[4096];
            int bytesRead;
            while ((bytesRead = in.read(buffer)) != -1) {
                String str = new String(buffer, 0, bytesRead);
                out.write(buffer, 0, bytesRead);
                out.flush();
            }
        } catch (IOException ex) {
            ex.printStackTrace();
        } finally {
            if (in != null) {
                in.close();
            }
            if (out != null) {
                out.close();
            }
        }

    }
</code></pre>
<p>The front:</p>
<pre><code>&lt;html&gt;
    &lt;head&gt;
        &lt;title&gt;Test&lt;/title&gt;
        &lt;script type=&quot;text/javascript&quot;&gt;
        
        var xhr = null;
        
         function setConnected(connected) {
                
                document.getElementById('connect').disabled = connected;
                document.getElementById('disconnect').disabled = !connected;
                document.getElementById('response').innerHTML = '';
            }
          
         function connect() {
        
          xhr = new XMLHttpRequest()

          xhr.open('GET', `http://proxy.k8s.io/backend/api/pod-0/log?container=pod&amp;tailLines=500&amp;timestamps=true&amp;follow=true`, true)

          xhr.onreadystatechange = () =&gt; {
            setConnected(true);
            if (xhr.readyState &gt;= 3 &amp;&amp; xhr.status === 200) {
               console.log(&quot;###&quot;)
               console.log(xhr.responseText)
               document.getElementById('response').innerHTML = document.getElementById('response').innerHTML + xhr.responseText;
            }
          }

          xhr.send()
        }
         function disconnect() {
                
                if(xhr != null) {
                    xhr.abort();
                }
                
                setConnected(false);
                console.log(&quot;Disconnected&quot;);
            }
        &lt;/script&gt;
        
    &lt;/head&gt;
    
    &lt;body  onload=&quot;disconnect()&quot;&gt;
     &lt;div&gt;
        &lt;button id=&quot;connect&quot; onclick=&quot;connect();&quot;&gt;Connect&lt;/button&gt;
        &lt;button id=&quot;disconnect&quot; disabled=&quot;disabled&quot; onclick=&quot;disconnect();&quot;&gt;Disconnect&lt;/button&gt;
        &lt;/div&gt;
    &lt;div id=&quot;response&quot;&gt;&lt;/div&gt;
    &lt;/body&gt;
&lt;/html&gt;
</code></pre>
<p>I could get the full log and watched new generated log <strong>without nginx</strong>.
However nginx with the following config can't get the full log from backend.</p>
<pre><code>upstream backend {
        server backend:8080;
        keepalive_timeout 60s;
        keepalive 60;
        keepalive_requests 100;
}

server {
    listen       80;

    location / {
        root   /usr/share/nginx/html;
        index  index.html index.htm;
    }

    location /backend/api/ {
        proxy_pass http://backend/;
    }
}
</code></pre>
<p>The expected log sample:</p>
<pre><code>2021-08-02T02:51:04.857054753Z  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2021-08-02T02:51:04.857057468Z  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2021-08-02T02:51:04.857060467Z  at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
2021-08-02T02:51:04.857063232Z  at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
</code></pre>
<p>The sample log I got:</p>
<pre><code>2021-08-02T02:51:04.857054753Z  at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
2021-08-02T02:51:04.857057468Z  at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
2021-08-02T02:51:04.857060467Z  at org.springframework.web.filter.HiddenHt
</code></pre>
<p>It looks like that the last chunked data was lost.
When I accessed it with <code>tailLines=200</code>, some data still was lost. And when new logs were generated, no new data could display in the front page.</p>

niaomingjian
<p>The root cause is the incorrect <a href="http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_http_version" rel="nofollow noreferrer">proxy_http_version</a>.
By default, the version 1.0 is used. Version 1.1 should be used for the keepalive connection.</p>
<p>Docs say:</p>
<blockquote>
<p>Syntax:   proxy_http_version 1.0 | 1.1;<br />
Default:<br />
proxy_http_version 1.0;<br />
Context:    http, server, location<br />
This directive appeared in version 1.1.4.</p>
</blockquote>
<p>Sets the HTTP protocol version for proxying. <strong>By default, version 1.0</strong> is used. <strong>Version 1.1 is recommended for use with keepalive connections</strong> and NTLM authentication.</p>
<p>How to fix:<br />
Add <code>proxy_http_version    1.1;</code> under location block.</p>
<pre><code>    location /backend/api/ {
        proxy_http_version    1.1;
        proxy_pass http://backend/;
    }
</code></pre>
