<p>Summary:</p>
<p>I have a docker container which is running kubectl port-forward, forwarding the port (5432) of a postgres service running as a k8s service to a local port (2223).
In the Dockerfile, I have exposed the relevant port 2223. Then I ran the container by publishing the said port (<code>-p 2223:2223</code>)</p>
<p>Now when I am trying to access the postgres through <code>psql -h localhost -p 2223</code>, I am getting the following error:</p>
<pre><code>psql: server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
</code></pre>
<p>However, when I do <code>docker exec -ti</code> to the said container and run the above psql command, I am able to connect to postgres.</p>
<p>Dockerfile CMD:</p>
<pre><code>EXPOSE 2223
CMD [&quot;bash&quot;, &quot;-c&quot;, &quot;kubectl -n namespace_test port-forward service/postgres-11-2 2223:5432&quot;]
</code></pre>
<p>Docker Run command:</p>
<pre><code>docker run -it --name=k8s-conn-12 -p 2223:2223 my_image_name:latest
</code></pre>
<p>Output of the docker run command:</p>
<pre><code>Forwarding from 127.0.0.1:2223 -&gt; 5432
</code></pre>
<p>So the port forwarding is successful, and I am able to connect to the postgres instance from inside the docker container. What I am not able to do is to connect from outside the container with the exposed and published port</p>

Chayan Ghosh
<p>You are missing a following parameter with your <code>$ kubectl port-forward ...</code>:</p>
<ul>
<li><code>--address 0.0.0.0</code></li>
</ul>
<p>I've reproduced the setup that you've tried to achieve and this was the reason the connection wasn't possible. I've included more explanation below.</p>
<hr />
<h3>Explanation</h3>
<ul>
<li><code>$ kubectl port-forward --help</code></li>
</ul>
<blockquote>
<p>Listen on port 8888 on all addresses, forwarding to 5000 in the pod</p>
<p><code>kubectl port-forward --address 0.0.0.0 pod/mypod 8888:5000</code></p>
<hr />
<h3>Options:</h3>
<p><code>--address=[localhost]</code>: Addresses to listen on (comma separated). Only accepts IP addresses or
localhost as a value. When localhost is supplied, kubectl will try to bind on both 127.0.0.1 and ::1
and will fail if neither of these addresses are available to bind.</p>
</blockquote>
<p>By default: <code>$ kubectl port-forward</code> will bind to the <code>localhost</code> i.e. <code>127.0.0.1</code>. <strong>In this setup the <code>localhost</code> will be the internal to the container</strong> and will not be accessible from your host even with the <code>--publish</code> (<code>-p</code>) parameter.</p>
<p>To allow the connections that are not originating from <code>localhost</code> you will need to pass earlier mentioned: <code>--address 0.0.0.0</code>. This will make <code>kubectl</code> listen on all IP addresses and respond to the traffic accordingly.</p>
<p>Your <code>Dockerfile</code> <code>CMD</code> should look similar to:</p>
<pre><code>CMD [&quot;bash&quot;, &quot;-c&quot;, &quot;kubectl -n namespace_test port-forward --address 0.0.0.0 service/postgres-11-2 2223:5432&quot;]
</code></pre>
<hr />
<p>Additional reference:</p>
<ul>
<li><em><a href="https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands" rel="nofollow noreferrer">Kubernetes.io: Docs: Reference: Generated: Kubectl commands</a></em></li>
</ul>
