İçeriğe geç
Docker Compose ile Mikroservis Mimarisi

Docker Compose ile Mikroservis Mimarisi

8 dk okuma DevOps

Modern yazılım geliştirme dünyasında mikroservis mimarisi, büyük ve karmaşık uygulamaları daha küçük, bağımsız ve yönetilebilir servislere ayırmak için kullanılan bir mimari yaklaşımdır. Bu yapı, ekiplerin farklı servisler üzerinde bağımsız çalışmasına, servislerin ihtiyaçlarına göre ayrı ayrı ölçeklendirilmesine ve birbirlerinden bağımsız şekilde güncellenebilmesine olanak tanır.

Docker Compose Nedir?

Docker Compose, birden fazla Docker container'ını tek bir uygulama yapısı altında tanımlamak ve yönetmek için kullanılan bir araçtır. YAML tabanlı bir yapılandırma dosyası üzerinden servisleri, ağları, volume'leri, environment variable'ları ve diğer container ayarlarını tanımlamanıza olanak tanır.

Özellikle geliştirme, test ve küçük ölçekli deployment ortamlarında birden fazla servisten oluşan uygulamaları tek bir komutla başlatmak, durdurmak ve yönetmek için oldukça kullanışlıdır.

Docker Compose'u Kubernetes gibi kapsamlı bir container orkestrasyon platformuyla karıştırmamak gerekir. Compose daha çok çoklu container uygulamalarının tanımlanması ve yönetilmesine odaklanırken, Kubernetes büyük ölçekli ve dağıtık container ortamları için daha kapsamlı orkestrasyon yetenekleri sunar.

Kurulum

Modern Docker kurulumlarında Docker Compose, docker compose komutunu sağlayan Compose Plugin olarak kullanılabilir. Ubuntu ve Debian tabanlı sistemlerde Docker'ın resmi paketleri kullanılıyorsa aşağıdaki bileşenler kurulabilir:

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

Kurulumun başarılı olduğunu kontrol etmek için:

docker compose version

Not: Docker Engine ve Docker Compose Plugin'in dağıtımın kendi depolarından veya Docker'ın resmi depolarından kurulması mümkündür. Paket isimleri ve sürümleri kullanılan Linux dağıtımına göre değişebilir.

Temel Docker Compose Yapılandırması

Aşağıdaki örnekte bir web uygulaması, PostgreSQL veritabanı ve Redis servisi birlikte tanımlanmaktadır. Güncel Compose Specification kullanıldığında version alanına ihtiyaç yoktur.

services:
  web:
    build: ./web
    ports:
      - "3000:3000"
    environment:
      DATABASE_URL: postgres://appuser:strong-password@postgres:5432/appdb
      REDIS_URL: redis://redis:6379
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy

  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: appuser
      POSTGRES_PASSWORD: strong-password
      POSTGRES_DB: appdb
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  postgres_data:

Compose tarafından oluşturulan varsayılan ağ sayesinde servisler birbirlerine servis adları üzerinden erişebilir. Örneğin web container'ı PostgreSQL'e postgres:5432, Redis'e ise redis:6379 adresleri üzerinden bağlanabilir.

ports ile yalnızca host üzerinden erişilmesi gereken servislerin portları dışarı açılmalıdır. PostgreSQL ve Redis gibi backend servislerinin portlarını gereksiz yere host'a yayınlamak yerine Compose ağı içerisinde erişilebilir bırakmak daha güvenli bir yaklaşımdır.

Servisleri Yönetme

Compose dosyasının bulunduğu dizinde tüm servisleri arka planda başlatmak için:

docker compose up -d

Çalışan container'ları görüntülemek için:

docker compose ps

Servis loglarını takip etmek için:

docker compose logs -f

Belirli bir servisin loglarını görmek için:

docker compose logs -f web

Uygulama stack'ini durdurmak için:

docker compose down

Volume'lerin de silinmesi isteniyorsa -v seçeneği kullanılabilir. Ancak bu işlem PostgreSQL gibi stateful servislerin verilerini silebileceğinden dikkatli kullanılmalıdır:

docker compose down -v

Healthcheck Kullanımı

Bir container'ın çalışıyor olması, uygulamanın gerçekten kullanılabilir olduğu anlamına gelmez. Örneğin PostgreSQL container'ı çalışıyor olabilir ancak veritabanı henüz bağlantı kabul etmeye hazır olmayabilir.

Bu nedenle kritik servislerde healthcheck tanımlamak ve servis bağımlılıklarını gerektiğinde bu healthcheck sonuçlarına göre yönetmek faydalıdır.

healthcheck:
  test: ["CMD-SHELL", "pg_isready -U appuser -d appdb"]
  interval: 10s
  timeout: 5s
  retries: 5

Burada önemli bir ayrım vardır: Docker Compose'taki depends_on, tek başına uygulamanın sağlıklı olduğunu garanti etmez. condition: service_healthy kullanıldığında Compose, bağımlı servisi başlatmadan önce ilgili healthcheck'in başarılı olmasını bekleyebilir.

Resource Limitleri

Container'ların sınırsız kaynak tüketmesini engellemek için CPU ve bellek kullanımının kontrol edilmesi önemlidir. Kullanılacak kaynak ayarları Compose sürümüne ve deployment ortamına göre değişebileceğinden, üretim ortamında kullanılan Compose implementasyonunun desteklediği alanlar kontrol edilmelidir.

Örneğin bazı Compose ortamlarında servis için CPU ve bellek limitleri tanımlanabilir:

services:
  web:
    image: my-web-app:latest
    deploy:
      resources:
        limits:
          cpus: "1.0"
          memory: 512M

deploy bölümündeki bazı özelliklerin davranışı kullanılan çalışma ortamına göre değişebilir. Bu nedenle Docker Compose ile Docker Swarm veya Kubernetes yapılandırmalarının aynı şekilde çalışacağı varsayılmamalıdır.

Environment Variable ve Secret Yönetimi

Parola, API anahtarı ve veritabanı bilgileri gibi hassas verilerin Compose dosyasına doğrudan yazılması önerilmez. Geliştirme ortamlarında .env dosyası kullanılabilir ancak bu dosyanın kaynak kod deposuna yanlışlıkla eklenmemesine dikkat edilmelidir.

services:
  postgres:
    image: postgres:15-alpine
    environment:
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
      POSTGRES_DB: ${POSTGRES_DB}

Örneğin .env dosyası:

POSTGRES_USER=appuser
POSTGRES_PASSWORD=guclu-ve-gizli-parola
POSTGRES_DB=appdb

Üretim ortamlarında hassas bilgilerin yönetimi için kullanılan deployment platformunun secret management özelliklerinden yararlanmak daha güvenli bir yaklaşımdır.

Docker Compose ile Ağ Yönetimi

Compose, varsayılan olarak aynı Compose projesindeki servisler için bir ağ oluşturur. Servisler bu ağ üzerinde birbirlerine servis isimleri üzerinden ulaşabilir.

services:
  web:
    build: ./web
    networks:
      - backend

  postgres:
    image: postgres:15-alpine
    networks:
      - backend

networks:
  backend:

Bu örnekte web servisi PostgreSQL'e postgres hostname'i üzerinden erişebilir. PostgreSQL portunun host'a açılması gerekmez.

Volume ve Veri Kalıcılığı

Container'lar geçici çalışma ortamlarıdır. Container silindiğinde container'ın kendi dosya sistemindeki veriler de kaybolabilir. PostgreSQL gibi stateful servislerde verilerin kalıcı olması için Docker volume kullanılmalıdır.

services:
  postgres:
    image: postgres:15-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Volume kullanılması tek başına yedekleme anlamına gelmez. Üretim ortamlarında veritabanı için ayrıca düzenli backup, restore testi ve uygun bir disaster recovery planı oluşturulmalıdır.

Log Yönetimi

Birden fazla servisten oluşan uygulamalarda logların merkezi şekilde toplanması hata ayıklama ve gözlemlenebilirlik açısından önemlidir.

Geliştirme ortamlarında Compose logları doğrudan takip edilebilir:

docker compose logs -f

Üretim ortamlarında ise uygulamanın gereksinimlerine göre merkezi loglama çözümleri, log driver'ları veya harici gözlemlenebilirlik platformları kullanılabilir.

En İyi Uygulamalar

  • Her servis için uygun healthcheck tanımlayın.

  • Container'ların CPU ve bellek tüketimini kontrol altında tutun.

  • Parola ve API anahtarı gibi hassas bilgileri Compose dosyasına doğrudan yazmayın.

  • Backend servislerinin portlarını gereksiz yere host'a açmayın.

  • Stateful servisler için Docker volume kullanın.

  • Volume kullanmanın yedekleme yerine geçmediğini unutmayın ve düzenli backup alın.

  • Logları merkezi olarak toplayarak uygulamanın gözlemlenebilirliğini artırın.

  • Production ortamında kullanılan image sürümlerini kontrollü şekilde yönetin ve mümkün olduğunca doğrulanabilir sürümler kullanın.

  • Compose dosyasını kaynak kodla birlikte versiyon kontrolünde tutun ancak secret içeren dosyaları repository'ye eklemeyin.

  • Servisler arasındaki bağımlılıkları depends_on ile açıkça tanımlayın; uygulama seviyesinde de bağlantı hatalarına karşı retry mekanizmaları kullanın.

Sonuç

Docker Compose, birden fazla container'dan oluşan uygulamaları tanımlamak ve yönetmek için pratik ve güçlü bir araçtır. Tek bir YAML dosyası üzerinden servisleri, ağları, volume'leri ve çalışma yapılandırmalarını yönetebilmek özellikle geliştirme, test ve küçük ölçekli deployment süreçlerini önemli ölçüde kolaylaştırır.

Mikroservis mimarisinde Docker Compose kullanırken yalnızca container'ları çalıştırmak yerine healthcheck, kaynak yönetimi, secret yönetimi, ağ izolasyonu, kalıcı veri ve loglama gibi konuların da birlikte ele alınması gerekir. Uygulama büyüdükçe ve orkestrasyon ihtiyaçları arttıkça Kubernetes gibi daha kapsamlı platformlara geçiş değerlendirilebilir.