Skip to content

Instantly share code, notes, and snippets.

@rosswf
Last active July 10, 2024 12:24
Show Gist options
  • Save rosswf/e5c4c85efb54a9f8d6e19a21cf09aa63 to your computer and use it in GitHub Desktop.
Save rosswf/e5c4c85efb54a9f8d6e19a21cf09aa63 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:

@frenkye
Copy link

frenkye commented Jul 10, 2024

Hi, just question why would you use kube-vip and metallb together when they do the same work and act as Loadbalancers? Trying to figure out why.

Thank you.

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