Debian Üzerinde LXC Konteyner Ortamı Kurulumu ve Yönetimi

Konteyner teknolojileri söz konusu olduğunda aklımıza hemen Docker geliyor. Ancak Docker’dan çok önce, Linux çekirdeğinin kendi yetenekleriyle hayata geçirilmiş bir konteyner altyapısı var: LXC (Linux Containers). Özellikle Debian sunucularda LXC kullanmak, tam bir sanal makine kurmanın getirdiği yükü taşımadan izole ortamlar elde etmenizi sağlıyor. Geliştirme ortamları, test sunucuları, servis izolasyonu… Bunların hepsi için LXC gerçek anlamda işe yarayan bir çözüm.

Bu yazıda Debian üzerinde LXC kurulumundan başlayarak, konteyner oluşturma, ağ yapılandırması, kaynak yönetimi ve günlük operasyonel senaryolara kadar her şeyi ele alacağız.

LXC Nedir ve Docker’dan Farkı Nedir?

LXC, Linux çekirdeğinin cgroups ve namespace özelliklerini kullanarak işletim sistemi düzeyinde izolasyon sağlar. Docker tek bir uygulama çalıştırmak için tasarlanmışken, LXC daha çok tam bir işletim sistemi ortamı sunar. LXC konteynerinizin içine girdiğinizde kendinizi gerçek bir sisteminizde gibi hissedersiniz: kendi init süreciniz, kendi servis yöneticiniz, kendi kullanıcılarınız olur.

LXC’nin öne çıktığı durumlar:

  • Birden fazla Debian/Ubuntu/Alpine ortamı izole tutmak istiyorsanız
  • Tam VM kurmanın gereksiz olduğu hafif izolasyon senaryolarında
  • Geliştirici ortamlarını birbirinden ayırmak gerektiğinde
  • Paylaşımlı sunucularda tenant izolasyonu sağlamak için
  • Mevcut shell scriptleriyle yönetilen geleneksel ortamları konteynerize ederken

Kurulum Öncesi Hazırlık

Debian 11 (Bullseye) veya Debian 12 (Bookworm) üzerinde çalıştığınızı varsayıyorum. İlk olarak sistemin güncel olduğundan emin olun:

apt update && apt upgrade -y

Ardından çekirdeğin cgroups ve namespace desteğini kontrol edin:

grep -E "CONFIG_CGROUPS|CONFIG_NAMESPACES|CONFIG_NET_NS" /boot/config-$(uname -r)

Bu komutun çıktısında değerlerin =y olarak işaretli olması gerekiyor. Debian’ın varsayılan çekirdeği bu özelliklerin tamamını destekler, endişelenmenize gerek yok.

Gerekli Paketlerin Kurulumu

apt install -y lxc lxc-utils lxc-templates libvirt0 debootstrap bridge-utils

Kurulumun ardından LXC’nin doğru çalışıp çalışmadığını kontrol edin:

lxc-checkconfig

Bu komut çekirdek özelliklerini tek tek test eder. Çıktıda enabled yazan satırlar sorunsuz, missing veya disabled yazanlar potansiyel sorunlara işaret eder. Debian’da genellikle tüm kritik özellikler aktif gelir.

İlk Konteyneri Oluşturmak

LXC’de konteyner oluşturmak için lxc-create komutunu kullanırsınız. Şablon sistemi sayesinde farklı dağıtımları doğrudan indirebilirsiniz:

lxc-create -n web-sunucu -t download -- -d debian -r bookworm -a amd64

Buradaki parametreleri açıklayalım:

  • -n web-sunucu: Konteynere vereceğiniz isim
  • -t download: İndirme şablonunu kullan
  • -d debian: Dağıtım seçimi
  • -r bookworm: Debian sürümü (bullseye, bookworm gibi)
  • -a amd64: Mimari

Komut çalıştıktan sonra LXC gerekli dosyaları /var/lib/lxc/web-sunucu/ dizinine yerleştirir. Bu dizinin yapısına bakalım:

ls -la /var/lib/lxc/web-sunucu/
# config  rootfs

rootfs dizini konteynerin kök dosya sistemi, config ise konteyner yapılandırması.

Konteyneri Başlatmak ve İçine Girmek

# Konteyneri başlat
lxc-start -n web-sunucu

# Durumunu kontrol et
lxc-info -n web-sunucu

# Konsola bağlan
lxc-attach -n web-sunucu

