Skip to content

Instantly share code, notes, and snippets.

@agozie
Forked from rosswf/k3s.md
Created March 5, 2024 18:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save agozie/eaf623d425136a9bb82b29a0073ece0c to your computer and use it in GitHub Desktop.
Save agozie/eaf623d425136a9bb82b29a0073ece0c to your computer and use it in GitHub Desktop.
Deploy HA k3s with kube-vip and MetalLB using k3sup

Prerequisites

kubectl

Install the required tools for deploying and controlling k3s.

Installation Docs:

# Download
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
# Checksum
curl -LO "https://dl.k8s.io/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl.sha256"
echo "$(cat kubectl.sha256)  kubectl" | sha256sum --check
# Install
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

k3sup

Installation Docs

# Download
curl -sLS https://get.k3sup.dev | sh
# Install
sudo install k3sup /usr/local/bin/

Nodes

Requirements:

  • Static IP address
  • SSH key copied over
  • Sudo setup for no password %sudo ALL=(ALL:ALL) NOPASSWD: ALL

Deploy First Master Node

Requirements & Information needed:

  • IP Address of node: --ip = 192.168.0.161 (dust-01)
  • IP Address to be used by kube-vup: --tls-san = 192.168.0.160
  • User with sudo priviledges: --user ross

Deploy k3s:

Note: Ensure $HOME/.kube/ folder exists

k3sup install \
--ip 192.168.0.161 \
--tls-san 192.168.0.160 \
--cluster \
--k3s-channel latest \
--k3s-extra-args "--disable servicelb" \
--local-path $HOME/.kube/config \
--user ross

kube-config will be saved to $HOME/.kube/config for use with kubectl.

Deploy kube-vip DaemonSet

Installation Docs

Requirements & Information needed:

  • IP Address to be used by kube-vup: --address 192.168.0.160
  • Network interface (check with ip a): --interface eth0

Apply RBAC

kubectl apply -f https://kube-vip.io/manifests/rbac.yaml

Pull image and create alias

SSH into first master node and do these steps as root

ssh 192.168.0.161
# Pull image - Check latest version on github or refer to docs.
ctr image pull ghcr.io/kube-vip/kube-vip:v0.4.4
# Create alias
alias kube-vip="ctr run --rm --net-host ghcr.io/kube-vip/kube-vip:v0.4.4 vip /kube-vip"

Generate and deploy manifest

kube-vip manifest daemonset \
--interface eth0 \
--address 192.168.0.160 \
--inCluster \
--taint \
--controlplane \
--arp \
--leaderElection | tee /var/lib/rancher/k3s/server/manifests/kube-vip.yaml

This should autodeploy because the manifest is copied to the k3s/server folder.

Modify kubeconfig.yml

Modify kubeconfig and change the server IP address to that used by kube-vip 192.168.0.160.

Deploy Addtional Master Nodes

Requirements & Information needed:

  • IP Address of new master nodes:
    • --ip = 192.168.0.162 (dust-02)
    • --ip = 192.168.0.163 (dust-03)
  • IP address used by kube-vip: --server-ip 192.168.0.160
  • User with sudo priviledges: --user ross

Deploy k3s to additional master nodes & join cluster:

Note --server flag is used

k3sup join \
--ip 192.168.0.162 \
--server-ip 192.168.0.160 \
--server \
--k3s-channel latest \
--user ross

Check nodes are up

kubectl get nodes

Add Worker Nodes

Requirements & Information needed:

  • IP Address of new worker nodes:
    • --ip = 192.168.0.164 (dust-04)
    • --ip = 192.168.0.165 (dust-05)
  • IP address used by kube-vip: --server-ip 192.168.0.160
  • User with sudo priviledges: --user ross

Deploy k3s to additional master nodes & join cluster:

k3sup join \
--ip 192.168.0.164 \
--server-ip 192.168.0.160 \
--k3s-channel latest \
--user ross

Check nodes are up

kubectl get nodes

Deploy and Configure MetalLB

Installation Docs

Install manifests

# Create namespace (metallb-system)
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
# Deploy metallb
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml

Create ConfigMap

Create config.yml as below, modify addresses to be the range of IP addresses MetalLb can hand out.

# config.yml
apiVersion: v1
kind: ConfigMap
metadata:
  namespace: metallb-system
  name: config
data:
  config: |
    address-pools:
    - name: default
      protocol: layer2
      addresses:
      - 192.168.0.170-192.168.0.180

Deploy ConfigMap

kubectl apply -f config.yml

Check MetalLb is running

kubectl get ds -n metallb-system

Test Deployment using Nginx

Create manifests

# deployment.yml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
# service.yml
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer

Deploy manifests

kubectl apply -f deployment.yml
kubectl apply -f service.yml

Check IP address assigned by Metal-LB

kubectl describe service nginx

Check accessible

# ip address handed out by MetalLB from describe service above
curl 192.168.0.XXX 

Teardown

kubectl delete deployment,service nginx

Resources and Thanks

Thanks to:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment