Azure Container Registry Yönetimi: Kapsamlı Rehber

Konteyner tabanlı uygulama geliştirme ve dağıtım süreçlerinde en kritik bileşenlerden biri, Docker image’larını güvenli ve merkezi bir şekilde saklamaktır. Azure Container Registry (ACR), Microsoft’un bu ihtiyaca verdiği yanıttır ve özellikle Azure ekosistemi içinde çalışıyorsanız neredeyse kaçınılmaz bir tercih haline gelir. Bu yazıda ACR’yi sıfırdan kurmaktan, güvenlik yapılandırmasına, image yönetiminden otomatik temizleme politikalarına kadar gerçek dünya senaryolarıyla tüm kritik konuları ele alacağız.

Azure Container Registry Nedir ve Neden Kullanmalısınız?

ACR, özel Docker ve OCI uyumlu image’larınızı Azure üzerinde barındırmanızı sağlayan, tam yönetilen bir konteyner kayıt defteri hizmetidir. Docker Hub’ın aksine, ACR kurumsal kullanım için tasarlanmış erişim kontrolü, coğrafi replikasyon, güvenlik taraması ve Azure servislerle derin entegrasyon sunar.

Özellikle şu senaryolarda ACR kullanmak neredeyse zorunlu hale gelir:

  • AKS (Azure Kubernetes Service) üzerinde uygulama çalıştırıyorsanız
  • Kurumsal uyum gereksinimleri nedeniyle image’larınızın kendi kontrolünüzde olması gerekiyorsa
  • CI/CD pipeline’larınız Azure DevOps veya GitHub Actions üzerindeyse
  • Farklı coğrafi bölgelerde düşük latency ile image çekmek istiyorsanız
  • Image’larınızda güvenlik açığı taraması yapmak istiyorsanız

ACR üç farklı SKU ile gelir: Basic, Standard ve Premium. Çoğu production ortamı için Standard veya Premium tercih edin. Premium, geo-replikasyon ve özel endpoint desteği gibi kurumsal özellikleri barındırır.

ACR Oluşturma ve Temel Yapılandırma

Öncelikle Azure CLI’ın kurulu ve oturum açılmış olduğundan emin olun. Resource group ve registry oluşturmakla başlayalım.

# Azure'a giriş yap
az login

# Resource group oluştur
az group create 
  --name rg-container-prod 
  --location westeurope

# ACR oluştur (Standard SKU ile)
az acr create 
  --resource-group rg-container-prod 
  --name mycompanyregistry 
  --sku Standard 
  --admin-enabled false 
  --location westeurope

# Registry bilgilerini görüntüle
az acr show 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --output table

Registry adının globally unique olması gerektiğini unutmayın. mycompanyregistry.azurecr.io formatında bir login server URL’si otomatik oluşturulur.

–admin-enabled false seçeneğine dikkat edin. Admin account’u açık bırakmak, paylaşılan tek bir kullanıcı adı/şifre kombinasyonu oluşturur ve bu production ortamlarında ciddi bir güvenlik riski taşır. Bunun yerine service principal veya managed identity kullanın.

Registry’ye İlk Image Push İşlemi

Local’de build ettiğiniz bir image’ı ACR’ye göndermek için önce authenticate olmanız gerekir.

# ACR'ye login ol
az acr login --name mycompanyregistry

# Mevcut bir image'ı tag'le
docker tag myapp:latest mycompanyregistry.azurecr.io/myapp:latest
docker tag myapp:latest mycompanyregistry.azurecr.io/myapp:v1.2.3

# Image'ı push et
docker push mycompanyregistry.azurecr.io/myapp:latest
docker push mycompanyregistry.azurecr.io/myapp:v1.2.3

# Registry'deki repository'leri listele
az acr repository list 
  --name mycompanyregistry 
  --output table

# Belirli bir repository'nin tag'lerini gör
az acr repository show-tags 
  --name mycompanyregistry 
  --repository myapp 
  --orderby time_desc 
  --output table

