Deploy a Lightweight k3s Cluster on Cloud Servers with WireGuard
This step‑by‑step guide shows how to download the k3s binary, upgrade the kernel for WireGuard support, install WireGuard, configure the control plane and worker nodes, fix flannel IP issues, and enable metrics‑server on a cross‑cloud Kubernetes cluster.
1. Download binary
Download the k3s binary (v1.17.6+k3s1) from GitHub or a CDN accelerator. Example:
$ wget https://github.com/rancher/k3s/releases/download/v1.17.6+k3s1/k3s -O /usr/local/bin/k3s
$ chmod +x /usr/local/bin/k3sRepeat on all nodes.
2. Upgrade kernel
k3s uses the WireGuard CNI, which requires a newer kernel. On CentOS 7 install the ELRepo kernel‑ml packages:
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
$ rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
$ yum --disablerepo=* --enablerepo=elrepo-kernel repolist
$ yum --disablerepo=* --enablerepo=elrepo-kernel install kernel-ml.x86_64 -y
$ yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64 -y
$ yum --disablerepo=* --enablerepo=elrepo-kernel install kernel-ml-tools kernel-ml-devel kernel-ml-headers -y
$ grub2-set-default 'CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)'
$ rebootPerform the upgrade on every cluster node.
3. Install WireGuard
After the kernel upgrade, install WireGuard packages:
$ yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
$ yum install yum-plugin-elrepo
$ yum install kmod-wireguard wireguard-tools4. Deploy control plane
Create a systemd service unit for k3s on the master node:
$ cat > /etc/systemd/system/k3s.service <<EOF
[Unit]
Description=Lightweight Kubernetes
Wants=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
--tls-san <public_ip> \
--node-ip <public_ip> \
--node-external-ip <public_ip> \
--no-deploy servicelb \
--flannel-backend wireguard \
--kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \
--kube-proxy-arg "metrics-bind-address=0.0.0.0"
EOFEnable and start the service: $ systemctl enable k3s --now Check component health with kubectl get cs. k3s stores data in SQLite, which is lightweight for small clusters.
5. Join worker nodes
Create a similar unit file for the agent on each worker:
$ cat > /etc/systemd/system/k3s-agent.service <<EOF
[Unit]
Description=Lightweight Kubernetes
Wants=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=exec
EnvironmentFile=/etc/systemd/system/k3s-agent.service.env
KillMode=process
Delegate=yes
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s agent \
--node-external-ip <public_ip> \
--node-ip <public_ip> \
--kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \
--kube-proxy-arg "metrics-bind-address=0.0.0.0"
EOFProvide the master URL and token in /etc/systemd/system/k3s-agent.service.env:
K3S_URL=https://<master_ip>:6443
K3S_TOKEN=xxxxxxxxEnable and start the agent, then verify nodes with kubectl get node.
6. Fix flannel IP when internal network is unavailable
Annotate each node so flannel uses the public IP:
$ kubectl annotate nodes <node> flannel.alpha.coreos.com/public-ip-overwrite=<public_ip>Restart k3s on the node and confirm the WireGuard interface shows the public endpoint.
7. Resolve metrics‑server missing metrics
Edit the metrics‑server deployment to add the following arguments:
- --kubelet-preferred-address-types=ExternalIP
- --kubelet-insecure-tlsAfter redeploying, kubectl top nodes and kubectl top pod -n kube-system display CPU and memory usage.
With these steps, a cross‑cloud k3s cluster is ready. The next article will show how to expose the cluster to a home network.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
