👋 This guide is mostly intented for Windows users. However, Linux and macOS users can easily skip or execute the equivalent steps to get the same result.
This repository contains the instructions and code to setup a local Kubernetes cluster. At the end, you'll get:
- A local Kubernetes cluster with TLS support for your services on local domains (such as
myapi.example.local
) - Command-line tools and completion for your terminal
- A configured nginx ingress controller with compression, web application firewall and extra security settings enabled
- A self-signed root certificate authority trusted by your OS, the cluster and your browsers
- Upgradeable Helm charts to easily customize this setup
Table of contents
- 🔧 Required setup
- ✨ Recommended additional setup
- 🔥 Getting started
- ☁ Install nginx ingress controller
- 🔑 Install cert-manager to manage TLS certificates
- 🚀 Deploy an ASP.NET Core example service
- 🧷 Install Kubernetes dashboard
Installing WSL 2 and an Ubuntu Linux distribution is only required on Windows.
Install Docker Desktop:
- Windows: https://docs.docker.com/desktop/install/windows-install/
- Linux: https://docs.docker.com/desktop/install/linux-install/
- macOS: https://docs.docker.com/desktop/install/mac-install/
Then, go to Docker Desktop settings > Kubernetes and check the Enable Kubernetes.
PowerShell Core 7 is cross-platform and only required on your OS and WSL 2 for one particular steps of this guide, which is coping the mkcert root certificate authority into the chart directory.
You may look at the content the script and do the equivalent on your own, without installing PowerShell Core.
On Windows, installing using Chocolatey is preferred.
mkcert (38k+⭐) is a simple tool for making locally-trusted development certificates. It will be used here to allow Kubernetes to issue self-signed certificates that are trusted by your browser and Windows / WSL 2, using a root certificate authority (CA). Execute mkcert -install
once installed.
Reuse mkcert CA on WSL 2
- Execute
mkcert -CAROOT
on both Windows and WSL 2 to print the directory of the root certificate authority files - Copy the files from Windows to WSL 2
- Execute once again
mkcert -install
on WSL 2
From Ubuntu, you can access Windows
C:\
drive using this mount/mnt/c/
From Windows, you can access Ubuntu files using this mount
\\wsl$\Ubuntu\
This step changes the cluster targeted by commands such as kubectl
, helm
, k9s
, etc. by modifying your kubeconfig file. This file is located:
- On Windows:
%userprofile%\.kube\config
- On Linux and macOS:
~/.kube/config
Run this command to target your local cluster:
kubectl config use-context docker-desktop
On Windows, you can also right click on Docker Desktop tray icon, then on Kubernetes and you should have access to a dropdown.
If you also installed
kubectl
and on your WSL 2 distribution, then both Windows and WSL 2 will use different kubeconfig files. You can force WSL 2 to use Windows' kubeconfig file by editing your~/.bashrc
and~/.zshrc
(if applicable) and adding the following line at the end (insert your Windows username):export KUBECONFIG=/mnt/c/Users/<WINDOWS-USERNAME>/.kube/config
.
These steps will mostly enhance your tooling and development experience.
- Windows: https://aka.ms/terminal
- Linux and macOS: https://ohmyz.sh and https://github.com/romkatv/powerlevel10k
After installing the module as an administrator, open a normal terminal and edit your profile (notepad $PROFILE
) to enable smart auto-complete by adding these lines:
Import-Module PSReadLine
Set-PSReadLineOption -PredictionSource History
Set-PSReadLineOption -PredictionViewStyle ListView
Set-PSReadlineOption -BellStyle None
Edit your profile (notepad $PROFILE
) and add the following lines:
kubectl completion powershell | Out-String | Invoke-Expression
helm completion powershell | Out-String | Invoke-Expression
Follow these and these steps for Linux and macOS.
"K9s is a terminal based UI to interact with your Kubernetes clusters. The aim of this project is to make it easier to navigate, observe and manage your deployed applications in the wild. K9s continually watches Kubernetes for changes and offers subsequent commands to interact with your observed resources."
Modify the maximum CPU and memory used by WSL 2 by following these steps.
-
Clone this git repository
-
Open a terminal into the cloned repository
-
Then, copy mkcert's root certificate authority (CA) into the
mkcert-local-setup
chart directory:
pwsh ./mkcert-local-setup/mkcert/Copy-Certificates.ps1
Nginx ingress controller is used to route the incoming traffic of your browser/tools to the services inside the cluster. By default it uses the ports
80
and433
so make sure you don't already have something using these ports, or edit thevalues.yaml
file.
First, have a look at .\nginx-ingress-setup\Chart.yaml
and .\nginx-ingress-setup\values.yaml
. You'll see that we install nginx-ingress
as a chart dependency, which pins a specific version and makes it easy to upgrade. The values.yaml
enables:
- Brotli and gzip compression
- Modsecurity web application firewall
- HSTS and secure headers
Now, run this command anytime you want to install or update the nginx ingress controller:
helm upgrade --install --wait --debug --dependency-update --namespace nginx-ingress --create-namespace nginx-ingress ./nginx-ingress-setup
Cert-manager is used to automatically issue certificates for the hostnames used by your services using mkcert's root certificate authority.
First, have a look at .\cert-manager-setup\Chart.yaml
and .\cert-manager-setup\values.yaml
. It's installed as a chart dependency too.
helm upgrade --install --wait --debug --dependency-update --namespace cert-manager --create-namespace cert-manager ./cert-manager-setup
We'll deploy the service in a dedicated Kubernetes namespace. It's a way to group Kubernetes objects in logical units. In this example, we will create and use a namespace named demo
.
We'll also deploy the service to the domain aspnetcore.example.local
. Two things:
- Make sure to add this custom local domain to your hosts files (instructions for Windows)
*.example.local
TLS support is pre-configured in the file.\mkcert-local-setup\values.yaml
, so if you want to use another local domain please update this file too
Issue a TLS certificate for *.example.local
in the demo
namespace by installing a release of this chart:
helm upgrade --install --wait --dependency-update --namespace demo --create-namespace demo-mkcert ./mkcert-local-setup
This will issue a TLS certificate stored in a secret named <helm-release-name>-tls-secret
. In this case the release name was demo-mkcert
, so created TLS secret is named demo-mkcert-tls-secret
. This secret name is very important because it will be referenced by your ingress.
The chart aspnetcore-service
exposes the Microsoft ASP.NET Core sample Docker application. The .\aspnetcore-service\values.yaml
ingress values are already configured to support the domain aspnetcore.example.local
and the TLS secret created in the previous step:
ingress:
className: nginx
hostname: aspnetcore.example.local # <-- Local domain covered by the TLS certificate
# [...]
tls:
enabled: true # <-- Don't want HTTPS? Set this to false
secretName: demo-mkcert-tls-secret # <-- Secret created in the previous step
Now, deploy the ASP.NET Core app to the demo
namespace, next to the TLS secret:
helm upgrade --install --wait --debug --dependency-update --namespace demo --create-namespace demo-aspnetcore ./aspnetcore-service
The service should now be accessible at https://aspnetcore.example.local/
Kubernetes dashboard is similar to k9s. It's a web-based UI to manage your cluster.
- We'll deploy it in a new namespace
kubernetes-dashboard
- It will be accessible at the URL https://kubernetes-dashboard.example.local, so modify your hosts file accordingly
Same as for the ASP.NET Core app, we first need a TLS certificate:
helm upgrade --install --wait --dependency-update --namespace kubernetes-dashboard --create-namespace kubernetes-dashboard-mkcert ./mkcert-local-setup
The kubernetes-dashboard-setup
chart uses the kubernetes-dashboard subchart and is already configured for our custom domain and TLS certificate secret name.
helm upgrade --install --wait --debug --dependency-update --namespace kubernetes-dashboard --create-namespace kubernetes-dashboard ./kubernetes-dashboard-setup
The service should now be accessible at https://kubernetes-dashboard.example.local. Press the "Skip" button to sign-in, anonymous access should be enabled.