Erişim Kontrolü ve Kimlik Doğrulama

ACR’nin güvenliğini sağlamanın en iyi yolu, Azure RBAC ile service principal veya managed identity kullanmaktır. Şimdi farklı senaryolar için nasıl yapılandırma yapacağımıza bakalım.

Service Principal ile Erişim

CI/CD pipeline’ları veya dış sistemler için service principal ile erişim en yaygın yöntemdir.

# Service principal oluştur ve ACR'ye pull yetkisi ver
ACR_ID=$(az acr show 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --query id 
  --output tsv)

# Pull işlemi için service principal (CI/CD deploy için)
az ad sp create-for-rbac 
  --name sp-acr-pull 
  --role AcrPull 
  --scopes $ACR_ID 
  --output json

# Push işlemi için ayrı service principal (build pipeline için)
az ad sp create-for-rbac 
  --name sp-acr-push 
  --role AcrPush 
  --scopes $ACR_ID 
  --output json

Bu komutlar appId ve password döndürür. Bunları güvenli bir secrets manager’da saklayın, asla kod içine yazmayın.

AcrPull: Sadece image çekme yetkisi verir AcrPush: Image çekme ve push etme yetkisi verir AcrDelete: Image silme yetkisi verir Owner/Contributor: Tam yönetim yetkisi verir

AKS ile Managed Identity Entegrasyonu

AKS cluster’ınızın ACR’den image çekebilmesi için en temiz yol managed identity kullanmaktır.

# AKS cluster'ına ACR pull yetkisi ver
az aks update 
  --name myaks-cluster 
  --resource-group rg-container-prod 
  --attach-acr mycompanyregistry

# Mevcut yetkilendirmeyi doğrula
az aks check-acr 
  --name myaks-cluster 
  --resource-group rg-container-prod 
  --acr mycompanyregistry.azurecr.io

Bu sayede Kubernetes pod’larınız herhangi bir ImagePullSecret tanımlamanıza gerek kalmadan ACR’den image çekebilir. Bu, hem operasyonel yükü azaltır hem de şifre rotasyonu sorunlarını ortadan kaldırır.

ACR Tasks ile Otomatik Build

ACR’nin güçlü özelliklerinden biri, cloud üzerinde doğrudan image build edebilme yeteneğidir. Local Docker daemon gerektirmeden GitHub veya Azure Repos’ta kod değişikliği olduğunda otomatik build tetikleyebilirsiniz.

# Hızlı build: Local Dockerfile'dan direkt ACR'ye build et
az acr build 
  --registry mycompanyregistry 
  --image myapp:v1.2.4 
  --file Dockerfile 
  .

# Zamanlanmış görev oluştur (her gece base image güncelle)
az acr task create 
  --registry mycompanyregistry 
  --name scheduled-base-update 
  --image baseimages/node:18-alpine 
  --schedule "0 2 * * *" 
  --context /dev/null 
  --cmd "mcr.microsoft.com/acr/acrtasks:acr-task" 
  --file base-update.yaml

# GitHub commit'te otomatik build tetikle
az acr task create 
  --registry mycompanyregistry 
  --name build-on-commit 
  --image myapp:{{.Run.ID}} 
  --context https://github.com/myorg/myapp.git 
  --file Dockerfile 
  --git-access-token $GITHUB_PAT

# Mevcut task'ları listele
az acr task list 
  --registry mycompanyregistry 
  --output table

# Task çalıştırma geçmişini gör
az acr task list-runs 
  --registry mycompanyregistry 
  --task build-on-commit 
  --output table

ACR Tasks özellikle base image güncellemelerini otomatize etmek için kullanışlıdır. Mesela resmi node:18-alpine image’ı güncellendiğinde, buna bağlı tüm uygulama image’larınızı otomatik yeniden build edebilirsiniz. Bu, güvenlik yamalarının uygulamalarınıza hızla yayılması için kritik bir mekanizmadır.

Image Güvenlik Taraması

