1

I've read a dozen of articles about how to set up Docker CLI with Minikube (or the other way around, depending on how you look at it) on Windows.

The idea came while watching this YouTube video: DevOps Toolkit - Free Docker Desktop Alternative For Mac And Windows

What have I done so far, well, first off I've set up the necessary packages:

Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V-All
choco install docker-cli minikube k9s -y
...

Then started Minikube:

$ minikube start
  minikube v1.25.1 on Microsoft Windows 11 Pro 10.0.22000 Build 22000
✨  Automatically selected the hyperv driver
  Starting control plane node minikube in cluster minikube
  Creating hyperv VM (CPUs=2, Memory=6000MB, Disk=20000MB) ...
  Preparing Kubernetes v1.23.1 on Docker 20.10.12 ...
    ▪ kubelet.housekeeping-interval=5m
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
  Enabled addons: storage-provisioner, default-storageclass
  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

and displayed the env variables to use minikube's Docker daemon, i.e. pipe docker to minikube

$ minikube docker-env
$Env:DOCKER_TLS_VERIFY = "1"
$Env:DOCKER_HOST = "tcp://172.22.43.208:2376"
$Env:DOCKER_CERT_PATH = "C:\Users\natalie-perret\.minikube\certs"
$Env:MINIKUBE_ACTIVE_DOCKERD = "minikube"
# To point your shell to minikube's docker-daemon, run:
# & minikube -p minikube docker-env --shell powershell | Invoke-Expression

which I've executed promptly:

$ & minikube -p minikube docker-env --shell powershell | Invoke-Expression

and I could see the kube containers with the Docker CLI:

$ docker container ls
CONTAINER ID   IMAGE                           COMMAND                  CREATED          STATUS          PORTS                                                      NAMES
5fffd86809db   6e38f40d628d                    "/storage-provisioner"   41 minutes ago   Up 41 minutes                                                              k8s_storage-provisioner_storage-provisioner_kube-system_ad473bd3-57aa-448d-87d4-26f7786d5321_1
e939d8c637de   a4ca41631cc7                    "/coredns -conf /etc…"   42 minutes ago   Up 42 minutes                                                              k8s_coredns_coredns-64897985d-z9k9m_kube-system_64e26de3-b379-49db-800e-6041f6f5b384_0
1866d17e5126   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_coredns-64897985d-z9k9m_kube-system_64e26de3-b379-49db-800e-6041f6f5b384_0
1e7f8815c7d9   b46c42588d51                    "/usr/local/bin/kube…"   42 minutes ago   Up 42 minutes                                                              k8s_kube-proxy_kube-proxy-qbjd8_kube-system_6a1016cc-7272-404e-8528-582615333943_0
81ea804ae46e   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_kube-proxy-qbjd8_kube-system_6a1016cc-7272-404e-8528-582615333943_0
160dd07d4e57   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_storage-provisioner_kube-system_ad473bd3-57aa-448d-87d4-26f7786d5321_0
37d7f248a31c   71d575efe628                    "kube-scheduler --au…"   42 minutes ago   Up 42 minutes                                                              k8s_kube-scheduler_kube-scheduler-minikube_kube-system_b8bdc344ff0000e961009344b94de59c_0
06b7d0007a1b   25f8c7f3da61                    "etcd --advertise-cl…"   42 minutes ago   Up 42 minutes                                                              k8s_etcd_etcd-minikube_kube-system_a9ff16e4ba59eb7890b7fb3e6b59a60b_0
9aca0a09e443   b6d7abedde39                    "kube-apiserver --ad…"   42 minutes ago   Up 42 minutes                                                              k8s_kube-apiserver_kube-apiserver-minikube_kube-system_86c1ec74f5feb61f5b7f86812aea2e10_0
0898146be8d2   f51846a4fd28                    "kube-controller-man…"   42 minutes ago   Up 42 minutes                                                              k8s_kube-controller-manager_kube-controller-manager-minikube_kube-system_d3f0dbc1c3a23fddbc9f30b9e08c775e_0
c9daa18706bd   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_kube-scheduler-minikube_kube-system_b8bdc344ff0000e961009344b94de59c_0
fe9808d7fc2e   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_kube-controller-manager-minikube_kube-system_d3f0dbc1c3a23fddbc9f30b9e08c775e_0
852aa124d436   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_kube-apiserver-minikube_kube-system_86c1ec74f5feb61f5b7f86812aea2e10_0
bd884e37ea62   k8s.gcr.io/pause:3.6            "/pause"                 42 minutes ago   Up 42 minutes                                                              k8s_POD_etcd-minikube_kube-system_a9ff16e4ba59eb7890b7fb3e6b59a60b_0

