<p>I'm doing some tutorials using k3d (k3s in docker) and my yml looks like this:</p>
<pre><code>apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
          - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - name: http
    port: 80
    targetPort: 80
</code></pre>
<p>With the resulting node port being 31747:</p>
<pre><code>:~$ kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.43.0.1       &lt;none&gt;        443/TCP        18m
nginx        NodePort    10.43.254.138   &lt;none&gt;        80:31747/TCP   17m

:~$ kubectl get endpoints
NAME         ENDPOINTS         AGE
kubernetes   172.18.0.2:6443   22m
nginx        10.42.0.8:80      21m
</code></pre>
<p>However wget does not work:</p>
<pre><code>:~$ wget localhost:31747
Connecting to localhost:31747 ([::1]:31747)
wget: can't connect to remote host: Connection refused
:~$
</code></pre>
<p>What have I missed? I've ensured that my labels all say <code>app: nginx</code> and my <code>containerPort</code>, <code>port</code> and <code>targetPort</code> are all 80</p>

A G
<p>The question is, is the NodePort range mapped from the host to the docker container acting as the node. The command <code>docker ps</code> will show you, for more details you can <code>docker inspect $container_id</code> and look at the <code>Ports</code> attribute under <code>NetworkSettings</code>. I don't have k3d around, but here is an example from kind.</p>
<pre><code>$ docker ps
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                       NAMES
1d2225b83a73        kindest/node:v1.17.0          &quot;/usr/local/bin/entr…&quot;   18 hours ago        Up 18 hours         127.0.0.1:32769-&gt;6443/tcp   kind-control-plane
</code></pre>
<pre><code>$ docker inspect kind-control-plane
[
    {
        # [...]
        &quot;NetworkSettings&quot;: {
            # [...]
            &quot;Ports&quot;: {
                &quot;6443/tcp&quot;: [
                    {
                        &quot;HostIp&quot;: &quot;127.0.0.1&quot;,
                        &quot;HostPort&quot;: &quot;32769&quot;
                    }
                ]
            },
        # [...]
    }
]
</code></pre>
<p>If it is not, working with <code>kubectl port-forward</code> as suggested in the comment is probably the easiest approach. Alternatively, start looking into Ingress. Ingress is the preferred method to expose workloads outside of a cluster, and in the case of kind, <a href="https://kind.sigs.k8s.io/docs/user/ingress/" rel="noreferrer">they have support</a> for Ingress. It seems k3d also has a way to <a href="https://k3d.io/usage/guides/exposing_services/" rel="noreferrer">map the ingress port to the host</a>.</p>