ACR, Microsoft Defender for Containers ile entegre çalışarak image’larınızdaki güvenlik açıklarını tespit edebilir. Bu özelliği etkinleştirmek için Azure Defender planını aktifleştirmeniz gerekir.

# Defender for Containers'ı etkinleştir
az security pricing create 
  --name Containers 
  --tier Standard

# Manuel güvenlik taraması başlat
az acr run 
  --registry mycompanyregistry 
  --cmd "mcr.microsoft.com/azuredefender/stable/acrscanner:latest 
         scan --registry mycompanyregistry.azurecr.io 
         --image myapp:latest" 
  /dev/null

# Tarama sonuçlarını görüntüle (Azure Security Center CLI üzerinden)
az security alert list 
  --location westeurope 
  --query "[?contains(name, 'Registry')]" 
  --output table

Gerçek dünyada gördüğüm en yaygın hatalardan biri, güvenlik taramasının sonuçlarını görmezden gelmek veya yalnızca kritik seviyedeki açıklara odaklanmaktır. Prod’a giden her image için en azından High ve Critical seviyesindeki açıkların kapatılmış olması gerektiğini ekibinizle politika olarak belirleyin.

Image Yaşam Döngüsü Yönetimi ve Retention Politikaları

Zamanla ACR’nizdeki image sayısı kontrolsüz şekilde büyüyebilir. Bu hem depolama maliyetini artırır hem de yönetimi zorlaştırır. ACR’nin retention policy ve purge özellikleri bu sorunu çözmenizi sağlar.

# 30 günden eski ve hiçbir manifest'e referans edilmeyen image'ları temizle
az acr run 
  --registry mycompanyregistry 
  --cmd "acr purge 
    --filter 'myapp:.*' 
    --untagged 
    --ago 30d" 
  /dev/null

# Belirli bir pattern dışındaki tüm eski tag'leri temizle
# v ile başlayan semantic versioning tag'lerini koru, diğerlerini sil
az acr run 
  --registry mycompanyregistry 
  --cmd "acr purge 
    --filter 'myapp:[0-9a-f]{7}' 
    --keep 20 
    --ago 14d" 
  /dev/null

# Zamanlanmış temizleme görevi oluştur
az acr task create 
  --name cleanup-old-images 
  --registry mycompanyregistry 
  --schedule "0 1 * * 0" 
  --cmd "acr purge 
    --filter 'myapp:.*' 
    --keep 10 
    --ago 30d 
    --untagged" 
  --context /dev/null

# Standard SKU için retention policy ayarla (untagged manifest'ler için)
az acr config retention update 
  --registry mycompanyregistry 
  --status Enabled 
  --days 15 
  --type UntaggedManifests

–keep 10 parametresi: Tag filtresiyle eşleşen en son 10 image’ı korur, geri kalanları siler –ago 30d: 30 günden eski image’ları hedefler –untagged: Tag’siz manifest’leri de temizler

Retention politikasını oluştururken şu stratejiyi öneririm: Semantic versioning (v1.2.3 formatı) ile etiketlenen image’ları asla otomatik silmeyin. Bunlar release artifact’ları olarak kalıcı saklanmalıdır. Ancak feature branch’lerden gelen commit hash ile etiketlenmiş image’ları 14-30 gün sonra temizlemek hem maliyet hem de yönetim açısından mantıklıdır.

Geo-Replikasyon Yapılandırması

Birden fazla coğrafi bölgede hizmet veriyorsanız, image pull latency’sini azaltmak için ACR Premium SKU ile geo-replikasyon kullanabilirsiniz.

# Premium SKU'ya yükselt
az acr update 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --sku Premium

# East US bölgesine replikasyon ekle
az acr replication create 
  --registry mycompanyregistry 
  --location eastus 
  --resource-group rg-container-prod

# Southeast Asia bölgesine replikasyon ekle
az acr replication create 
  --registry mycompanyregistry 
  --location southeastasia 
  --resource-group rg-container-prod

# Replikasyon durumlarını kontrol et
az acr replication list 
  --registry mycompanyregistry 
  --resource-group rg-container-prod 
  --output table

