In my previous post, I shared my my experiences with k3s. Today I will show how easy it is to set up and host a simple static web page.

Prerequisites

You will need a server (or your computer) and a DNS domain name. For my playground, I used OVH Public Cloud instance - D2-2 with Debian 11, and *.k3s.domain.com domain name.

Install k3s

Installing k3s is very simple. Just execute curl -sfL https://get.k3s.io | sh - (although, I am not a fan of this method, as it’s best to download the script and take a look at it first). After executing the command, wait for 1-2 minutes for the cluster to be ready. You can check its status by executing command below. If it does not throw any errors - everything is OK.

1
2
3
root $ k3s kubectl get nodes
NAME        STATUS   ROLES                  AGE   VERSION
d2-2-waw1   Ready    control-plane,master   85s   v1.26.3+k3s1

Exposing the website with Traefik ingress

If you are familiar with k8s, then there is nothing fancy going on here ;) We need a deployment with definition of containers, service and ingress.

First, create a namespace: k3s kubectl create namespace pages

Create a deployment with a simple nginx container and default page, use k3s kubectl apply -f deployment.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  namespace: pages
  labels:
    app: pages
    page: nginx
spec:
  selector:
    matchLabels:
      app: pages
  replicas: 1
  strategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: pages
        page: nginx
    spec:
      containers:
        - name: web
          image: nginx
          resources:
            limits:
              cpu: 500m
              memory: 128Mi
            requests:
              cpu: 16m
              memory: 16Mi

Define a service that exposes the nginx port internally, use k3s kubectl apply -f service.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
apiVersion: v1
kind: Service
metadata:
  labels:
    app: pages
    page: nginx
  name: nginx-service
  namespace: pages
spec:
  internalTrafficPolicy: Cluster
  clusterIP: None
  ports:
    - name: http
      port: 8080
      protocol: TCP
      targetPort: 80
  selector:
    app: pages
    page: nginx
type: ClusterIP

Ingress configuration, use k3s kubectl apply -f ingress.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: nginx-k3s-domain-com
  namespace: pages
spec:
  rules:
    - host: nginx.k3s.domain.com
      http:
        paths:
          - backend:
              service:
                name: nginx-service
                port:
                  number: 8080
              path: /
              pathType: Prefix

After creating all the resources, you can check if everything is created correctly by running the command: k3s kubectl -n pages get deployment,pods,service,ingress

Next steps

I suggest installing cert-manager as the next step and then updating the ingress to generate certificates, as described here.

Updated ingress.yml looks as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt
  name: nginx-k3s-domain-com
  namespace: pages
spec:
  rules:
    - host: nginx.k3s.domain.com
      http:
        paths:
          - backend:
              service:
                name: nginx-service
                port:
                  number: 8080
            path: /
            pathType: Prefix
  tls:
    - hosts:
        - nginx.k3s.domain.com
      secretName: nginx-k3s-domain-com-tls