lxc-attach komutu sizi doğrudan konteynerin içine alır. Artık ayrı bir Debian sistemindeymiş gibi çalışabilirsiniz. exit yazarak çıkabilirsiniz.

Ağ Yapılandırması

LXC’nin varsayılan ağ yapılandırması lxcbr0 adlı bir köprü arayüzü üzerinden NAT kullanır. Bu temel senaryolar için yeterli, ancak üretim ortamları için genellikle daha fazlasına ihtiyaç duyarsınız.

Temel Ağ Yapılandırması Kontrolü

cat /etc/lxc/default.conf

Varsayılan içerik genellikle şöyle görünür:

lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx

lxcbr0 köprüsünün aktif olup olmadığını kontrol edin:

ip addr show lxcbr0

Eğer köprü yoksa lxc-net servisini başlatın:

systemctl enable lxc-net
systemctl start lxc-net

Statik IP Atama

Birden fazla konteyner yönetirken DHCP yerine statik IP kullanmak hayatı çok kolaylaştırır. Bunun için konteynerin config dosyasını düzenleyin:

nano /var/lib/lxc/web-sunucu/config

Şu satırları ekleyin veya düzenleyin:

lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.ipv4.address = 10.0.3.100/24
lxc.net.0.ipv4.gateway = 10.0.3.1

Ardından konteyneri yeniden başlatın:

lxc-stop -n web-sunucu
lxc-start -n web-sunucu
lxc-info -n web-sunucu

Bridge Ağı ile Fiziksel Ağa Bağlanma

Konteynerlerinizin doğrudan fiziksel ağa erişmesini istiyorsanız (örneğin konteynere dışarıdan direkt erişim için), bir bridge arayüzü oluşturmanız gerekir.

/etc/network/interfaces dosyasını düzenleyin:

auto br0
iface br0 inet static
    address 192.168.1.50
    netmask 255.255.255.0
    gateway 192.168.1.1
    dns-nameservers 8.8.8.8
    bridge_ports enp3s0
    bridge_stp off
    bridge_fd 0
    bridge_maxwait 0

Sonra konteyner config dosyasında lxcbr0 yerine br0 yazın. Bu şekilde konteynerler LAN’daki diğer makineler gibi görünür hale gelir.

Kaynak Yönetimi ve Limitleme

LXC’nin en güçlü yanlarından biri cgroups üzerinden CPU, bellek ve disk I/O limitlemesi yapabilmesidir.

CPU ve Bellek Limiti

Konteyner config dosyasına şu satırları ekleyin:

nano /var/lib/lxc/web-sunucu/config
# Bellek limiti (512MB)
lxc.cgroup2.memory.max = 536870912

# CPU limiti (toplam CPU zamanının %50'si)
lxc.cgroup2.cpu.max = 50000 100000

# CPU çekirdek sayısı (2 çekirdek)
lxc.cgroup2.cpuset.cpus = 0-1

Çalışan bir konteynerde anlık olarak bellek limitini de değiştirebilirsiniz:

lxc-cgroup -n web-sunucu memory.max 268435456

Disk Kotası

LXC, doğrudan disk kotası yönetimi için zpool veya btrfs alt birimleri kullanmayı tercih eder. Ancak basit bir yaklaşım olarak loop cihaz kullanabilirsiniz:

# 10GB'lık bir imaj dosyası oluştur
dd if=/dev/zero of=/var/lib/lxc/web-sunucu-disk.img bs=1M count=10240

# Ext4 olarak formatla
mkfs.ext4 /var/lib/lxc/web-sunucu-disk.img

# Konteyner rootfs'ini buna bağla
mount -o loop /var/lib/lxc/web-sunucu-disk.img /var/lib/lxc/web-sunucu/rootfs

Unprivileged Konteynerler: Güvenli Kullanım

Şimdiye kadar anlattığım kurulum privileged modda çalışıyor, yani root yetkisiyle. Üretim ortamları için unprivileged konteynerler kullanmanız ciddi ölçüde daha güvenli bir yaklaşım.

Unprivileged konteynerlerde, konteyner içindeki root kullanıcısı aslında host sistemde düşük yetkili bir kullanıcıya eşlenir. Konteyner kırılsa bile saldırgan host sistemde normal bir kullanıcı yetkisine sahip olur.

# Normal kullanıcı olarak çalış
su - deployer

# Kullanıcı namespace haritalaması için /etc/subuid ve /etc/subgid kontrolü
grep deployer /etc/subuid
grep deployer /etc/subgid

