İçeriğe geç

(B) DevOps

Kaniko ile Kubernetes Pod İçinde Dockersız İmaj Derleme

6 dk okuma

Neden Kaniko

Kubernetes kümelerinde container imajı derlemek denildiğinde akla ilk gelen çözüm genellikle Docker-in-Docker veya host'a mount edilmiş paylaşımlı bir Docker socket olur. Her iki yaklaşımda da bir daemon süreci çalıştırmak, imajları host dosya sistemine yazmak ve bu sürece erişim vermek gerekir. Güvenlik perspektifinden baktığında bu, yönetim karmaşıklığını artırır ve saldırı yüzeyini genişletir. Kaniko, bu bağımlılığı ortadan kaldıran bir build aracı olarak tasarlanmıştır. Pod içinde executor imajını çalıştırarak Dockerfile'ı okur, her talimatı sırayla işler ve ortaya çıkan katmanları doğrudan registry'ye gönderir. Docker daemon'a ihtiyaç duymaz; tüm komutlar userspace'de koşar. Bir not: proje GoogleContainerTools çatısı altında arşivlendi. Kod tarihsel amaçla erişilebilir durumda; yaygın kullanımı hâlâ sürdüğü için mevcut pipeline'larda karşılaşmak normal, yeni tasarımlarda bu durumu hesaba katmak gerekir.

Çalışma Prensibi

Kaniko, Dockerfile'daki her talimatı yorumlar ve geçici bir dosya sistemi üzerinde çalıştırır. Executor, base imajın (FROM satırındaki imajın) filesystem'ini kendi container root'una açar, her komuttan sonra userspace'de snapshot alır ve değişen dosyaları base imaja katman olarak ekler. Build context pod filesystem'inden, bir git repository'sinden veya bir bucket'tan alınabilir. Destination parametresi ile hedef registry ve imaj adı belirlenir.

Pod Konfigürasyonu

Kaniko çalıştırmak için bir pod tanımı yeterlidir. Aşağıdaki örnek, git üzerinden context alıp Docker Hub tarzı bir registry'ye push eden bir build pod'u gösterir.
apiVersion: v1
kind: Pod
metadata:
  name: kaniko-build
spec:
  restartPolicy: Never
  containers:
  - name: kaniko
    image: gcr.io/kaniko-project/executor:latest
    args:
    - "--dockerfile=Dockerfile"
    - "--context=git://github.com/kullanici/proje.git#refs/heads/main"
    - "--destination=registry.example.com/uygulama:1.4.0"
    volumeMounts:
    - name: kaniko-secret
      mountPath: /kaniko/.docker
  volumes:
  - name: kaniko-secret
    secret:
      secretName: docker-config
      items:
      - key: .dockerconfigjson
        path: config.json
Secret, registry'ye erişim için gerekli kimlik bilgilerini taşır. Kaniko bu dosyayı /kaniko/.docker/config.json yolundan okuyarak push işlemini gerçekleştirir. ECR için credential helper executor imajının içinde gömülü gelir; instance role kullanılıyorsa secret'a gerek kalmaz, AWS_SDK_LOAD_CONFIG=true ortam değişkeni yeterli olur. Harbor gibi registry'ler docker config auth mekanizmasıyla çalışır.

Context Türleri

Kaniko, farklı context kaynaklarını destekler. Local pod filesystem'ından build etmek için context parametresine dir:///workspace biçiminde bir dizin yolu verilir; prefix verilmezse kaniko zaten local dizin varsayar. Git repository'sinden derlemek için URL scheme olarak git:// kullanılır; dal adı #refs/heads/ referansıyla, commit ise sonuna eklenen hash ile sabitlenebilir. tar:// ile lokal veya stdin üzerinden tar.gz, gs:// ve s3:// ile bucket, Azure Blob Storage için https URL'si kullanılır. Bucket kullananlarda context önce sıkıştırılıp yüklenir, kaniko indirip açar ve build'e başlar.

Katman Cache

Ephemeral pod'larda her build sıfırdan başlar; Docker'daki local layer cache karşılığı yoktur. Kaniko'nun çözümü registry üstünde katman cache'i. --cache=true ile RUN ve COPY katmanları uzak bir repository'de saklanır; komut çalıştırılmadan önce cache'e bakılır, katman bulunursa çekilip açılır. Cache repository'si --cache-repo ile verilir; verilmezse destination'dan türetilir. Cache miss yaşandığında kalan katmanların hiçbiri cache'e danışılmadan lokal kurulur; Dockerfile'daki satır sırası bu yüzden halen önemli. Cache ömrü --cache-ttl ile ayarlanır. Base imajlar için ayrı bir mekanizma var. gcr.io/kaniko-project/warmer imajı ile bir volume içine önceden indirilen base imajlar, pod'a mount edilen --cache-dir üzerinden okunur. Bu lokal cache salt okunurdur, warmer ile doldurulması gerekir.

Snapshot Mode Seçimleri

