Skip to main content

Set up K3s and basic resources

Now it's time to set up Kubernetes on the home server.
I tried many tools to install K8s, but finally chose K3s.

  • HyperKit lacks support for M1/M2 Apple device.
  • Docker for Mac is quite heavy, so I didn't want to use it directly. Also minikube has some problems with exposing ingress.
  • I considered MicroK8s, kind and other tools, but I'm not satisfied with these too.

Install multipass + K3s (Mac mini)

  1. Install multipass via Homebrew

    brew install --cask multipass
  2. Install K3s and set up host kubectl config to control VM's Kubernetes.
    I previously explained this step in my personal document, Dive to Argo.
    Configured VM spec is like below:

    multipass launch --name k3s --memory 8G --disk 100G --cpus 4

PostgreSQL

PostgreSQL will be provided by Supabase.
Home server can be stopped in various situations, so I determined to place the database in an external service.

Install Argo CD

I chose Argo CD for CI/CD tool.
My Helm charts are in the private repository, and I can easily sync them with the cluster with Argo CD.

To install Argo CD, I created a new namespace.

kubectl create ns cicd

At the initial installation, I used Helm.
First, I added the Helm chart to the local repository.

brew install helm
helm repo add argo https://argoproj.github.io/argo-helm

Then, I created a values.yaml file to configure the resources.

values.yaml
controller:
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi

dex:
resources:
requests:
cpu: 5m
memory: 96Mi
limits:
cpu: 10m
memory: 144Mi
# Set up other resources

Finally, I installed Argo CD with the Helm chart.

helm install argocd -n cicd argo/argo-cd -f Downloads/values.yaml

Access ArgoCD from public domain

I wanted to expose Argo CD to the public domain, so that I could access it not only from the internal network.

MetalLB

MetalLB provides the external IP address to the Kubernetes service.

First, I added the Helm chart to the local repository.

helm repo add metallb https://metallb.github.io/metallb
helm install metallb metallb/metallb -n metallb-system

Then, I configured the IP address. I used Layer 2 method.

ipconfig.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: metallb-ip-pool
spec:
addresses:
- 192.168.0.200-192.168.0.250
---
apiVersion: metallb.io/v1beta1
kind: L2Advertisement
metadata:
name: metallb-advertise

Finally, I upgraded the Helm chart to apply the changes.

helm upgrade metallb metallb/metallb -n metallb-system

NGINX Ingress Controller

MetalLB only provides the external IP address to the Kubernetes service.
To expose Argo CD to the public domain, I installed NGINX Ingress.

helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update

helm install ingress-nginx ingress-nginx/ingress-nginx -n ingress --create-namespace --set controller.service.loadBalancerIP=192.168.0.222

After that, I looked forward to seeing the NGINX page at http://192.168.0.222.
However, I couldn't access it from the MacBook Air.
I checked the network settings of the VM, and found that the VM was not connected to the WiFi network.

lhu-macmini@macmini-austin ~ % multipass networks
Name Type Description
en0 ethernet Ethernet
en1 wifi Wi-Fi
en4 ethernet Ethernet Adapter (en4)
en5 ethernet Ethernet Adapter (en5)

To fix this, I added the network to the VM. I referred to the official document.

multipass set local.bridged-network=en1
multipass stop k3s
multipass set local.k3s.bridged=true
multipass start k3s

Finally, I could access Argo CD from the MacBook Air.

cert-manager

cert-manager is used to issue certificates for the ingress. I don't want to expose the Argo CD to the pure IP address or public domain without TLS, so I needed to configure certificate management.

cert-manager can be installed with the Helm chart, but I used the manifest file for the initial installation.

kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.15.3/cert-manager.yaml

cert-manager needs ACME issuer to issue certificates.
To configure the ACME issuer, I referred to the official document. Cloudflare also offers various services, so I decided to use it.

Configure Argo CD

After I configured cert-manager, I thought that it's ended up, but I found that I needed to configure Argo CD.

First, I needed to update the values.yaml file.

values.yaml
global:
domain: argocd.haulrest.me

configs:
params:
server.insecure: true
# ...

Then, I created a service and ingress to access Argo CD from the public domain.
Because the service is in another namespace, I used ExternalName type. I referred to the official document, but I finally configured it by myself because I cannot find the accurate configuration to my environment.

argocd-ingress.yaml
apiVersion: v1
kind: Service
metadata:
name: argocd-proxy-svc
spec:
type: ExternalName
externalName: argocd-server.cicd.svc.cluster.local
ports:
- name: http
port: 80

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-ingress
annotations:
cert-manager.io/cluster-issuer: tls-issuer
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-proxy-svc
port:
name: http
host: argocd.haulrest.me
tls:
- hosts:
- argocd.haulrest.me
secretName: argocd-tls

Finally, I upgraded the Helm chart to apply the changes.

helm upgrade argocd -n cicd argo/argo-cd -f Downloads/values.yaml
Comment (Korean)

아래 블로그에서도 부족한 내용을 많이 참고했습니다.
https://hibernationit.github.io/blog/oracle-cloud-with-k3s-tls/