Eğer deployer kullanıcısı için kayıt yoksa ekleyin:

usermod --add-subuids 100000-165535 deployer
usermod --add-subgids 100000-165535 deployer

Kullanıcı başına LXC yapılandırma dizini oluşturun:

mkdir -p ~/.config/lxc
cp /etc/lxc/default.conf ~/.config/lxc/default.conf

~/.config/lxc/default.conf dosyasına şu satırları ekleyin:

lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536

Artık bu kullanıcıyla unprivileged konteyner oluşturabilirsiniz:

lxc-create -n guvenli-konteyner -t download -- -d debian -r bookworm -a amd64

Snapshot ve Klonlama

Geliştirme ortamlarında sıkça karşılaşılan senaryo: “Bir şeyleri denemek istiyorum ama sistemi bozmak istemiyorum.” LXC’nin snapshot özelliği tam olarak bunun için var.

# Konteyneri durdur
lxc-stop -n web-sunucu

# Snapshot al
lxc-snapshot -n web-sunucu

# Snapshot listesi
lxc-snapshot -n web-sunucu -L

Bir şeyler ters giderse snapshot’a dönmek:

lxc-snapshot -n web-sunucu -r snap0

Konteyner Klonlama

Mevcut bir konteyneri kopyalamak istediğinizde:

lxc-copy -n web-sunucu -N web-sunucu-test

Bu komut web-sunucu konteynerinin tam kopyasını web-sunucu-test adıyla oluşturur. Yeni sunucuları hızlıca devreye almak için idealdir. Bir “altın imaj” konteyner hazırlayıp ihtiyaç duydukça klonlayabilirsiniz.

Gerçek Dünya Senaryosu: Çok Kiracılı Web Hosting

Diyelim ki küçük bir VPS’te birden fazla müşteri için web sitesi barındırıyorsunuz. Her müşterinin kendi izole ortamı olsun istiyorsunuz. İşte bu durumda kullanabileceğiniz bir yaklaşım:

#!/bin/bash
# yeni-musteri.sh

MUSTERI=$1
IP_ADRES=$2

if [ -z "$MUSTERI" ] || [ -z "$IP_ADRES" ]; then
    echo "Kullanim: $0 <musteri-adi> <ip-adresi>"
    exit 1
fi

# Konteyneri oluştur
lxc-create -n "musteri-${MUSTERI}" -t download -- -d debian -r bookworm -a amd64

# IP yapılandırmasını ekle
cat >> "/var/lib/lxc/musteri-${MUSTERI}/config" << EOF
lxc.net.0.ipv4.address = ${IP_ADRES}/24
lxc.net.0.ipv4.gateway = 10.0.3.1
lxc.cgroup2.memory.max = 536870912
lxc.cgroup2.cpu.max = 30000 100000
EOF

# Konteyneri başlat
lxc-start -n "musteri-${MUSTERI}"

# Web sunucu kurulumu
lxc-attach -n "musteri-${MUSTERI}" -- bash -c "
    apt-get update -qq
    apt-get install -y -qq nginx
    systemctl enable nginx
    systemctl start nginx
    echo 'Merhaba ${MUSTERI}!' > /var/www/html/index.html
"

echo "Musteri ${MUSTERI} icin konteyner hazir. IP: ${IP_ADRES}"

Bu scripti kullanmak için:

chmod +x yeni-musteri.sh
./yeni-musteri.sh ahmet 10.0.3.101
./yeni-musteri.sh mehmet 10.0.3.102

Konteyner İzleme ve Yönetim Komutları

Günlük operasyonlarda en çok kullanacağınız komutlar:

# Tüm konteynerleri listele
lxc-ls --fancy

# Belirli bir konteynerin detaylı bilgisi
lxc-info -n web-sunucu

# Konteyner içinde komut çalıştır (içine girmeden)
lxc-attach -n web-sunucu -- systemctl status nginx

# Konteyneri durdur
lxc-stop -n web-sunucu

# Konteyneri zorla durdur (yanıt vermiyorsa)
lxc-stop -n web-sunucu -k

# Konteyneri sil (önce durdurulmuş olmalı)
lxc-destroy -n web-sunucu

# Konsol çıktısını izle
lxc-console -n web-sunucu

lxc-ls --fancy komutu tüm konteynerlerin adını, durumunu, IP adresini ve RAM kullanımını güzel bir tablo halinde gösterir. Bunu bir alias olarak eklemek işleri hızlandırır:

echo "alias lxclist='lxc-ls --fancy'" >> ~/.bashrc
source ~/.bashrc

Otomatik Başlatma Yapılandırması

Sunucu yeniden başladığında konteynerlerin otomatik olarak ayağa kalkması için config dosyasına şu satırları ekleyin:

nano /var/lib/lxc/web-sunucu/config
lxc.start.auto = 1
lxc.start.delay = 5
lxc.start.order = 100
  • lxc.start.auto: 1 değeri konteynerin otomatik başlayacağını belirtir
  • lxc.start.delay: Bir önceki konteynerden kaç saniye bekleyeceği
  • lxc.start.order: Başlatma sırası, düşük sayı önce başlar

Systemd üzerinden LXC servisini etkinleştirmeyi de unutmayın:

systemctl enable lxc
systemctl start lxc

Yedekleme Stratejisi

Konteynerleri yedeklemek için birkaç farklı yaklaşım var. En pratik yöntem rootfs dizinini tar ile arşivlemek:

#!/bin/bash
# lxc-yedek.sh

KONTEYNER=$1
YEDEK_DIZIN="/backup/lxc"
TARIH=$(date +%Y%m%d-%H%M)

mkdir -p "${YEDEK_DIZIN}"

echo "Konteyner durduruluyor..."
lxc-stop -n "${KONTEYNER}"

echo "Yedek aliniyor..."
tar -czf "${YEDEK_DIZIN}/${KONTEYNER}-${TARIH}.tar.gz" 
    -C /var/lib/lxc "${KONTEYNER}"

echo "Konteyner yeniden baslatiliyor..."
lxc-start -n "${KONTEYNER}"

echo "Yedek tamamlandi: ${YEDEK_DIZIN}/${KONTEYNER}-${TARIH}.tar.gz"

# 7 gunden eski yedekleri sil
find "${YEDEK_DIZIN}" -name "${KONTEYNER}-*.tar.gz" -mtime +7 -delete

Yedeği geri yüklemek için:

tar -xzf /backup/lxc/web-sunucu-20240315-0200.tar.gz -C /var/lib/lxc/
lxc-start -n web-sunucu

Sık Karşılaşılan Sorunlar

Konteyner başlamıyor: Önce log dosyasına bakın:

lxc-start -n web-sunucu -l DEBUG -o /tmp/lxc-debug.log
cat /tmp/lxc-debug.log

Ağ bağlantısı yok: lxcbr0 köprüsünü kontrol edin:

systemctl restart lxc-net
brctl show lxcbr0

Cgroup2 hataları: Debian 12’de cgroup v2 varsayılan olarak gelir. Eğer eski uygulamalarla uyumluluk sorunu yaşıyorsanız:

# GRUB parametresi ekle
echo 'GRUB_CMDLINE_LINUX_DEFAULT="systemd.unified_cgroup_hierarchy=0"' >> /etc/default/grub
update-grub

Konteyner içinde DNS çalışmıyor:

lxc-attach -n web-sunucu -- bash -c "
    echo 'nameserver 8.8.8.8' > /etc/resolv.conf
    echo 'nameserver 1.1.1.1' >> /etc/resolv.conf
"

Sonuç

LXC, özellikle Debian sunucularda işletim sistemi düzeyinde izolasyon için son derece olgun ve güvenilir bir çözüm. Docker kadar popüler olmayabilir ama tam sistem ortamı gerektiren senaryolarda, az kaynak kullanan lightweight izolasyonda ve geleneksel sistem yönetimi alışkanlıklarıyla uyumlu ortamlarda gerçekten parlıyor.

Bu yazıda öğrendiklerinizle artık konteyner oluşturabilir, ağ yapılandırabilir, kaynak limitleyebilir ve yedek alabilirsiniz. Unprivileged konteynerler konusunu ciddiye alın, üretim ortamlarında mutlaka bu yolu tercih edin.

Bir sonraki adım olarak LXD’ye (LXC’nin daha modern yönetim katmanı) bakmanızı öneririm. LXD, REST API, web arayüzü ve cluster desteğiyle LXC’nin üzerine inşa edilmiş ve daha büyük ölçekli ortamlar için çok daha pratik bir deneyim sunuyor. Ancak temel LXC’yi anlamadan LXD kullanmak, temelsiz bir bina inşa etmek gibi olur.

Yorum yapın