Everyone wants to play with the Kubernetes(K8s). There are many options from Google, AWS, Heroku, etc. They offer free tiers that anyone can play with. But what if you want to have your K8s. On your laptop, for fun or to learn something new, without any restrictions.
What is k3s
The K3s is lightweight k8s by the rancher for Linux. K3s is intended to work with low resources and IoT devices. So, it can easily run on laptops. It is packed as a single binary so it is easy to setup. It requires to have installed docker, as nodes will be run inside containers.
What is k3d
The k3d is a wrapper around k3s as well made by the rancher. It intends to ease installation by detecting running OS, downloading binaries, and setting up the default configuration for the target OS.
Installation and usage
To install k3d and start a local cluster is rather easy. For example, if you are running Linux or OSX you could install it by using the brew:
> brew install k3d
When done you can do:
> k3d
Usage:
k3d [flags]
k3d [command]
Available Commands:
cluster Manage cluster(s)
completion Generate completion scripts for [bash, zsh, fish, powershell | psh]
config Work with config file(s)
help Help about any command
image Handle container images.
kubeconfig Manage kubeconfig(s)
node Manage node(s)
registry Manage registry/registries
version Show k3d and default k3s version
Flags:
-h, --help help for k3d
--timestamps Enable Log timestamps
--trace Enable super verbose output (trace logging)
--verbose Enable verbose output (debug logging)
--version Show k3d and default k3s version
Use "k3d [command] --help" for more information about a command.
If you do not have installed brew you can check other installation options on the k3d site.
Create cluster
Assuming you already have installed the docker and the kubectl you can init new cluster:
> k3d cluster create private-cluster
INFO[0000] Prep: Network
INFO[0000] Created network 'k3d-private-cluster'
INFO[0000] Created volume 'k3d-private-cluster-images'
INFO[0001] Creating node 'k3d-private-cluster-server-0'
INFO[0002] Creating LoadBalancer 'k3d-private-cluster-serverlb'
INFO[0002] Starting cluster 'private-cluster'
INFO[0002] Starting servers...
INFO[0002] Starting Node 'k3d-private-cluster-server-0'
INFO[0014] Starting agents...
INFO[0014] Starting helpers...
INFO[0014] Starting Node 'k3d-private-cluster-serverlb'
INFO[0016] (Optional) Trying to get IP of the docker host and inject it into the cluster as 'host.k3d.internal' for easy access
INFO[0020] Successfully added host record to /etc/hosts in 2/2 nodes and to the CoreDNS ConfigMap
INFO[0020] Cluster 'private-cluster' created successfully!
INFO[0020] --kubeconfig-update-default=false --> sets --kubeconfig-switch-context=false
INFO[0020] You can now use it like this:
kubectl config use-context k3d-private-cluster
kubectl cluster-info
You can check some info for the local cluster:
> kubectl cluster-info
Kubernetes control plane is running at https://0.0.0.0:49996
CoreDNS is running at https://0.0.0.0:49996/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Metrics-server is running at https://0.0.0.0:49996/api/v1/namespaces/kube-system/services/https:metrics-server:/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
Or get all nodes:
> ❯ kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3d-private-cluster-server-0 Ready master 2m28s v1.18.16+k3s1
Get all running pods:
❯ kubectl get pod --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system local-path-provisioner-6d59f47c7-8j4z6 1/1 Running 0 2m29s
kube-system metrics-server-7566d596c8-jwtxr 1/1 Running 0 2m29s
kube-system helm-install-traefik-5lbnw 0/1 Completed 0 2m30s
kube-system svclb-traefik-d2cvn 2/2 Running 0 2m4s
kube-system coredns-7944c66d8d-7b5rc 1/1 Running 0 2m29s
kube-system traefik-758cd5fc85-df4mq 1/1 Running 0 2m4s
Deploy a Pod
Let start the Apache server in local cluster:
> kubectl run test --image=httpd \
--port=80 \
--replicas=3 \
--restart='Always' \
--expose \
--requests='cpu=100m,memory=256Mi' \
--limits='cpu=200m,memory=512Mi' \
--labels=app=apache,version=1
Flag --replicas has been deprecated, has no effect and will be removed in the future.
service/test created
pod/test created
Check pod and services:
❯ kubectl get pod
NAME READY STATUS RESTARTS AGE
test 1/1 Running 0 94s
❯ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 6m55s
test ClusterIP 10.43.98.145 <none> 80/TCP 101s
The local cluster in addition to default services and pods has running httpd service and attached service all named test.
The basic work with a cluster
You can stop the cluster when done with it, so it does not eat not needed resource:
❯ k3d cluster stop private-cluster
INFO[0000] Stopping cluster 'private-cluster'
List all clusters managed by k3s:
❯ k3d cluster list
NAME SERVERS AGENTS LOADBALANCER
private-cluster 0/1 0/0 true
Start it again:
❯ k3d cluster start private-cluster
INFO[0000] Starting cluster 'private-cluster'
INFO[0000] Starting servers...
INFO[0000] Starting Node 'k3d-private-cluster-server-0'
INFO[0005] Starting agents...
INFO[0005] Starting helpers...
INFO[0005] Starting Node 'k3d-private-cluster-serverlb'
Check all:
❯ kubectl get all --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system pod/helm-install-traefik-5lbnw 0/1 Completed 0 17m
kube-system pod/local-path-provisioner-6d59f47c7-8j4z6 1/1 Running 1 17m
kube-system pod/metrics-server-7566d596c8-jwtxr 1/1 Running 1 17m
kube-system pod/svclb-traefik-d2cvn 2/2 Running 2 17m
default pod/test 1/1 Running 1 12m
kube-system pod/coredns-7944c66d8d-7b5rc 1/1 Running 1 17m
kube-system pod/traefik-758cd5fc85-df4mq 1/1 Running 1 17m
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 17m
kube-system service/kube-dns ClusterIP 10.43.0.10 <none> 53/UDP,53/TCP,9153/TCP 17m
kube-system service/metrics-server ClusterIP 10.43.133.151 <none> 443/TCP 17m
kube-system service/traefik-prometheus ClusterIP 10.43.5.75 <none> 9100/TCP 17m
kube-system service/traefik LoadBalancer 10.43.44.46 172.19.0.2 80:31193/TCP,443:30794/TCP 17m
default service/test ClusterIP 10.43.98.145 <none> 80/TCP 12m
NAMESPACE NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
kube-system daemonset.apps/svclb-traefik 1 1 1 1 1 <none> 17m
NAMESPACE NAME READY UP-TO-DATE AVAILABLE AGE
kube-system deployment.apps/local-path-provisioner 1/1 1 1 17m
kube-system deployment.apps/metrics-server 1/1 1 1 17m
kube-system deployment.apps/coredns 1/1 1 1 17m
kube-system deployment.apps/traefik 1/1 1 1 17m
NAMESPACE NAME DESIRED CURRENT READY AGE
kube-system replicaset.apps/local-path-provisioner-6d59f47c7 1 1 1 17m
kube-system replicaset.apps/metrics-server-7566d596c8 1 1 1 17m
kube-system replicaset.apps/coredns-7944c66d8d 1 1 1 17m
kube-system replicaset.apps/traefik-758cd5fc85 1 1 1 17m
NAMESPACE NAME COMPLETIONS DURATION AGE
kube-system job.batch/helm-install-traefik 1/1 26s 17m
Notice in the namespace named default there is a pod test and service test. This means our deployed httpd server is online.
Conclusion
Without going into details and reading long manuals you can get a fully functional K8s cluster to learn and develop. It is easy to operate so you can focus on learning to use K8s.