So far so good, but is it? Well there are two things I'm still very much struggling with (and that are both indicated pretty explicitly in the title):

  1. I still have port mapping issue, and I couldn't really figure out how to do this, based on my superficial understanding, the minikube has its "own ip address". I mean displaying the Minikube help, shows among other things:

    Troubleshooting Commands:
    ssh-key        Retrieve the ssh identity key path of the specified node
    ssh-host       Retrieve the ssh host key of the specified node
    ip             Retrieves the IP address of the specified node
    logs           Returns logs to debug a local Kubernetes cluster
    update-check   Print current and latest version number
    version        Print the version of minikube
    options        Show a list of global command-line options (applies to all commands).
    
    $ minikube ip
    172.22.42.203
    

    However, I would like to the minikube ip to point to the localhost instead, not sure whether this is doable.

    A simple use case with nginx:

    $ docker run -it --rm -d -p 8080:80 --name web nginx
    Unable to find image 'nginx:latest' locally
    latest: Pulling from library/nginx
    5eb5b503b376: Pull complete
    1ae07ab881bd: Pull complete
    78091884b7be: Pull complete
    091c283c6a66: Pull complete
    55de5851019b: Pull complete
    b559bad762be: Pull complete
    Digest: sha256:2834dc507516af02784808c5f48b7cbe38b8ed5d0f4837f16e78d00deb7e7767
    Status: Downloaded newer image for nginx:latest
    9f00b9c8ab74436bdf1525c6255cab2aab86fe47163d2ed304c8e65dd98b0b4a
    

    which inevitably leads to this not working

    $ [System.Net.WebRequest]::Create('http://127.0.0.1:8080').GetResponse() | % {$_.StatusCode}
    MethodInvocationException: Exception calling "GetResponse" with "0" argument(s): "No connection could be made because the target machine actively refused it. [::ffff:127.0.0.1]:8080(127.0.0.1:8080)"
    

    while that command obviously does:

    [System.Net.WebRequest]::Create('http://172.22.42.203:8080').GetResponse() | % {$_.StatusCode}
    OK
    
  2. How to make & minikube -p minikube docker-env --shell powershell | Invoke-Expression applied at startup and for every command line prompts? If I don't apply the command in every PowerShell prompt I end up with:

    error during connect: In the default daemon configuration on Windows, the docker client must be run with elevated privileges to connect.: Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/containers/json": open //./pipe/docker_engine: The system cannot find the file specified.
    
Natalie Perret
  • 365
  • 2
  • 3
  • 11
  • 1
    With WSL2 this is doable, otherwise it isn’t. Do you _really_ need it? // Keep in mind that localhost networking is special. – Daniel B Feb 27 '22 at 10:22
  • @DanielB, thanks for your comment, may I ask, what is doable? (as my questions was two-folded) – Natalie Perret Feb 27 '22 at 10:24
  • 1
    Having Docker port bindings on localhost. WSL 2 supports this out of the box, for all network applications. // Docker Desktop is yet another alternative—perhaps. It depends on your actual requirements. – Daniel B Feb 27 '22 at 11:11
  • Gotcha. Well the whole thing about bothering myself going down the Minikube hole was among other things, to not pay for a Docker Desktop license. Another option on the table, albeit not exactly 100% Docker-CLI compliant was to use podman but it also required to use WSL2). Do you know if the second point is achievable, tho? Aka `& minikube -p minikube docker-env --shell powershell | Invoke-Expression` at startup for every PowerShell prompt? – Natalie Perret Feb 27 '22 at 11:49

1 Answers1

1

localhost networking is special. It is trusted. That also means that you cannot easily bring remote ports to localhost. (A VM is considered remote.) It’s still possible of course, on a case-by-case basis, using userspace tools or maybe via netsh portproxy. Minikube does not offer support for this.

WSL 2 comes with localhost binding built-in. So maybe give it a try. Setup is a little involved, but after that, it works basically the same as Minikube here. WSL 2 is also what Docker Desktop now uses to actually run the Docker daemon.

No matter what, to use the Docker CLI on Windows, it needs some configuration. That’s what minikube -p minikube docker-env --shell powershell prints. To run code when starting PowerShell, use profiles. Very similar to how they work with Linux shells, you put the code in a file in a specific location and that’s it. For your use case, I recommend putting the code in the “current user, all hosts” profile. To get its path, use $PROFILE.CurrentUserAllHosts in PowerShell. It differs between PowerShell and PowerShell Core.

Daniel B
  • 60,360
  • 9
  • 122
  • 163
  • Gee, I'm really dumb, I should have really thought about the PowerShell profiles (which despite tweaking mine for the past month didn't really hit me wee brain), thanks for pointing this out. – Natalie Perret Feb 27 '22 at 13:26
  • Thanks for your answer and comments! – Natalie Perret Feb 27 '22 at 13:26
  • One last thing, is there any way to specify a particular ip for the default node `minikube`? Been thru the whole `start` flag documentation https://minikube.sigs.k8s.io/docs/commands/start/ but `--mount-ip` doesn't seem to address that usecase – Natalie Perret Feb 27 '22 at 16:26
  • 1
    The Hyper-V Default Switch (which offers NAT connectivity) does not have persistent IP addresses, sorry. If you are exclusively connected using Ethernet, maybe create a bridged Virtual Switch and use `--hyperv-use-external-switch`. This will expose your minikube VM on the physical network where you might have persistent IP addresses. – Daniel B Feb 27 '22 at 16:39
  • I see, I will try to work something out otherwise will fall back to wsl2, anyway thanks a ton for your thorough answers! – Natalie Perret Feb 27 '22 at 17:29