<p>I'm using the <a href="https://docs.docker.com/docker-for-mac/kubernetes/" rel="nofollow noreferrer">kubernetes cluster built in to Docker Desktop</a> to develop my application.</p>

<p>I would like to expose services inside the cluster as ports on <code>localhost</code>.</p>

<p>I can do so using <code>kubectl expose deployment foobar --type=NodePort --port=30088</code>, which creates a service like this:</p>

<pre><code>apiVersion: v1
kind: Service
metadata:
  labels:
    role: web
  name: foobar
spec:
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 30088
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    role: web
  type: NodePort
</code></pre>

<p>But it only works for very high numbered ports.  If I try something lower I get:</p>

<pre><code>The Service "kafka-external" is invalid: spec.ports[0].nodePort: Invalid value: 9092: provided port is not in the valid range. The range of valid ports is 30000-32767
</code></pre>

<p>It seems there is a kubernetes apiserver setting called <code>ServiceNodePortRange</code> which would allow me to override this restriction, but I can't figure out how to set it on Docker's builtin cluster.</p>

<p>So my question is: how do I expose a specific, low-numbered port (like 9092) on Docker's kubernetes cluster?   Is there a way to override that setting?   Or a better way to expose the service than <code>NodePort</code>?</p>

Lawrence D'Anna
<p><code>NodePort</code> is intended to be a building block for load-balancers or other<br>
ingress modes. This means it didn't matter which port you got as long as<br>
you got one. This makes it a little clunky to use directly - you can't<br>
have just any port. You can change the port range, but you run the risk of<br>
conflicts with real things running on your nodes and with any pod HostPorts.</p>

<p>The default range is indeed 30000-32767 but it can be changed by setting the <code>--service-node-port-range</code> Update the file <code>/etc/kubernetes/manifests/kube-apiserver.yaml</code> and add the line <code>--service-node-port-range=xxxxx-yyyyy</code>.</p>

<p>In the Kubernetes cluster there is a  <code>kube-apiserver.yaml</code> file which is in the directory - <code>/etc/kubernetes/manifests/kube-apiserver.yaml</code> but not on the kube-apiserver container/pod but on the master itself.</p>

<ol>
<li><p>Login to Docker VM:</p></li>
<li><p>Add the following line to the pod spec:</p>

<pre><code>spec:
  containers:
  - command:
    - kube-apiserver
    ...
    - --service-node-port-range=xxxxx-yyyyy  # &lt;-- add this line
    ...

</code></pre></li>
</ol>

<p>Save and exit. Pod kube-apiserver will be restarted with new parameters.</p>

<ol start="3">
<li><p>Exit Docker VM (for  <code>screen</code>:  <code>Ctrl-a,k</code>  , for container:  <code>Ctrl-d</code>  )</p></li>
<li><p>Check the results:</p></li>
</ol>

<pre><code>$ kubectl get pod kube-apiserver-docker-desktop -o yaml -n kube-system | less
</code></pre>

<p>Take a look: <a href="https://github.com/kubernetes/kubernetes/blob/59876df736c41093363f4c198aeec05e29c9c902/cmd/kube-apiserver/app/server.go#L197" rel="nofollow noreferrer">service-pod-range</a>,  <a href="https://github.com/kubernetes/minikube/issues/1359" rel="nofollow noreferrer">changing pod range</a>, <a href="https://stackoverflow.com/questions/57582980/how-to-change-the-default-nodeport-range-on-mac-docker-desktop">changing-nodeport-range</a>.</p>
