Konteyner Orkestrasyon
TEKNİK REHBER KONTEYNER & EDGE K3s 2026

K3s —
Edge Kubernetes.

Tek binary, hafif Kubernetes dağıtımı. ARM64 kurulumu, kubectl yönetimi, Helm v3 ile uygulama dağıtımı. Multi-node edge cluster ve OTA güncelleme. RPi4 üzerinde MQTT broker + Node-RED.

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ı

ÖzellikKubernetes (kubeadm)K3s
Binary boyutuBirden fazla binary ~500 MBTek binary ~100 MB
Min RAM (server)~2 GB~512 MB
Veritabanıetcd (external)Embedded SQLite veya embedded etcd
Container runtimecontainerd / CRI-OEmbedded containerd
Kurulum süresi30-60 dakika<2 dakika
ARM64 desteğiEvet (yapılandırma gerekir)Resmi, birinci sınıf
Load balancerCloud LB veya MetalLBEmbedded ServiceLB (Klipper)
IngressAyrı kurulumTraefik gömülü gelir
TLS otomasyonucert-manager ayrıca kurulurOtomatik self-signed TLS

K3s bileşenleri

k3s serverControl plane: API server, scheduler, controller manager, embedded etcd/SQLite hepsini tek process olarak çalıştırır.
k3s agentWorker node. containerd, kube-proxy ve kubelet işlevlerini üstlenir. Server'a TLS ile bağlanır.
Embedded containerdDocker gerekmez. containerd doğrudan K3s içinde gömülü gelir; OCI imajları çalıştırır.
Klipper LBLoadBalancer tipi Service oluşturulduğunda node IP'si üzerinden port yönlendirmesi yapar; cloud LB gerektirmez.
Traefik ingressHTTP/HTTPS trafiği yönetir. IngressRoute CRD ile ileri yapılandırma desteği.
  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

bash — RPi4 ön hazırlık (Raspberry Pi OS Bookworm 64-bit)
# 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

bash — 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ı

/etc/rancher/k3s/config.yaml — K3s server 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ı

bash — kubectl temel kullanım
# 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

bash — kubeconfig ve context
# 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

k8s/deployment.yaml — örnek uygulama deployment
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

k8s/service-config-secret.yaml
---
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"
bash — manifest uygulama
# 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ı

k8s/pvc.yaml — PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: influxdb-data
  namespace: monitoring
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: local-path
  resources:
    requests:
      storage: 5Gi
bash — storage sınıfı ve PVC durumu
# 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/
WaitForFirstConsumerPVC, bir pod onu talep edene kadar Pending kalır. Bu, pod'un hangi node'da çalışacağını bilmeden volume oluşturulmamasını sağlar.
ReclaimPolicy: DeletePVC silindiğinde fiziksel veri de silinir. Üretimde Retain kullanın ve manuel temizlik yapın.
BackupYerel disk bozulursa veri kaybı yaşanır. Edge'de önemli veriler için rsync, restic veya Velero ile yedek alın.

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

bash — Helm v3 kurulumu ve repository ekleme
# 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

bash — Helm install ve upgrade
# 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

bash — K3s agent kurulumu (worker node)
# 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

k8s/arm64-deployment.yaml — mimari bazlı affinity
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

/etc/rancher/k3s/config.yaml — resource reservation
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"
ParametreAçıklamaRPi4 (4GB) Önerisi
kube-reserved.memoryK8s sistem bileşenlerine ayrılan RAM256 Mi
system-reserved.memoryOS ve diğer sistem süreçlerine ayrılan RAM128 Mi
eviction-hard.memoryBu eşiğin altına düşünce pod anında tahliye edilir100 Mi
eviction-soft.memoryGrace period sonunda tahliye başlar200 Mi
max-podsTek node'da maksimum pod sayısı50
bash — kaynak kullanımı izleme
# 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

iot/mosquitto-values.yaml — Helm values
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
bash — MQTT broker ve Node-RED deploy
# 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

bash — OTA uygulama güncelleme
# 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"}'
Üretim ipucu

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