This post is a recipe for setting up a minimal Kubernetes cluster on Fedora without requiring virtualization or a container registry. These two features make the system cloud-agnostic and the cluster entirely self-contained. The post will end with us running a simple Flask app from a local container.
This setup is primarily useful for simple CI environments or application development on Linux. (Docker Desktop has better tooling for development on Mac or Windows.)
Getting Kubernetes
The core of this effort is K3s, a Kubernetes distribution that allows us to run on a single node without virtualization.
But first off, install Docker.
Then install K3s:
$ curl -sfL https://get.k3s.io | sh -
It may prompt you to adjust some SELinux policies like so:
$ sudo dnf install -y container-selinux selinux-policy-base
$ sudo rpm -i https://rpm.rancher.io/k3s-selinux-0.1.1-rc1.el7.noarch.rpm
Swap these out with whatever it prompts and retry the K3s install.
Finally, install kubectl:
$ curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
Now copy the global K3s kubeconfig into ~/.kube/config
:
$ sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
$ sudo chown $USER:$GROUP ~/.kube/config
And enable K3s:
$ sudo systemctl enable k3s
If you're on Fedora 31+ you'll need to disable cgroups v2 and reboot:
$ sudo grubby --args="systemd.unified_cgroup_hierarchy=0" --update-kernel=ALL
$ sudo reboot
Finally, you can run kubectl
:
$ kubectl get pods
No resources found in default namespace.
A simple application
We'll create a small Flask app, containerize it, and write a Kubernetes deployment and service config for it.
We begin with app.py
:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def index():
return 'Hello World, Flask!'
if __name__ == '__main__':
app.run(debug=True)
Then a Dockerfile
:
FROM python:3-slim
RUN pip install flask
COPY . /app
CMD python3 /app/app.py
Then the deployment in manifest.yaml
:
apiVersion: apps/v1
kind: Deployment
metadata:
name: helloworld
spec:
selector:
matchLabels:
name: helloworld
template:
metadata:
labels:
name: helloworld
spec:
containers:
- image: helloworld
name: helloworld
Running in Kubernetes
First we build, save, and import the image into k3s
:
$ docker build . -t helloworld
$ docker save helloworld > helloworld.tar
$ sudo k3s ctr image import helloworld.tar
$ kubectl apply -f ./manifest.yaml
$ kubectl port-forward $(kubectl get pods | grep helloworld | cut -d ' ' -f 1) 5000 > log 2>&1 &
$ curl localhost:5000
Hello World, Flask
And that's it!
Latest post is a recipe for creating a self-contained, single-node Kubernetes cluster for CI environments using a basic Flask app.https://t.co/fegAZFEQzO
— Phil Eaton (@phil_eaton) July 25, 2020