Geo-replikasyon aktif olduğunda, image push işlemlerinden sonra tüm bölgelere sync tamamlanana kadar birkaç dakika bekleyebilirsiniz. CI/CD pipeline’larınızda bunu hesaba katın, özellikle global deployment senaryolarında push sonrası bir bekleme mekanizması ekleyin.

Private Endpoint ile Ağ Güvenliği

Kurumsal ortamlarda ACR’ye yalnızca sanal ağ içinden erişilmesi sık karşılaşılan bir gereksinimdir. Private endpoint bu ihtiyacı karşılar.

# Private endpoint için DNS zone oluştur
az network private-dns zone create 
  --resource-group rg-container-prod 
  --name "privatelink.azurecr.io"

# VNet ile DNS zone'u bağla
az network private-dns link vnet create 
  --resource-group rg-container-prod 
  --zone-name "privatelink.azurecr.io" 
  --name acr-dns-link 
  --virtual-network myVNet 
  --registration-enabled false

# Private endpoint oluştur
ACR_ID=$(az acr show 
  --name mycompanyregistry 
  --query id 
  --output tsv)

az network private-endpoint create 
  --resource-group rg-container-prod 
  --name pe-mycompanyregistry 
  --vnet-name myVNet 
  --subnet private-endpoints-subnet 
  --private-connection-resource-id $ACR_ID 
  --group-id registry 
  --connection-name acr-private-connection

# Public ağ erişimini kapat
az acr update 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --public-network-enabled false

Public erişimi kapattıktan sonra sadece private endpoint üzerinden erişilebilir hale gelir. Bu noktada ACR Tasks gibi bazı özelliklerin çalışması için dedicated agent pool oluşturmanız gerekebilir.

Webhook ile Otomatik Deployment Tetikleme

Image push olduğunda downstream sistemleri otomatik haberdar etmek için webhook kullanabilirsiniz.

# Push event'inde webhook tetikle
az acr webhook create 
  --registry mycompanyregistry 
  --resource-group rg-container-prod 
  --name deploy-on-push 
  --uri https://myapp-webhook.azurewebsites.net/api/deploy 
  --actions push 
  --scope myapp:production

# Webhook'u test et
az acr webhook ping 
  --registry mycompanyregistry 
  --name deploy-on-push

# Son webhook event'lerini gör
az acr webhook list-events 
  --registry mycompanyregistry 
  --name deploy-on-push 
  --output table

–scope myapp:production parametresiyle webhook’u yalnızca belirli repository ve tag kombinasyonuna kısıtlayabilirsiniz. Bu sayede her push işlemi webhook’u tetiklemez, yalnızca production tag’i ile yapılan push’lar tetikler.

Maliyet Optimizasyonu için İzleme ve Raporlama

ACR maliyetlerinin büyük bölümü depolama kullanımından kaynaklanır. Ne kadar yer kullandığınızı takip etmek ve optimize etmek önemlidir.

# Registry storage kullanımını kontrol et
az acr show-usage 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --output table

# Belirli bir repository'nin boyutunu hesapla
az acr manifest list-metadata 
  --registry mycompanyregistry 
  --name myapp 
  --output table

# En büyük image'ları bul
az acr repository list 
  --name mycompanyregistry 
  --output tsv | while read repo; do
  echo "=== $repo ==="
  az acr repository show 
    --name mycompanyregistry 
    --repository $repo 
    --query "{size:imageSize, tags:tagsCount}" 
    --output table
done

# Orphaned (tag'siz) manifest sayısını gör
az acr manifest list-metadata 
  --registry mycompanyregistry 
  --name myapp 
  --query "[?tags==null]" 
  --output table | wc -l

