00 K3s nedir — hafif Kubernetes, single binary
K3s, Rancher Labs (SUSE) tarafından geliştirilen, üretim kalitesinde ancak kaynak kullanımı minimize edilmiş bir Kubernetes dağıtımıdır. Tam Kubernetes API uyumluluğunu 512 MB RAM ve 200 MB disk'e sığdırır.
K3s vs tam Kubernetes karşılaştırması
| Özellik | Kubernetes (kubeadm) | K3s |
|---|---|---|
| Binary boyutu | Birden fazla binary ~500 MB | Tek binary ~100 MB |
| Min RAM (server) | ~2 GB | ~512 MB |
| Veritabanı | etcd (external) | Embedded SQLite veya embedded etcd |
| Container runtime | containerd / CRI-O | Embedded containerd |
| Kurulum süresi | 30-60 dakika | <2 dakika |
| ARM64 desteği | Evet (yapılandırma gerekir) | Resmi, birinci sınıf |
| Load balancer | Cloud LB veya MetalLB | Embedded ServiceLB (Klipper) |
| Ingress | Ayrı kurulum | Traefik gömülü gelir |
| TLS otomasyonu | cert-manager ayrıca kurulur | Otomatik self-signed TLS |
K3s bileşenleri
k3s server (RPi4 — control plane)
┌─────────────────────────────────────────────────────┐
│ API Server │ Scheduler │ Controller Manager │
│ embedded etcd/SQLite │
│ containerd │ kubelet │ kube-proxy │
│ Traefik (ingress) │ Klipper (LB) │
└─────────────────────────────────────────────────────┘
│ TLS (port 6443)
k3s agent (edge device 1) k3s agent (edge device 2)
Bu bölümde
- K3s = tek binary, <512 MB RAM, embedded SQLite/etcd
- Tam Kubernetes API uyumluluğu; mevcut manifest'ler değişiklik gerektirmez
- ARM64 birinci sınıf destek; RPi4, CM4, Jetson Nano, Orange Pi çalıştırır
01 K3s kurulumu — ARM64 ve systemd servisi
K3s kurulumu tek bir curl komutuyla gerçekleşir. Resmi kurulum script'i ARM64 mimarisini otomatik algılar ve uygun binary'yi indirir.
Ön gereksinimler
# cgroup memory etkinleştir — RPi'da gerekli
sudo sed -i 's/$/ cgroup_enable=memory cgroup_memory=1/' /boot/cmdline.txt
# Reboot gereklidir
sudo reboot
# Reboot sonrası cgroup doğrula
grep -i cgroup /proc/cmdline
cat /sys/fs/cgroup/cgroup.controllers
# cpuset cpu io memory hugetlb pids rdma misc
# iptables — nftables kullanılıyorsa uyumluluk katmanı ekle
sudo apt-get install -y iptables
sudo update-alternatives --set iptables /usr/sbin/iptables-legacy
K3s server kurulumu
# Resmi kurulum script'i — ARM64 otomatik algılanır
curl -sfL https://get.k3s.io | sh -
# Belirli versiyon ile kur
curl -sfL https://get.k3s.io | INSTALL_K3S_VERSION=v1.30.0+k3s1 sh -
# Traefik'i devre dışı bırakarak kur (kendi ingress kurulacaksa)
curl -sfL https://get.k3s.io | INSTALL_K3S_EXEC="--disable traefik" sh -
# Kurulum doğrulama
sudo systemctl status k3s
sudo k3s kubectl get nodes
# NAME STATUS ROLES AGE VERSION
# rpi4 Ready control-plane,master 30s v1.30.0+k3s1
# kubectl yapılandırması (root olmadan kullanmak için)
mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $(id -u):$(id -g) ~/.kube/config
# Node token kaydet (agent kurulumu için gerekli)
sudo cat /var/lib/rancher/k3s/server/node-token
Systemd servis yapılandırması
write-kubeconfig-mode: "0644"
tls-san:
- "192.168.1.100"
- "rpi4.local"
disable:
- traefik # kendi ingress kullanılacak
node-label:
- "node-role=edge-master"
- "location=factory-floor"
kube-reserved:
cpu: "200m"
memory: "256Mi"
system-reserved:
cpu: "100m"
memory: "128Mi"
Bu bölümde
- RPi4 için cgroup_enable=memory /boot/cmdline.txt'e eklenmeli
- curl -sfL https://get.k3s.io | sh - ile tek komut kurulum
- /etc/rancher/k3s/config.yaml ile server davranışı özelleştirilir
02 kubectl ile cluster yönetimi
kubectl, Kubernetes cluster'ını yönetmek için standart komut satırı aracıdır. K3s, kubectl'i binary içinde gömülü getirir.
Temel kubectl komutları
# Cluster bilgisi
kubectl cluster-info
kubectl get nodes -o wide
kubectl get nodes --show-labels
# Namespace yönetimi
kubectl get namespaces
kubectl create namespace production
kubectl create namespace monitoring
# Resource listele
kubectl get pods -A # tüm namespace
kubectl get pods -n production
kubectl get deployments -n production
kubectl get services -n production
# Pod detayları
kubectl describe pod <pod-name> -n production
kubectl logs <pod-name> -n production -f
kubectl logs <pod-name> -c <container-name> -n production
# Pod içine gir
kubectl exec -it <pod-name> -n production -- /bin/sh
# Resource sil
kubectl delete pod <pod-name> -n production
kubectl delete deployment <name> -n production
Konteks ve kubeconfig yönetimi
# Mevcut context göster
kubectl config current-context
# Tüm context'leri listele
kubectl config get-contexts
# Context değiştir
kubectl config use-context k3s-production
# Uzak cluster için kubeconfig merge et
export KUBECONFIG=~/.kube/config:~/.kube/k3s-edge.yaml
kubectl config view --merge --flatten > ~/.kube/merged-config
mv ~/.kube/merged-config ~/.kube/config
Bu bölümde
- kubectl get/describe/logs/exec temel yönetim döngüsünü oluşturur
- -n ile namespace belirt; -A tüm namespace'leri kapsar
- KUBECONFIG env değişkeni ile birden fazla cluster yönetilir
03 Deployment, Service, ConfigMap, Secret
Kubernetes'in temel kaynak tipleri: Deployment (pod replikaları), Service (ağ erişimi), ConfigMap (yapılandırma) ve Secret (hassas veriler).
Deployment manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: sensor-api
namespace: production
labels:
app: sensor-api
version: v1.2.0
spec:
replicas: 2
selector:
matchLabels:
app: sensor-api
template:
metadata:
labels:
app: sensor-api
spec:
containers:
- name: sensor-api
image: ghcr.io/myorg/sensor-api:v1.2.0
ports:
- containerPort: 5000
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "128Mi"
cpu: "250m"
envFrom:
- configMapRef:
name: sensor-api-config
- secretRef:
name: sensor-api-secrets
livenessProbe:
httpGet:
path: /api/health
port: 5000
initialDelaySeconds: 10
periodSeconds: 30
readinessProbe:
httpGet:
path: /api/ready
port: 5000
initialDelaySeconds: 5
periodSeconds: 10
Service, ConfigMap, Secret
---
apiVersion: v1
kind: Service
metadata:
name: sensor-api
namespace: production
spec:
selector:
app: sensor-api
ports:
- port: 80
targetPort: 5000
type: ClusterIP
---
apiVersion: v1
kind: ConfigMap
metadata:
name: sensor-api-config
namespace: production
data:
API_PORT: "5000"
LOG_LEVEL: "INFO"
MQTT_BROKER: "mqtt-broker.production.svc.cluster.local"
MQTT_PORT: "1883"
---
apiVersion: v1
kind: Secret
metadata:
name: sensor-api-secrets
namespace: production
type: Opaque
stringData:
DB_PASSWORD: "s3cur3pass"
API_TOKEN: "tok_abc123"
# Tüm manifest'leri uygula
kubectl apply -f k8s/
# Deployment durumu izle
kubectl rollout status deployment/sensor-api -n production
# Pod'ların node dağılımını gör
kubectl get pods -n production -o wide
Bu bölümde
- Deployment: replika sayısı, rolling update stratejisi, resource limit
- Service: ClusterIP (iç), NodePort (dış), LoadBalancer (Klipper)
- ConfigMap: env olarak, Secret: stringData base64 encode edilir
04 Local-path storage provisioner
K3s, local-path-provisioner ile gömülü dinamik PersistentVolume desteği sağlar. NFS veya cloud storage gerektirmeden node'un yerel diskini PVC'ye bağlar.
local-path kullanımı
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: influxdb-data
namespace: monitoring
spec:
accessModes:
- ReadWriteOnce
storageClassName: local-path
resources:
requests:
storage: 5Gi
# Varsayılan storage class listele
kubectl get storageclass
# NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE
# local-path (default) rancher.io/local-path Delete WaitForFirstConsumer
# PVC oluştur
kubectl apply -f k8s/pvc.yaml
# PVC durumu (pod bağlandığında Bound olur)
kubectl get pvc -n monitoring
# NAME STATUS VOLUME CAPACITY STORAGECLASS
# influxdb-data Bound pvc-abc123 5Gi local-path
# Fiziksel konum: /var/lib/rancher/k3s/storage/<pvc-id>
ls /var/lib/rancher/k3s/storage/
Bu bölümde
- local-path-provisioner K3s'e gömülüdür; ek kurulum gerekmez
- PVC oluştur, Deployment'ta volumeMounts ile bağla
- Veri /var/lib/rancher/k3s/storage/ altında node'da saklanır
05 Helm v3 ile chart deploy
Helm, Kubernetes uygulamalarını paketleyen ve yönetim döngüsünü (kurulum, güncelleme, rollback, kaldırma) standartlaştıran paket yöneticisidir.
Helm kurulumu
# Helm kurulumu
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
# Sürüm doğrula
helm version
# version.BuildInfo{Version:"v3.14.0", ...}
# Repository ekle
helm repo add stable https://charts.helm.sh/stable
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add mosquitto https://k-8s.github.io/mosquitto-helm-chart
helm repo update
# Chart ara
helm search repo mqtt
helm search hub influxdb
Chart deploy ve yönetim
# Namespace oluştur
kubectl create namespace monitoring
# InfluxDB v2 kur
helm install influxdb bitnami/influxdb \
--namespace monitoring \
--set auth.admin.password=securepass \
--set persistence.size=5Gi \
--set persistence.storageClass=local-path
# Release listele
helm list -n monitoring
# Values dosyasıyla kur
helm install nodered nodered/node-red \
--namespace iot \
--create-namespace \
-f nodered-values.yaml
# Güncelle
helm upgrade influxdb bitnami/influxdb \
--namespace monitoring \
--reuse-values \
--set image.tag=2.7.4
# Rollback (önceki versiyona dön)
helm rollback influxdb 1 -n monitoring
# Kaldır
helm uninstall influxdb -n monitoring
Bu bölümde
- Helm v3: helm install/upgrade/rollback/uninstall tam yaşam döngüsü
- --set ve -f values.yaml ile özelleştirme
- helm repo add ile community chart'larına erişim
06 K3s agent — multi-node edge cluster
K3s agent, worker node rolü üstlenir. ARM64 ve x86-64 node'lar aynı cluster'da karışık çalışabilir; node affinity ile iş yükleri belirli mimarilere yönlendirilir.
Agent kurulumu
# Server URL ve token'ı ayarla
export K3S_URL=https://192.168.1.100:6443
export K3S_TOKEN=K10abc...xyz # server node-token değeri
# Agent kurulumu
curl -sfL https://get.k3s.io | \
K3S_URL=$K3S_URL \
K3S_TOKEN=$K3S_TOKEN \
sh -
# Node label ekle (uygulama affinity için)
kubectl label node worker-01 \
node-role.kubernetes.io/worker=worker \
location=factory-floor \
arch=arm64
# Server üzerinde tüm node'ları gör
kubectl get nodes -o wide
# NAME STATUS ROLES AGE VERSION INTERNAL-IP
# rpi4 Ready master 2d v1.30.0+k3s1 192.168.1.100
# worker-01 Ready worker 1h v1.30.0+k3s1 192.168.1.101
# worker-02 Ready worker 45m v1.30.0+k3s1 192.168.1.102
Node affinity ile ARM64'e yönlendirme
apiVersion: apps/v1
kind: Deployment
metadata:
name: edge-sensor-collector
spec:
replicas: 1
selector:
matchLabels:
app: edge-sensor-collector
template:
metadata:
labels:
app: edge-sensor-collector
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/arch
operator: In
values:
- arm64
- key: location
operator: In
values:
- factory-floor
containers:
- name: collector
image: ghcr.io/myorg/collector:arm64
resources:
limits:
memory: "128Mi"
cpu: "200m"
Bu bölümde
- K3S_URL ve K3S_TOKEN ile agent tek komutla cluster'a katılır
- ARM64 ve x86-64 node'lar aynı cluster'da karışık çalışabilir
- nodeAffinity ile iş yükleri hedef mimari ve konuma yönlendirilir
07 Resource limits ve eviction threshold'ları
Edge cihazlarda RAM ve CPU kısıtlıdır. K3s server için ayrılan kaynaklar ve kubelet eviction ayarları, sistem kararlılığını korumak açısından kritiktir.
--kube-reserved ve --system-reserved
kubelet-arg:
- "kube-reserved=cpu=200m,memory=256Mi,ephemeral-storage=1Gi"
- "system-reserved=cpu=100m,memory=128Mi"
- "eviction-hard=memory.available<100Mi,nodefs.available<10%"
- "eviction-soft=memory.available<200Mi,nodefs.available<15%"
- "eviction-soft-grace-period=memory.available=1m30s,nodefs.available=2m"
- "max-pods=50"
| Parametre | Açıklama | RPi4 (4GB) Önerisi |
|---|---|---|
| kube-reserved.memory | K8s sistem bileşenlerine ayrılan RAM | 256 Mi |
| system-reserved.memory | OS ve diğer sistem süreçlerine ayrılan RAM | 128 Mi |
| eviction-hard.memory | Bu eşiğin altına düşünce pod anında tahliye edilir | 100 Mi |
| eviction-soft.memory | Grace period sonunda tahliye başlar | 200 Mi |
| max-pods | Tek node'da maksimum pod sayısı | 50 |
# Node kaynak kullanımı (metrics-server gerektirir)
kubectl top nodes
# Pod kaynak kullanımı
kubectl top pods -n production
# K3s ile gelen metrics-server'ı kontrol et
kubectl get deployment metrics-server -n kube-system
# Node koşulu izle
kubectl describe node rpi4 | grep -A 10 Conditions
Bu bölümde
- kube-reserved + system-reserved ile OS stabilitesi korunur
- eviction-hard: bellek kritik eşiğinin altına düşünce pod tahliye edilir
- kubectl top nodes/pods ile anlık kaynak kullanımı izlenir
08 Pratik — RPi4 üzerinde K3s + MQTT broker + Node-RED
Raspberry Pi 4 üzerinde K3s cluster'ına Helm ile Eclipse Mosquitto MQTT broker ve Node-RED deploy ediyoruz. Veriler MQTT'den Node-RED akışına akar, dashboard'dan izlenir.
Mimari
Sensör cihazları (MQTT publish: topic sensor/#)
│
▼
Mosquitto MQTT Broker (K3s, NodePort :1883)
│
▼
Node-RED (K3s, NodePort :1880)
MQTT-in → function → dashboard
MQTT-in → InfluxDB-out (veri arşivi)
│
▼
Dashboard :1880/ui (tarayıcıdan erişim)
Mosquitto MQTT broker kurulumu
replicaCount: 1
service:
type: NodePort
nodePorts:
mqtt: 31883
websocket: 31884
persistence:
enabled: true
storageClass: local-path
size: 1Gi
config: |
listener 1883
allow_anonymous true
persistence true
persistence_location /mosquitto/data/
log_dest stdout
# Namespace oluştur
kubectl create namespace iot
# Mosquitto chart repository ekle
helm repo add k8s-at-home https://k8s-at-home.com/charts/
helm repo update
# Mosquitto kur
helm install mosquitto k8s-at-home/mosquitto \
--namespace iot \
-f iot/mosquitto-values.yaml
# Node-RED kur
helm install node-red k8s-at-home/node-red \
--namespace iot \
--set service.type=NodePort \
--set service.nodePort=31880 \
--set persistence.enabled=true \
--set persistence.storageClass=local-path \
--set persistence.size=2Gi
# Deployment durumlarını izle
kubectl rollout status deployment/mosquitto -n iot
kubectl rollout status deployment/node-red -n iot
# Servisleri listele
kubectl get services -n iot
# NAME TYPE CLUSTER-IP PORT(S)
# mosquitto NodePort 10.43.10.20 1883:31883/TCP
# node-red NodePort 10.43.10.21 1880:31880/TCP
OTA güncelleme — kubectl rollout
# Deployment image'ını güncelle
kubectl set image deployment/sensor-api \
sensor-api=ghcr.io/myorg/sensor-api:v1.3.0 \
-n production
# Güncelleme durumunu izle
kubectl rollout status deployment/sensor-api -n production
# Waiting for deployment "sensor-api" rollout to finish: 1 out of 2 new replicas...
# deployment "sensor-api" successfully rolled out
# Rollback (önceki versiyona dön)
kubectl rollout undo deployment/sensor-api -n production
# Rollout geçmişi
kubectl rollout history deployment/sensor-api -n production
# MQTT test: broker'a mesaj gönder
mosquitto_pub -h 192.168.1.100 -p 31883 \
-t sensor/temperature \
-m '{"value": 23.5, "unit": "C"}'
Edge cluster'lar ağ bağlantısı kesintili ortamlarda çalışır. K3s server'ın embedded SQLite yerine embedded etcd kullanması için 3 node'lu HA kurulumu düşünün. İki node ile kurulum desteklenmez; HA için minimum 3 server node gerekir.
Bu bölümde
- Mosquitto + Node-RED Helm chart ile K3s'e deploy edildi
- NodePort ile RPi4 IP:port üzerinden dış erişim sağlandı
- kubectl rollout ile OTA güncelleme ve gerektiğinde rollback yapılır