Skip to content

Instantly share code, notes, and snippets.

@springcomp
Last active January 19, 2023 13:14
Show Gist options
  • Save springcomp/d21abc776ff2503129ebd3a64c73ddef to your computer and use it in GitHub Desktop.
Save springcomp/d21abc776ff2503129ebd3a64c73ddef to your computer and use it in GitHub Desktop.
Installing Docker and Kubernetes for WSL2 without Docker Desktop

Overview

This file outlines the steps taken to install and run Docker on Windows (WSL2) without Docker Desktop. To mimic the existing experience, those steps will guide you through creating a separate Linux distribution to host the Docker engine.

Download and install Linux distro from tarball

Distribution Location
Ubuntu-20.04 (Focal Fossa) https://cloud-images.ubuntu.com/focal/current/focal-server-cloudimg-amd64-wsl.rootfs.tar.gz
Ubuntu-22-04 (Jammy Jellyfish) microsoft/WSL#8402
  1. Create a new distribution
.\CreateLinuxDistro.ps1 `
	-INPUT_FILENAME <path-to-linux-distro-tarball> `
	-OUTPUT_DIRNAME "$env:LOCALAPPDATA\Packages\<distro>" `
	-OUTPUT_DISTRONAME <distro> `
	-CREATE_USER 1 `
	-CREATE_USER_USERNAME <username> `
	-ADD_USER_TO_GROUP 1 `
	-ADD_USER_TO_GROUP_NAME sudo `
	-SET_USER_AS_DEFAULT <username>

For instance, I named my <distro> ubuntu-docker and created a new <username> docker.

Install and configure Docker in WSL2

  1. Install docker

You can use the following command to retrieve the IP address from the WSL2 instance:

`ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}'`
  1. Configuration
  • Add <username> to the list of /etc/sudoers and prevent password prompt
<username>  ALL=(ALL:ALL) NOPASSWD:ALL

Run Docker from another WSL instance

  1. Install docker-ce-cli on another instance.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce-cli 
  1. Update the docker host

As Docker is running in a separate WSL2 instance, the DOCKER_HOST environment variable must be updated. Add this to the ~/.bashrc file:

# Docker is hosted on another WSL2 instance
#
ip=`wsl.exe -d <distro> sh -c "hostname -I | cut -f1 -d ' '"`
export DOCKER_HOST="tcp://$ip:2375"
  1. Install docker-compose utility

docker-compose is a separate binary which can be downloaded from the project’s GitHub releases page. Locate the latest version number and install using the following command:

sudo curl -L "https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose

Install Docker CLI on Windows

The docker CLI for Windows can be downloaded from: https://github.com/StefanScherer/docker-cli-builder/releases

The docker-compose CLI for Windows can be downloaded from: https://github.com/docker/compose/releases/download/v2.2.3/docker-compose-windows-x86_64.exe

Start and stop Docker from Windows PowerShell

Use the following scripts to start and stop Docker.

Start Docker

$Env:DOCKER_HOST="tcp://localhost:2375"

Function Start-Docker {
    $ip = (wsl -d <distro> sh -c "hostname -I").Split(" ")[0]
    Write-Host "netsh interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=$ip"
    $arguments = "interface portproxy add v4tov4 listenport=2375 connectport=2375 connectaddress=$ip" 
    Start-Process netsh -ArgumentList $arguments -Verb RunAs
    Start-Job { param([string]$ip) wsl -d <distro> sh -c "sudo dockerd -H tcp://$ip" } -ArgumentList $ip | Out-Null
}
Set-Alias -Name dockerd -Value Start-Docker

This retrieves the current IP address from the WSL2 Docker instance and sets up port forwarding from the local host address to the WSL Docker instance. This requires elevated privileges.

Once that is setup, a pwsh background job is started to run the dockerd daemon in the WSL2 Docker instance.

Please, wait for a few seconds, and test that Docker is running with the following command:

docker -H tcp://localhost:2375 ps -a

You can make the -H tcp://localhost:2375 a default value by creating the DOCKER_HOST environment variable.

Stop Docker

Function Stop-Docker { wsl --terminate <distro> }
Set-Alias -Name rmdocker -Value Stop-Docker

This will terminate the WSL2 Docker distribution.

Install Kubernetes

You can install Minikube in another WSL2 instance. We will take advantage of the previous Docker installation.

  1. Follow the steps outlined earlier to create a new distribution

For instance, I named my <distro> ubuntu-minikube and created a new <username> kube.

Log in to the WSL2 ubuntu-minikube instance and:

  1. Install Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube_latest_amd64.deb
sudo dpkg -i minikube_latest_amd64.deb
  1. Configuration
  • Add <username> to the list of /etc/sudoers and prevent password prompt
<username>  ALL=(ALL:ALL) NOPASSWD:ALL

As Docker is available from another WSL2 distribution, add the following commands in ~/.bashrc:

# Docker is hosted on another WSL2 instance
#
ip=`wsl.exe -d ubuntu-docker sh -c "hostname -I | cut -f1 -d ' '"`
export DOCKER_HOST="tcp://$ip:2375"

Install Kubernetes CLI tool on Windows

The kubectl CLI tool can be downloaded from: https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/

Start and stop Kubernetes from Windows PowerShell

Use the following command to start Kubernetes

Start Kubernetes

Function Start-Kubernetes {
    wsl -d ubuntu-minikube sh -c "/home/kube/minikube.sh start --embed-certs"
    wsl -d ubuntu-minikube sh -c "cp ~/.kube/config /mnt/c/Users/$($env:USERNAME)/.kube"
}
Set-Alias -Name k8s -Value Start-Kubernetes

This command start Minikube from its WSL2 distro with the --embed-certs command-line option. This makes the certificates available in the ~/.kube/config file.

Those certificates can then be copied to the Windows host username folder for kubectl to find them.

To enable Kubernetes from other WSL2 distributions, you can run the following command:

[[ ! -L ~/.kube/config ]] && ln -s "/mnt/c/Users/`cmd.exe /c "echo|set /p=%USERNAME%" 2>/dev/null`/.kube/config" ~/.kube/config

Managing Minikube from WWindows

You can use the following command to manage Minikube from Windows.

Function minikube { wsl -d ubuntu-minikube sh -c "/home/kube/minikube.sh $args" }

Stop Kubernetes

Function Stop-Kubernetes { wsl --terminate <distro> }
Set-Alias -Name rmkube -Value Stop-Kubernetes
Set-Alias -Name rmk8s -Value Stop-Kubernetes

This will terminate the WSL2 Docker distribution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment