<p>How to change the default nodeport range on Mac (docker-desktop)?</p>

<p>I'd like to change the default nodeport range on Mac. Is it possible? I'm glad to have found this article: <code>http://www.thinkcode.se/blog/2019/02/20/kubernetes-service-node-port-range</code>. Since I can't find <code>/etc/kubernetes/manifests/kube-apiserver.yaml</code> in my environment, I tried to achieve what I want to do by running <code>sudo kubectl edit pod kube-apiserver-docker-desktop --namespace=kube-system</code> and add the parameter <code>--service-node-port-range=443-22000</code>. But when I tried to save it, I got the following error:</p>

<pre><code># pods "kube-apiserver-docker-desktop" was not valid:
# * spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations` (only additions to existing tolerations)
</code></pre>

<p>(I get the same error even if I don't touch port 443.) Can someone please share his/her thoughts or experience? Thanks!</p>

<p>Append:</p>

<pre><code>skwok-mbp:kubernetes skwok$ kubectl get deployment -A
NAMESPACE       NAME                       READY   UP-TO-DATE   AVAILABLE   AGE
docker          compose                    1/1     1            1           15d
docker          compose-api                1/1     1            1           15d
ingress-nginx   nginx-ingress-controller   1/1     1            1           37m
kube-system     coredns                    2/2     2            2           15d
skwok-mbp:kubernetes skwok$ kubectl get pod -A
NAMESPACE       NAME                                        READY   STATUS    RESTARTS   AGE
default         fortune-configmap-volume                    2/2     Running   4          14d
default         kubia-2qzmm                                 1/1     Running   2          15d
docker          compose-6c67d745f6-qqmpb                    1/1     Running   2          15d
docker          compose-api-57ff65b8c7-g8884                1/1     Running   4          15d
ingress-nginx   nginx-ingress-controller-756f65dd87-sq6lt   1/1     Running   0          37m
kube-system     coredns-fb8b8dccf-jn8cm                     1/1     Running   6          15d
kube-system     coredns-fb8b8dccf-t6qhs                     1/1     Running   6          15d
kube-system     etcd-docker-desktop                         1/1     Running   2          15d
kube-system     kube-apiserver-docker-desktop               1/1     Running   2          15d
kube-system     kube-controller-manager-docker-desktop      1/1     Running   29         15d
kube-system     kube-proxy-6nzqx                            1/1     Running   2          15d
kube-system     kube-scheduler-docker-desktop               1/1     Running   30         15d
</code></pre>

<p><strong>Update</strong>: The <a href="https://minikube.sigs.k8s.io/docs/handbook/accessing/#increasing-the-nodeport-range" rel="nofollow noreferrer">example</a> from the documentation shows a way to adjust apiserver parameters during Minikube start:</p>
<pre><code>minikube start --extra-config=apiserver.service-node-port-range=1-65535
</code></pre>
<p><strong>--extra-config</strong>: A set of <code>key=value</code> pairs that describe configuration that may be passed to different components. The key should be '.' separated, and the first part before the dot is the component to apply the configuration to. Valid components are: <code>kubelet</code>, <code>apiserver</code>, <code>controller-manager</code>, <code>etcd</code>, <code>proxy</code>, <code>scheduler</code>. <a href="https://github.com/kubernetes/minikube/blob/8611a455cab8bce3cf218c8c276a97ebaa730c3c/docs/minikube_start.md" rel="nofollow noreferrer"><sup>link</sup></a></p>
<p>The list of available options could be found in <a href="https://kubernetes.io/docs/reference/command-line-tools-reference/" rel="nofollow noreferrer">CLI documentation</a></p>
<hr />
<p>Another way to change <code>kube-apiserver</code> parameters for Docker-for-desktop on Mac:</p>
<ol>
<li><p>login to Docker VM:</p>
<pre><code> $ screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty

 #(you can also use privileged container for the same purpose)
 docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
 #or
 docker run --rm -it --privileged --pid=host walkerlee/nsenter -t 1 -m -u -i -n sh
 # as suggested here: https://forums.docker.com/t/is-it-possible-to-ssh-to-the-xhyve-machine/17426/5
 # in case of minikube use the following command:
 $ minikube ssh
</code></pre>
</li>
<li><p>Edit kube-apiserver.yaml (it's one of static pods, they are created by kubelet using files in /etc/kubernetes/manifests)</p>
<pre><code> $ vi /etc/kubernetes/manifests/kube-apiserver.yaml
 # for minikube 
 $ sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
</code></pre>
</li>
<li><p>Add the following line to the pod spec:</p>
<pre><code> spec:
   containers:
   - command:
     - kube-apiserver
     - --advertise-address=192.168.65.3
     ...
     - --service-node-port-range=443-22000   # &lt;-- add this line
     ...
</code></pre>
</li>
<li><p>Save and exit. Pod kube-apiserver will be restarted with new parameters.</p>
</li>
<li><p>Exit Docker VM (for <code>screen</code>: <code>Ctrl-a,k</code> , for container: <code>Ctrl-d</code> )</p>
</li>
</ol>
<p>Check the results:</p>
<pre><code>$ kubectl get pod kube-apiserver-docker-desktop -o yaml -n kube-system | less
</code></pre>
<p>Create simple deployment and expose it with service:</p>
<pre><code>$ kubectl run nginx1 --image=nginx --replicas=2
$ kubectl expose deployment nginx1 --port 80 --type=NodePort
$ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       &lt;none&gt;        443/TCP        14d
nginx1       NodePort    10.99.173.234   &lt;none&gt;        80:14966/TCP   5s
</code></pre>
<p>As you can see NodePort was chosen from the new range.</p>
<p>There are other <a href="https://stackoverflow.com/a/54345488/9521610">ways</a> to expose your container: <a href="http://alesnosek.com/blog/2017/02/14/accessing-kubernetes-pods-from-outside-of-the-cluster/" rel="nofollow noreferrer">HostNetwork, HostPort</a>, <a href="https://metallb.universe.tf" rel="nofollow noreferrer">MetalLB</a></p>
<p>You need to add the correct <a href="https://kubernetes.io/docs/tasks/configure-pod-container/security-context/" rel="nofollow noreferrer">security context</a> for that purpose, check out how the ingress addon in minikube works, for example.</p>
<pre><code>...
ports:
- containerPort: 80
  hostPort: 80
  protocol: TCP
- containerPort: 443
  hostPort: 443
  protocol: TCP
...
securityContext:
  capabilities:
    add:
    - NET_BIND_SERVICE
    drop:
    - ALL
</code></pre>
