The Problem
Now that we have a cluster set up with storage, a persistent volume claim, ingress control, as well as local dns, we need something for all of this to do. I figured a good start would be a dashboarding app where we can get all of our future apps and services in one place and easily accessible.
I’ve been using the Homepage Dashboard on a docker container for over a year now, so now I plan to move it to the k3s cluster. This setup below will be for homepage, but other applications should be set up similarly.
Homepage Dashboard is configurable with xmls and can act as a “bookmarks” page for apps and services. It also has the ability to pull metrics and display them for various applications. I plan to just use the bookmarks page functionality so this guide will not include individual app metrics. This requires additional Role-Based Access Control (RBAC) set up that I will not be doing here.
The Approach
- On the control node, create the homepage namespace
kubectl create namespace homepage
- On the control node, create a “homepage” directory and cd into that new directory.
mkdir homepage && cd homepage
- Create a “manifests” and “config” directories
mkdir manifests && mkdir config
- create the following manifest files with the touch command:
touch manifests/homepage-deployment.yaml
touch manifests/homepage-service.yaml
touch manifests/clusterissuer.yaml
touch manifests/homepage-ingress.yaml
- Create the following config files with the touch command:
touch config/settings.yaml
touch config/bookmarks.yaml
touch config/services.yaml
touch config/widgets.yaml
- Edit the settings.yaml and copy in the following (the other files can be blank):
title: Homepage
- Create the homepage config map:
kubectl create configmap homepage-config --from-file=settings.yaml --from-file=bookmarks.yaml --from-file=services.yaml --from-file=widgets.yaml -n homepage
- cd into manifests directory and edit homepage-deployment.yaml file:
apiVersion: apps/v1
kind: Deployment
metadata:
name: homepage
namespace: homepage
spec:
replicas: 1
selector:
matchLabels:
app: homepage
template:
metadata:
labels:
app: homepage
spec:
containers:
- name: homepage
image: ghcr.io/gethomepage/homepage:latest
ports:
- containerPort: 3000
volumeMounts:
- name: config
mountPath: /app/config
volumes:
- name: config
configMap:
name: homepage-config
- Apply the deployment manifest:
kubectl apply -f homepage-deployment.yaml
- From the manifests directory, edit the homepage-service.yaml
apiVersion: v1
kind: Service
metadata:
name: homepage
namespace: homepage
spec:
selector:
app: homepage
ports:
- port: 3000
targetPort: 3000
- Apply the service manifest:
kubectl apply -f homepage-service.yaml
- From the manifests directory, edit the clusterissuer.yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: you@yourdomain.com
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: traefik
- Apply the clusterissuer manifest
kubectl apply -f manifests/clusterissuer.yaml
- From the manifests directory, edit the homepage-ingress.yaml.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: homepage
namespace: homepage
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- homepage.yourdomain.com
secretName: homepage-tls
rules:
- host: homepage.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: homepage
port:
number: 3000
- Apply the ingress manifest:
kubectl apply -f homepage-ingress.yaml
- Validate it is working with kubectl
kubectl get pods -n homepage
kubectl get svc -n homepage
kubectl get ingress -n homepage
- Once running, open browser and navigate to homepage.yourdomain.local and you should hit your new homepage dashboard without a certificate error
- You can update the config files as you wish based on homepage docs.
- Once edited, you’ll need to patch the ConfigMap from step 7:
kubectl create configmap homepage-config --from-file=settings.yaml --from-file=services.yaml --from-file=bookmarks.yaml --from-file=widgets.yaml -n homepage --dry-run=client -o yaml | kubectl apply -f -
kubectl rollout restart deployment/homepage -n homepage
The Impact
- This project taught me the differences between deploying an app to docker vs deploying an app to k3s. With docker being straight forward to set up, deploying an app on a container is as simple as configuring a docker-compose file, which is typically provided by the application or service doc website. The k3s install was a little more involved, due to the initial set up and configuration the cluster required. Once the cluster or containers are set up however, application config is fairly straightforward on k3s as well. Directory creation, manifest creation so the cluster can handle ingress control when the app is running on a pod, and service creation that the application can run as a service on the cluster.