Daemon olmadığı için katman farkları filesystem snapshot'ı ile hesaplanır. --snapshot-mode parametresi bu snapshot sırasında hangi dosya özelliklerinin karşılaştırılacağını belirler. Varsayılan full; dosya içeriği ve metadata tamamen incelenir, en yavaş ama en güvenilir seçenek. redo modunda mtime, boyut, mode, uid ve gid değerlerine bakılır; çok dosyalı projelerde full'e göre %50'ye varan hız artışı verir. time yalnızca mtime'a bakar; mtime güncellemesi gecikmeli olduğu için RUN komutlarının yaptığı değişiklikleri kaçırabilir. Üretim işlerinde time modundan uzak durmak mantıklı. Deneysel --use-new-run flag'i ise snapshot'a hiç bel bağlamaz; RUN öncesi bir marker dosyası oluşturup modtime'ı ondan büyük dosyaları tarar, build sürelerinde %75'e varan iyileşme bildirilmiş durumda. Doğruluk pahasına hız alır, bu yüzden dikkatli kullanılmalı.

Gerçek Dünya Kullanımı

Birçok kurumsal ortamda Kubernetes worker node'larında Docker daemon çalıştırmak güvenlik politikalarına aykırıdır. Kaniko, build'i pod içine hapseder. Tek başına güvenlik garantisi vermez; container runtime'ın izolasyonuna güvenir. Ek sınır istenirse gVisor runtime'ı ile çalıştırılabilir, bu durumda runtime tespiti yapılamadığından --force flag'i eklenmelidir. CI/CD tarafında Jenkins, GitLab CI veya Cloud Build adımlarında executor imajı bir build step olarak tanımlanır. GitOps yaklaşımı benimseyen ekiplerde kod commit'i geldiğinde imajın build edilip registry'ye push edilmesi, sonrasında ArgoCD benzeri bir aracın bu değişikliği fark ederek deployment'i güncellemesi yaygın bir kalıptır.

Sınırlar

Kaniko, Docker ile birebir aynı davranan bir Dockerfile yorumlayıcısı değildir. Windows container build'i desteklemez. v1 Registry API'sini desteklemez. Executor binary'sinin resmi imaj dışında bir imajda veya başka bir imaja kopyalanarak çalıştırılması desteklenmez; chroot ve bind-mount kullanamaz, base imajı doğrudan kendi container root'una açtığı için üzerine yazabileceği her şey tehlike sınırında sayılır. Build argümanları ve secret'lar doğru aktarılmazsa build başarısız olur; registry kimlik bilgilerinin secret içinde doğru formatta saklanması kritik. Çok büyük context'ler network üzerinden transfer edilirken bant genişliği sorunu yaşanabilir. Bu durumda context'i önceden hazırlayıp bir volume içinden vermek veya bucket tabanlı context kullanmak daha verimli olur. Kaniko, dockersız build ihtiyacının en bilinen cevabı. Katman cache'i, çeşitli context kaynakları ve snapshot mode seçenekleri farklı senaryolara uyum sağlıyor. Docker tabanlı eski build sistemlerini taşıyan ekipler için geçiş sürtünmesi düşük; arşiv durumunu ve runtime izolasyonunu hesaba katan herkes için sağlam bir seçenek.

Açık kaynak

GitHub projeleri

Tümünü gör
wireguard-server-panel

WireGuard VPN sunucu paneli - İstemci yönetimi, QR kodları ve trafik istatistikleri için kendi sunucunuzda barındırılan web kullanıcı arayüzü (fork, aktif olarak geliştirilmekte)

Go

Laravel-NDFirewall

Rota Kapsamlı Laravel WAF - RCE, SQLi, XSS ve SSRF algılama özelliklerine sahip hafif bir Web Uygulaması Güvenlik Duvarı

PHP

Trustsslroot

Tek komutla çalışan özel PKI oluşturucu - Kendi kendini imzalayan kök CA ve sertifikaları anında oluşturun

Go

node_exporter

Hafif sistem metrikleri aktarıcısı - Güvenli erişim kontrolüne sahip, Linux için durum bilgisi barındırmayan tek ikili dosyalı izleme hizmeti

Rust

ipReconary

IP keşif ve alt ağ analiz aracı - Hızlı ağ taraması ve IP istihbarat toplama

Rust

Cloudfiltred

Cloudflare IP beyaz liste güvenlik duvarı - 80/443 numaralı bağlantı noktalarını yalnızca Cloudflare IP’leriyle sınırlayarak kaynak sunucunuzu doğrudan saldırılara karşı koruyun

Rust

LoadAlertTracker

Hafif sistem yükü izleme arka plan programı - Eşik değerleri aşıldığında Telegram, Discord ve Mattermost üzerinden gerçek zamanlı uyarılar

Rust

ctCertWatch

Sertifika Şeffaflığı günlüğü izleyicisi - Kimlik avı alan adlarını, marka taklitçiliğini ve yetkisiz SSL sertifikalarını gerçek zamanlı olarak tespit eder

Rust

DDNS-FW

Dinamik DNS Güvenlik Duvarı - DDNS aracılığıyla değişen IP adreslerini takip edin ve güvenli erişim kontrolü için güvenlik duvarı kurallarını otomatik olarak güncelleyin

Rust