Install K3s on Oracle Cloud - Step by Step Guide
flowchart LR
subgraph Step1["1. Provision"]
TF[terraform apply]
end
subgraph Step2["2. Push"]
Git[git push]
end
subgraph Step3["3. Wait"]
Boot[Cloud-init<br/>Bootstrap]
end
subgraph Step4["4. Verify"]
Check[kubectl get nodes]
end
TF --> Git --> Boot --> Check
Provisioning
Section titled “Provisioning”After creating terraform.tfvars, run Terraform to provision the infrastructure:
cd tf-k3sterraform initterraform applysequenceDiagram
participant You as Developer
participant TF as Terraform
participant OCI as OCI API
participant Nodes as Compute Instances
You->>TF: terraform apply
TF->>OCI: Create VCN
TF->>OCI: Create Subnets
TF->>OCI: Create Security Lists
TF->>OCI: Create Instances
OCI->>Nodes: Launch with cloud-init
TF->>You: Output IPs
Note over Nodes: Bootstrapping begins...
Terraform creates the OCI networking and compute instances, then generates Kubernetes manifests in the argocd/ directory.
Push Manifests
Section titled “Push Manifests”The generated manifests must be committed to your repository for Argo CD to sync them:
cd ..git add argocd/git commit -m "Configure cluster manifests"git pushflowchart LR
TF[Terraform] -->|generates| Manifests[argocd/]
Manifests -->|git push| GH[GitHub]
GH -->|syncs| Argo[Argo CD]
Argo -->|deploys| Cluster[K3s Cluster]
Bootstrapping
Section titled “Bootstrapping”Cloud-init scripts automatically configure each node:
gantt
title Node Bootstrap Timeline
dateFormat X
axisFormat %s
section Ingress
Enable IP forwarding :0, 30
Configure iptables NAT :30, 60
Install K3s agent :60, 120
Join cluster :120, 150
section Server
Install K3s server :0, 90
Deploy Argo CD :90, 150
Create secrets :150, 180
Sync applications :180, 300
section Worker
Install K3s agent :0, 90
Join cluster :90, 120
- Ingress node enables IP forwarding and NAT
- Server node installs K3s and Argo CD
- Worker node joins the cluster
Allow approximately five minutes for all nodes to initialize and Argo CD to begin syncing.
Verification
Section titled “Verification”Check Nodes
Section titled “Check Nodes”terraform outputExpected output:
NAME STATUS ROLES AGE VERSIONingress Ready <none> 5m v1.34.3+k3s1server Ready control-plane 5m v1.34.3+k3s1worker-1 Ready <none> 5m v1.34.3+k3s1Check Applications
Section titled “Check Applications”Expected output:
NAME SYNC STATUS HEALTH STATUSargocd-ingress Synced Healthyargocd-self-managed Synced Healthycert-manager Synced Healthydocs-app Synced Healthyenvoy-gateway Synced Healthyexternal-dns Synced Healthyexternal-secrets Synced Healthygateway-api-crds Synced Healthymanaged-secrets Synced Healthyroot-app Synced HealthyCheck Pods
Section titled “Check Pods”All pods should be Running except for completed Job pods.
Verify DNS and TLS
Section titled “Verify DNS and TLS”After a few minutes, test the deployed application:
dig +short k3s.yourdomain.comcurl -I https://k3s.yourdomain.comTroubleshooting First Deploy
Section titled “Troubleshooting First Deploy”Applications Stuck in Unknown/OutOfSync
Section titled “Applications Stuck in Unknown/OutOfSync”If ArgoCD applications remain in Unknown status after initial deploy:
Check if kustomize.buildOptions is set:
kubectl -n argocd get cm argocd-cm -o jsonpath='{.data.kustomize\.buildOptions}'If empty, patch it and restart the repo server:
kubectl -n argocd patch cm argocd-cm --type=merge -p '{"data":{"kustomize.buildOptions":"--enable-helm"}}'kubectl -n argocd rollout restart deploy argocd-repo-serverSync applications in dependency order:
for app in gateway-api-crds external-dns cert-manager external-secrets envoy-gateway managed-secrets argocd-self-managed argocd-ingress docs-app; do kubectl -n argocd patch application $app --type=merge -p '{"operation":{"sync":{}}}' sleep 10doneNode Not Joining Cluster
Section titled “Node Not Joining Cluster”If a node fails to join with label validation errors, SSH to the node and check:
sudo journalctl -u k3s-agent -n 50If you see unknown 'kubernetes.io' labels, the cloud-init used a restricted label. Fix by reinstalling:
sudo /usr/local/bin/k3s-agent-uninstall.shcurl -sfL https://get.k3s.io | INSTALL_K3S_EXEC='agent --node-label role=ingress' K3S_URL=https://10.0.2.10:6443 K3S_TOKEN='<token>' sh -HTTPS Verification
Section titled “HTTPS Verification”After all applications are synced, verify HTTPS works:
curl -I https://k3s.yourdomain.comcurl -I https://cd.k3s.yourdomain.comBoth should return HTTP/2 200. HTTP requests should redirect with 301:
curl -I http://k3s.yourdomain.comSee Common Issues for more solutions.