How to change the default nodeport range on Mac (docker-desktop)?

8/21/2019

How to change the default nodeport range on Mac (docker-desktop)?

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

# 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)

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

Append:

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
-- skwokie
kubernetes

1 Answer

8/21/2019

The correct way to change kube-apiserver parameters for Docker-for-desktop on Mac:

  1. login to Docker VM:

    $ 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
    
  2. Edit kube-apiserver.yaml (it's one of static pods, they are created by kubelet using files in /etc/kubernetes/manifests)

    $ vi /etc/kubernetes/manifests/kube-apiserver.yaml
    # for minikube 
    $ sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
  3. Add the following line to the pod spec:

    spec:
      containers:
      - command:
        - kube-apiserver
        - --advertise-address=192.168.65.3
        ...
        - --service-node-port-range=443-22000   # <-- add this line
        ...
  4. Save and exit. Pod kube-apiserver will be restarted with new parameters.

  5. Exit Docker VM (for screen: Ctrl-a,k , for container: Ctrl-d )

Check the results:

$ kubectl get pod kube-apiserver-docker-desktop -o yaml -n kube-system | less

Create simple deployment and expose it with service:

$ 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       <none>        443/TCP        14d
nginx1       NodePort    10.99.173.234   <none>        80:14966/TCP   5s

As you can see NodePort was chosen from the new range.

There are other ways to expose your container: HostNetwork, HostPort, MetalLB

You need to add the correct security context for that purpose, check out how the ingress addon in minikube works, for example.

...
ports:
- containerPort: 80
  hostPort: 80
  protocol: TCP
- containerPort: 443
  hostPort: 443
  protocol: TCP
...
securityContext:
  capabilities:
    add:
    - NET_BIND_SERVICE
    drop:
    - ALL
-- VAS
Source: StackOverflow