Gerçek bir senaryoda karşılaştığım durumu paylaşayım: Bir müşterinin ACR faturası beklenmedik şekilde yükselmişti. İnceleyince her CI/CD çalışmasının yeni bir image push ettiğini ve eski olanların hiç temizlenmediğini gördük. Altı aylık biriken image’lar yaklaşık 800 GB depolama kaplamıştı. Yukarıdaki cleanup script’lerini zamanlanmış task olarak kurduktan sonra depolama kullanımı 80 GB’ın altına indi ve aylık maliyet önemli ölçüde azaldı.

ACR Import ile Dış Registry’den Image Aktarımı

Bazen Docker Hub veya başka registry’lerden image’ları ACR’nize aktarmanız gerekir. Özellikle internet erişimi kısıtlı ortamlarda bu kritik bir ihtiyaçtır.

# Docker Hub'dan public image'ı ACR'ye import et
az acr import 
  --name mycompanyregistry 
  --source docker.io/library/nginx:1.25.3 
  --image base-images/nginx:1.25.3

# Microsoft Container Registry'den import et
az acr import 
  --name mycompanyregistry 
  --source mcr.microsoft.com/dotnet/aspnet:8.0 
  --image base-images/dotnet-aspnet:8.0

# Başka bir ACR'den import et (authenticated)
az acr import 
  --name mycompanyregistry 
  --source sourceregistry.azurecr.io/myapp:v2.0 
  --image myapp:v2.0 
  --username $SOURCE_SP_ID 
  --password $SOURCE_SP_SECRET

ACR Import özelliği, image’ı local’e pull edip tekrar push etmek yerine cloud-to-cloud transfer yaparak hem hızlı hem de bandwidth tasarruflu bir yöntem sunar.

Diagnostic Log ve Monitoring

Production ortamında ACR aktivitelerini izlemek için Log Analytics entegrasyonu kurun.

# Log Analytics workspace oluştur (yoksa)
az monitor log-analytics workspace create 
  --resource-group rg-container-prod 
  --workspace-name law-container-prod 
  --location westeurope

WORKSPACE_ID=$(az monitor log-analytics workspace show 
  --resource-group rg-container-prod 
  --workspace-name law-container-prod 
  --query id 
  --output tsv)

ACR_ID=$(az acr show 
  --name mycompanyregistry 
  --resource-group rg-container-prod 
  --query id 
  --output tsv)

# ACR diagnostic settings'i etkinleştir
az monitor diagnostic-settings create 
  --resource $ACR_ID 
  --name acr-diagnostics 
  --workspace $WORKSPACE_ID 
  --logs '[
    {"category": "ContainerRegistryRepositoryEvents", "enabled": true},
    {"category": "ContainerRegistryLoginEvents", "enabled": true}
  ]' 
  --metrics '[{"category": "AllMetrics", "enabled": true}]'

Log Analytics’e akan verilerle başarısız login denemelerini, en çok pull yapılan image’ları ve anormal aktiviteleri takip edebilirsiniz. Özellikle başarısız authentication girişimlerini izleyen bir alert kurmak güvenlik açısından önerilir.

Sonuç

Azure Container Registry, surface alanı geniş ve detaylarında boğulmak kolay bir servistir. Ancak temel prensipleri anladıktan sonra son derece güvenilir ve entegre bir platform olarak çalışır.

En kritik noktaları özetlemek gerekirse: Admin account’u kapalı tutun ve her zaman RBAC tabanlı erişim kullanın. Image temizleme politikalarını baştan kurun, sonradan temizlemek çok daha zahmetlidir. CI/CD pipeline’larınız için ayrı service principal’lar oluşturun ve least privilege prensibini uygulayın. Geo-replikasyon ve private endpoint gibi premium özellikler gerçekten fark yaratır, maliyet-fayda analizini yapın.

Kurumsal ortamlarda ACR yönetiminin sadece teknik konfigürasyonla bitmediğini de vurgulamak isterim. Image isimlendirme konvansiyonları, tag stratejileri, retention politikaları ve güvenlik tarama süreçlerini ekibinizle birlikte yazılı hale getirin. İyi tanımlanmış operasyonel süreçler olmadan en iyi kurulmuş teknik altyapı bile zamanla kaotik hale gelir.

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir