Disclaimer : I work at Microsoft. And you might think that this makes me a bit biased about the current topic. However, I was an enthusiastic MacOS / MacBook user – both privately and professionally. I work as a so-called “Cloud Solution Architect” in the area of Open Source / Cloud Native Application Development – i.e. everything concerning container technologies, Kubernetes etc. This means that almost every tool you have to deal with is Unix based – or at least, it only works perfectly on that platform. That’s why I early moved to the Apple ecosystem, because it makes your (dev) life so much easier – although you get some not so serious comments on it at work every now and then :)
Well, things have changed…
Introduction
In this article I would like to describe how my current setup of tools / the environment looks like on my Windows 10 machine and how to setup the latest version of the Windows Subsystem for Linux 2 (WSL2) optimally – at least for me – when working in the “Cloud Native” domain.
Long story short…let’s start!
Basics
Windows Subsystem for Linux 2 (WSL2)
The whole story begins with the installation of WSL2, which is now available with the current version of Windows (Windows 10, version 2004, build 19041 or higher). The Linux subsystem has been around for quite a while now, but it has never been really usable – at least this is the case for version 1 (in terms of performance, compatibility etc.).
The bottom line is that WSL2 gives you the ability to run ELF64 Linux binaries on Windows – with 100% system call compatibility and “near-native” performance! The Linux kernel (optimized in size and performance for WSL2) is built by Microsoft from the latest stable branch based on the sources available on “kernel.org”. Updates of the kernel are provided via Windows Update.
I won’t go into the details of the installation process as you can simply get WSL2 by following this tutorial: https://docs.microsoft.com/en-us/windows/wsl/install-win10
It comes down to:
- installing the Subsystem for Linux
- enabling “Virtual Machine Platform”
- setting WSL2 as the default version
Next step is to install the distribution of your choice…
Install Ubuntu 20.04
I decided to use Ubuntu 20.04 LTS, because I already know the distribution well and have used it for private purposes for some time – there are, of couse, others: Debian, openSUSE, Kali Linux etc. No matter which one you choose, the installation itself couldn’t be easier: all you have to do is open the Windows Store app, find the desired distribution and click “Install” (or simply click on this link for Ubuntu: https://www.microsoft.com/store/apps/9n6svws3rx71).
Once it is installed, you have to check if “version 2” of the subsystem for Linux is used (we have set “version 2” as default, but just in case…). Therefor, open a Powershell prompt and execute the following commands:
C:\> wsl --list --verbose
NAME STATE VERSION
* Ubuntu-20.04 Running 2
docker-desktop-data Running 2
docker-desktop Running 2
Ubuntu-18.04 Stopped 2
If you see “Version 1” for Ubuntu-20.04, please run…
C:\> wsl --set-version Ubuntu-20.04 2
This will convert the distribution to be able to run in WSL2 mode (grab yourself a coffee, the conversion takes some time ;)).
Windows Terminal
Next, you need a modern, feature-rich and lightweight terminal. Fortunately, Microsoft also delivered on this: the Open Source Windows Terminal. It includes many of the features most frequently requested by the Windows command-line community including support for tabs, rich text, globalization, configurability, theming & styling etc.
The installation is also done via the Windows Store: https://www.microsoft.com/store/productId/9N0DX20HK701
Once it’s on your machine, we can tweak the settings of the terminal to use Ubuntu 20.04 as the default terminal. Therefor, open Windows Terminal and hit “Ctrl+,” (that opens the settings.json file in your default text editor).
Add the guid of the Ubuntu 20.04 profile to the “defaultProfile” property:
Last but not least we upgrade all existing packages to be up to date.
$ sudo apt upgrade
So, the “basics” are in place now…we have a terminal that’s running Ubuntu Linux in Windows. Next, let’s give it super-powers!
Setup / tweak the shell
The software that is now being installed is an extract of what I need for my daily work. Of course the selection differs from what you might want (although I think this will cover a lot someone in the “Cloud Native” space would install). Nevertheless, it was important for me to list almost everything here, because it basically also helps me if I have to set up the environment again in the future :)
SSH Keys
Since it’s in the nature of a developer to work with GitHub (and other services, of course :)), I first need an SSH key to authenticate against the service. To do this, I create a new key (or copy an existing one to ~/.ssh/), which I then publish to GitHub (via their website).
At the same time the key is added to ssh-agent, so you don’t have to enter the corresponding keyphrase all the time when using it.
$ ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
# start the ssh-agent in the background
$ eval $(ssh-agent -s)
> Agent pid 59566
$ ssh-add ~/.ssh/id_rsa
Oh My Zsh
Now comes the best part :) To give the Ubuntu shell (which is bash by default) real superpowers, I exchange it with zsh_in combination with the awesome project _Oh My Zsh (which provides hundreds of plugins, customizing options, tweaks etc. for it). zsh is an extended bash shell which has many improvements and extensions compared to bash. Among other things, the shell can be themed, the command prompt adjusted, auto-completion can be used etc.
So, let’s install both:
$ sudo apt install git zsh -y
# After the installation has finished, add OhMyZsh...
$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
When ready, OhMyZsh can be customized via the .zshrc file in you home directory (e.g. enable plugins, set the theme). Here are the settings I usually make:
- Adjust Theme
- Activate plugins
Let’s do this step by step…
Theme
As theme, I use powerlevel10k (great stuff!), which you can find here.
The installation is very easy by first cloning the repo to your local machine and then activating the theme in ~/.zshrc (variable ZSH_THEME, see screenshot below):
$ git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH\_CUSTOM:-~/.oh-my-zsh/custom}/themes/powerlevel10k
The next time you open a new shell, a wizard guides you through all options of the theme and allows you to customize the look&feel of your terminal (if the wizard does not start automatically or you want to restart it, simply run p10k configure
from the command prompt).
The wizard offers a lot of options. Just find the right setup for you, play around with it a bit and try out one or the other. My setup finally looks like this:
Optional, but recommended...install the corresponding fonts (and adjust the settings.json of Windows Terminal to use these, see image below): https://github.com/romkatv/powerlevel10k#meslo-nerd-font-patched-for-powerlevel10k
Plugins
In terms of OhMyZsh plugins, I use the following ones:
- git (git shortcuts, e.g. “gp” for “git pull“, “gc” for “git commit -v“)
- zsh-autosuggestions / zsh-completions (command completion / suggestions)
- kubectl (kubectl shortcuts / completion, e.g. “kaf” for “kubectl apply -f“, “kgp” for “kubectl get pods“, “kgd” for “kubectl get deployment” etc.)
- ssh-agent (starts the ssh agent automatically on startup)
You can simply add them by modifying .zshrc in your home directory:
Additional Tools
Now comes the setup of the tools that I need and use every day. I will not go into detail about all of them here, because most of them are well known or the installation is incredibly easy. The ones, that don’t need much explanation are:
-
Azure CLI (
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo zsh
) + kubectl (handy installer via Azure CLI:az aks install-cli
) -
Node Version Manager NVM (
wget -qO- https://raw.githubusercontent.com/creationix/nvm/v0.33.8/install.sh | zsh
) and NodeJS LTS version (current: nvm install v12.18.0) - Azure Functions Core Tools (npm install -g azure-functions-core-tools@3)
- Terraform (https://www.terraform.io/downloads.html)
-
Helm via get_helm.sh script(
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
) -
Go (
sudo apt install golang
) - .NET Core (simply follow https://docs.microsoft.com/en-us/dotnet/core/install/linux-package-manager-ubuntu-2004)
- jq – work with JSON data in the shell (https://stedolan.github.io/jq/download/)
Give me more…!
There are a few tools that I would like to discuss in more detail, as they are not necessarily widely used and known. These are mainly tools that are used when working with Kubernetes/Docker. This is exactly the area where kubectx/kubens and stern are located. Docker for Windows and Visual Studio Code are certainly well known to everyone and are familiar through daily work. The reason why I want to talk about the latter two is because they meanwhile tightly integrate with WSL2!
kubectx / kubens
Who doesn’t know it? You work with Kubernetes and have to switch between clusters and/or namespaces all the time…forgetting the appropriate commands to set the context correctly and typing yourself “to death”. This is where the tools kubectx and kubens come in and help you to switch between different clusters and namespaces quickly and easily. I never want to work with a system again where these tools are not installed – honestly. To see kubectx/kubens in action, here are the samples from their GitHubrepo:
To install both tools, follow these steps:
$ sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx$ sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx$ sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubensmkdir -p ~/.oh-my-zsh/completionschmod -R 755 ~/.oh-my-zsh/completionsln -s /opt/kubectx/completion/kubectx.zsh ~/.oh-my-zsh/completions/\_kubectx.zshln -s /opt/kubectx/completion/kubens.zsh ~/.oh-my-zsh/completions/\_kubens.zsh
To be able to work with the autocomletion features of these tools, you need to add the following line at the end of your .zshrc:
autoload -U compinit && compinit
Congrats, productivity gain: 100% :)
stern
_stern_allows you to output the logs of multiple Pods simultaneously to the local command line. In Kubernetes it is normal to have many services running at the same time that communicate with each other. It is sometimes difficult to follow a call through the cluster. With stern, this becomes relatively easy, because you can select pods by e.g. label selectors from which you want to follow the logs.
With the command stern -l application=scmcontacts
e.g. you can stream the logs of all pods with the label application=scmcontacts to your local shell…which then looks like that (each color represents another pod!):
To install stern, use this script:s
$ sudo curl -fsSL -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.11.0/stern\_linux\_amd64
$ sudo chmod 755 /usr/local/bin/stern
One more thing
Docker for Windows has been around for a long time and is probably running on your machine right now. What some people may not know is that Docker for Windows integrates seamlessly with WSL2. If you are already running Docker on Windows, a simple invocation of the settings is enough to enable Docker / WSL2 integration:
If you want more details about the integration, please visit this page: https://www.docker.com/blog/new-docker-desktop-wsl2-backend/ For this article, the fact that Docker now runs within WSL2 is sufficient :)
Last but not least, one short note. Of course, Visual Studio Code can also be integrated into WSL2. If you install a current version of the editor in Windows, all components to run VS Code with WSL2 are included.
A simple call of code .
in the respective directory with your source code is sufficient to install the Visual Studio Code Server (https://github.com/cdr/code-server) in Ubuntu. This allows VSCode to connect remotely to your distro and work with source code / Frameworks that are located in WSL2.
That’s all :)
Wrap-Up
Pretty long blog post now, I know…but it contains all the tools that are necessary (take that with a “grain of salt” ;)) to make your Windows 10 machine a “wonderful experience” for you as a developer or architect in the “Cloud Native” space. You have a full compatible Linux “system”, which tightly integrates with Windows. You have .NET Core, Go, NodeJS, tools to work in the “Kubernetes universe”, the best code editor currently out there, git, ssh-agent etc. etc.…and a beautiful terminal which makes working with it simply fun!
For sure, there are thing that I missed or I just don’t know at the moment. I would love to hear from you, if I forgot “the one” tool to mention. Looking forward to read your comments/suggestions!
Hope this helps someone out there! Take care…
Photo by Maxim Selyuk on Unsplash
Top comments (11)
Hi, i use webpack + node to develop an client side js app on Windows, using native/win32 node version.
Is there any advantage to use webpack + node Linux version through WSL2, instead of it windows version?
Hi Luiz, I don't see any advantage of this env being in WSL2. If you're happy with it, stick to it :)
One of the biggest Issues for me is networking. Since WSL2 uses Hyper-V NAT (unlike WSL1 which bridges), it is hard to get the external LAN access WSL2. This is a pretty big deal and any info to do this would be great. And netsh portforwarding is kludgy and wont work with UDP ports.
Hi, great post, I have a question, this WSL it's like to use linux? I mean, can you install python3 and docker and play around docker, python, installing modules like wkhtmltopdf or modiying systemd files?... like an ubuntu machine
Correct...and you can even connect VS Code from Windows to the Linux environment and work on code that’s located in the Linux distro. You won’t even notice the difference.
I was looking forward to trying WSL2 but when I installed it I bumped into this issue: github.com/microsoft/WSL/issues/4739 which is a deal-breaker, so at least for now, I reverted back to WSL1 until they fix it.
Really useful, thanks! I've been wondering how to (a) tell if my existing wsl is v2 and (b) switch. Also liking powerline10k, after about 18 years of my own theme (:
It automatically comes with the Windows version mentioned above. So, just try to convert a version 1 distro to version 2 (an example is in the article). Fastest way to check :) BTW, both versions can run in parallel.
And thanks for the feedback!
Sorry, this was my lack of communication: what I meant to say was: I had these questions, and you answered them right at the top of the article, so I don't have them any more :D
Great article! One question: any idea how to run minkube on wsl2?
Haven’t looked into it yet...but I would currently rather try k3s than installing minikube.