Cloud-Init ile Proxmox Üzerinde Otomatik Sanal Makine Hazırlama

Proxmox ortamında onlarca sanal makine kuruyorsanız ve her seferinde aynı işlemleri tek tek yapıyorsanız, bu yazı tam size göre. Cloud-Init, bulut ortamlarında yıllardır kullanılan bir araç olsa da on-premise Proxmox kurulumlarında da son derece etkili biçimde kullanılabiliyor. Bir kez şablon hazırlayıp sonrasında dakikalar içinde, tamamen yapılandırılmış sanal makineler oluşturabiliyorsunuz. Haydi başlayalım.

Cloud-Init Nedir ve Neden Önemli?

Cloud-Init, sanal makinelerin ilk açılışında otomatik yapılandırma yapmasını sağlayan bir araçtır. Hostname ayarlamak, kullanıcı oluşturmak, SSH anahtarı yerleştirmek, ağ yapılandırması yapmak, paket yüklemek gibi işlemleri VM açılır açılmaz gerçekleştirir. AWS, Azure, GCP gibi büyük bulut sağlayıcılarının tamamı bu aracı kullanır.

Proxmox tarafında ise Cloud-Init entegrasyonu oldukça olgunlaşmış durumda. Proxmox, Cloud-Init yapılandırmasını bir ISO imajı olarak sanal makineye bağlar ve VM açıldığında Cloud-Init bu imajdaki verileri okuyarak kendini yapılandırır. Bu sayede:

  • Her VM için ayrı ayrı konsola bağlanıp kurulum yapmanıza gerek kalmaz
  • Terraform veya Ansible gibi araçlarla entegrasyon kolaylaşır
  • Standart, tutarlı VM’ler elde edersiniz
  • Hata oranı dramatik biçimde düşer

Gereksinimler

Başlamadan önce şunların hazır olması gerekiyor:

  • Proxmox VE 7.x veya 8.x kurulu bir sunucu
  • Cloud-Init destekli bir işletim sistemi imajı (Ubuntu Cloud, Debian Cloud, CentOS Stream gibi)
  • Proxmox sunucusuna SSH veya konsol erişimi
  • Temel Linux bilgisi

Cloud-Init destekli imajlar genellikle “cloud” veya “cloudimg” eki ile gelir. Ubuntu için ubuntu-22.04-server-cloudimg-amd64.img, Debian için debian-12-genericcloud-amd64.qcow2 gibi.

Adım Adım Cloud-Init Şablonu Oluşturma

İmajı İndirme

Proxmox sunucunuza SSH ile bağlanın ve çalışmak istediğiniz dizine geçin:

cd /var/lib/vz/template/iso/

# Ubuntu 22.04 Cloud imajı indir
wget https://cloud-images.ubuntu.com/jammy/current/jammy-server-cloudimg-amd64.img

# Debian 12 Cloud imajı indir
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2

İmajı indirdikten sonra boyutunu ve formatını doğrulamak iyi bir alışkanlık:

qemu-img info jammy-server-cloudimg-amd64.img

Bu komut çıktısında file format: qcow2 veya file format: raw gibi bilgileri göreceksiniz. İmaj formatı ne olursa olsun Proxmox ile kullanabilirsiniz.

Temel VM Oluşturma

Şimdi bu imajı temel alacak bir VM oluşturuyoruz. Bu VM, daha sonra şablona dönüştüreceğimiz iskelet yapıdır:

# VM ID olarak 9000 kullanıyoruz (şablonlar için yüksek ID'ler tercih edilir)
qm create 9000 
  --name "ubuntu-2204-cloudinit-template" 
  --memory 2048 
  --cores 2 
  --net0 virtio,bridge=vmbr0 
  --ostype l26 
  --agent enabled=1 
  --serial0 socket 
  --vga serial0

# İndirdiğimiz imajı disk olarak içe aktarıyoruz
# "local-lvm" yerine kendi storage adınızı yazın
qm importdisk 9000 jammy-server-cloudimg-amd64.img local-lvm

# İçe aktarılan diski VM'e bağlıyoruz
qm set 9000 --scsihw virtio-scsi-pci --scsi0 local-lvm:vm-9000-disk-0

# Boot diskini belirliyoruz
qm set 9000 --boot c --bootdisk scsi0

# Cloud-Init sürücüsü için bir IDE disk ekliyoruz
qm set 9000 --ide2 local-lvm:cloudinit

# Disk boyutunu isteğimize göre genişletiyoruz (opsiyonel, 20GB'a çıkaralım)
qm resize 9000 scsi0 20G

Cloud-Init Parametrelerini Ayarlama

Şimdi Cloud-Init ayarlarını yapıyoruz. Bu ayarlar şablona gömülü olacak ve her yeni VM oluşturduğunuzda başlangıç noktası olarak kullanılacak:

# Varsayılan kullanıcı adı ve SSH anahtarı ayarlama
qm set 9000 
  --ciuser ubuntu 
  --sshkeys ~/.ssh/id_rsa.pub 
  --ipconfig0 ip=dhcp 
  --nameserver 8.8.8.8 
  --searchdomain local.domain

# Opsiyonel: Şifreyle de giriş istiyorsanız (tavsiye edilmez ama test için kullanışlı)
qm set 9000 --cipassword "GucluBirSifre123!"

Şablona Dönüştürme

VM hazır olduğunda şablona dönüştürüyoruz. Bu işlemden sonra VM’i doğrudan başlatamazsınız, sadece klonlayabilirsiniz:

qm template 9000

İşte bu kadar. Artık elimizde kullanıma hazır bir Cloud-Init şablonu var.

Şablondan Yeni VM Oluşturma

Şablon hazır olduğunda yeni VM oluşturmak birkaç satır komuttan ibaret:

# Şablonu klonlayarak yeni VM oluştur
qm clone 9000 101 
  --name "web-sunucu-01" 
  --full 
  --storage local-lvm

# Yeni VM'e özgü Cloud-Init ayarları yap
qm set 101 
  --ipconfig0 ip=192.168.1.101/24,gw=192.168.1.1 
  --nameserver 192.168.1.1 
  --ciuser webadmin 
  --sshkeys ~/.ssh/production_key.pub

# VM'i başlat
qm start 101

VM başladıktan sonra 30-60 saniye içinde Cloud-Init işlemlerini tamamlar ve SSH ile bağlanabilir hale gelir. İlk açılışta hostname, SSH anahtarları, ağ yapılandırması ve paket güncellemeleri otomatik olarak yapılır.

Gelişmiş Cloud-Init Yapılandırması: User-Data

Cloud-Init’in gerçek gücü user-data yapılandırmasında gizlidir. Proxmox GUI’sinden veya komut satırından özel user-data dosyası tanımlayabilirsiniz. Bu sayede ilk açılışta çok daha karmaşık işlemleri otomatikleştirebilirsiniz.

Önce bir user-data dosyası oluşturalım:

#cloud-config
# /var/lib/vz/snippets/webserver-userdata.yaml

hostname: web-sunucu-01
fqdn: web-sunucu-01.sirket.local
manage_etc_hosts: true

users:
  - name: sysadmin
    groups: sudo
    shell: /bin/bash
    sudo: ['ALL=(ALL) NOPASSWD:ALL']
    ssh_authorized_keys:
      - ssh-rsa AAAAB3NzaC1yc2EAAAADAQAB... sysadmin@yonetim

package_update: true
package_upgrade: true

packages:
  - nginx
  - curl
  - htop
  - qemu-guest-agent
  - fail2ban

runcmd:
  - systemctl enable nginx
  - systemctl start nginx
  - systemctl enable qemu-guest-agent
  - systemctl start qemu-guest-agent
  - timedatectl set-timezone Europe/Istanbul
  - echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
  - sysctl -p

write_files:
  - path: /etc/nginx/sites-available/default
    content: |
      server {
        listen 80 default_server;
        root /var/www/html;
        index index.html;
        server_name _;
        location / {
          try_files $uri $uri/ =404;
        }
      }
    permissions: '0644'

final_message: "Sistem hazir! $UPTIME saniyede yapilandirildi."

Bu dosyayı Proxmox’un snippet alanına kaydedin:

# Snippet dizini yoksa oluştur
mkdir -p /var/lib/vz/snippets

# Dosyayı kaydet
nano /var/lib/vz/snippets/webserver-userdata.yaml

# Storage'da snippets'i etkinleştir (eğer local storage kullanıyorsanız)
pvesm set local --content vztmpl,iso,snippets,backup,images

# VM'e user-data bağla
qm set 101 --cicustom "user=local:snippets/webserver-userdata.yaml"

Gerçek Dünya Senaryosu: 10 VM’lik Web Kümesi

Diyelim ki bir web uygulaması için 10 adet identik uygulama sunucusu hazırlamanız gerekiyor. Bunu bash scripti ile otomatikleştirelim:

#!/bin/bash
# deploy-web-cluster.sh
# Kullanım: ./deploy-web-cluster.sh 10

TEMPLATE_ID=9000
BASE_ID=200
COUNT=${1:-5}
STORAGE="local-lvm"
NETWORK_BASE="192.168.10"
GATEWAY="192.168.10.1"
SSH_KEY_FILE="/root/.ssh/production.pub"

echo "=== Web Kümesi Kurulumu Basliyor ==="
echo "Olusturulacak VM sayisi: $COUNT"

for i in $(seq 1 $COUNT); do
  VM_ID=$((BASE_ID + i))
  VM_NAME="web-node-$(printf '%02d' $i)"
  VM_IP="${NETWORK_BASE}.$((100 + i))/24"

  echo "[*] Olusturuluyor: $VM_NAME (ID: $VM_ID, IP: $VM_IP)"

  # Şablondan klonla
  qm clone $TEMPLATE_ID $VM_ID 
    --name "$VM_NAME" 
    --full 
    --storage $STORAGE

  # Cloud-Init ayarlarını yap
  qm set $VM_ID 
    --ipconfig0 ip=$VM_IP,gw=$GATEWAY 
    --nameserver 192.168.10.1 
    --ciuser webadmin 
    --sshkeys $SSH_KEY_FILE 
    --cicustom "user=local:snippets/webserver-userdata.yaml"

  # CPU ve RAM ayarla
  qm set $VM_ID --cores 4 --memory 4096

  # VM'i başlat
  qm start $VM_ID

  echo "[+] $VM_NAME baslatildi"
  sleep 2
done

echo "=== Tum VM'ler olusturuldu ve baslatildi ==="
echo "SSH baglantilarini test etmek icin 60 saniye bekleyin"

Bu script çalıştırıldığında 10 VM otomatik olarak oluşturulur, yapılandırılır ve başlatılır. Elle yapıldığında saatler alacak bir işlem 5-10 dakikaya iner.

Terraform ile Cloud-Init Entegrasyonu

Proxmox’u Terraform ile yönetiyorsanız Cloud-Init ile mükemmel bir kombinasyon elde edersiniz. telmate/proxmox provider’ı kullanarak şöyle bir yapı kurabilirsiniz:

# main.tf
terraform {
  required_providers {
    proxmox = {
      source  = "telmate/proxmox"
      version = ">=2.9.0"
    }
  }
}

provider "proxmox" {
  pm_api_url      = "https://proxmox.sirket.local:8006/api2/json"
  pm_user         = "terraform@pve"
  pm_password     = var.proxmox_password
  pm_tls_insecure = false
}

resource "proxmox_vm_qemu" "web_server" {
  count       = var.web_server_count
  name        = "web-${format("%02d", count.index + 1)}"
  target_node = "proxmox01"
  clone       = "ubuntu-2204-cloudinit-template"
  full_clone  = true

  cores   = 4
  sockets = 1
  memory  = 4096
  agent   = 1

  disk {
    slot    = 0
    size    = "30G"
    type    = "scsi"
    storage = "local-lvm"
  }

  network {
    model  = "virtio"
    bridge = "vmbr0"
  }

  os_type = "cloud-init"

  ipconfig0  = "ip=192.168.10.${100 + count.index + 1}/24,gw=192.168.10.1"
  nameserver = "192.168.10.1"
  ciuser     = "webadmin"
  sshkeys    = file("~/.ssh/production.pub")

  lifecycle {
    ignore_changes = [
      network,
    ]
  }
}

Cloud-Init Sorun Giderme

Cloud-Init bazen beklendiği gibi çalışmayabilir. İşte en sık karşılaşılan sorunlar ve çözümleri:

Cloud-Init log dosyalarını kontrol etme:

# VM içinde (SSH veya konsol ile bağlandıktan sonra)
sudo cat /var/log/cloud-init.log
sudo cat /var/log/cloud-init-output.log

# Cloud-Init durumunu kontrol et
cloud-init status --long

# Yapılandırmanın doğru parse edilip edilmediğini kontrol et
sudo cloud-init schema --config-file /etc/cloud/cloud.cfg

Cloud-Init’i sıfırlama (şablon hazırlarken önemli):

Şablona dönüştürmeden önce Cloud-Init’i temizlemek gerekir. Aksi halde her klonlanan VM eski instance ID’yi taşır ve Cloud-Init çalışmaz:

# VM içinde çalıştırın, ŞABLONU KAPATMADENBeklemeyin
sudo cloud-init clean --logs
sudo cloud-init clean --seed
sudo rm -rf /var/lib/cloud/

# Makineyi kapat (KAPATMAK ÖNEMLI, reboot değil)
sudo poweroff

Makine kapandıktan sonra Proxmox’ta şablona dönüştürme işlemini yapın.

Ağ yapılandırması uygulanmıyor:

Bazen NetworkManager ve Cloud-Init arasında çakışma olabilir. Ubuntu 22.04’te şu sorunu sık görürüz:

# VM içinde sorun giderme
sudo systemctl status systemd-networkd
sudo networkctl status
sudo cloud-init status

# Ağ yapılandırma dosyasını kontrol et
cat /etc/netplan/50-cloud-init.yaml

# Netplan uygula
sudo netplan apply

Proxmox GUI Üzerinden Cloud-Init Yönetimi

Komut satırı sevmeyenler için Proxmox GUI de oldukça kullanışlı. VM oluşturduktan sonra:

  • Sol panelde VM’i seçin
  • Hardware sekmesinden Cloud-Init diski eklenip eklenmediğini kontrol edin
  • Cloud-Init sekmesine geçin
  • Buradan User, Password, SSH Public Key, DNS domain, DNS servers ve IP Configuration alanlarını doldurun
  • Regenerate Image butonuna tıklayın

GUI’den yapılan değişiklikler hemen etkili olmaz. VM’i yeniden başlatmanız veya Cloud-Init’i tetikleyen bir değişiklik yapmanız gerekir.

Güvenlik Önerileri

Cloud-Init kullanırken güvenlik açısından dikkat edilmesi gereken birkaç önemli nokta:

  • Şifre yerine SSH anahtarı kullanın: cipassword parametresini mümkün olduğunca kullanmayın, özellikle üretim ortamlarında. SSH anahtarı tabanlı kimlik doğrulama çok daha güvenlidir.
  • Root girişini devre dışı bırakın: User-data dosyasında root SSH girişini kapatın.
  • Sudo yetkilerini sınırlayın: NOPASSWD:ALL production’da riskli olabilir. Gerçekten hangi komutların sudo ile çalıştırılacağını belirleyin.
  • Şifreli SSH anahtarı kullanın: Proxmox sunucusunda saklanan SSH özel anahtarını passphrase ile koruyun.
  • Snippets erişimini kısıtlayın: User-data dosyaları içinde hassas bilgi (API token, şifre vb.) bulunuyorsa bu dosyalara erişimi kısıtlayın.
# Snippets dizini izinlerini düzenle
chmod 700 /var/lib/vz/snippets/
chmod 600 /var/lib/vz/snippets/*.yaml

Çoklu Şablon Stratejisi

Tek bir şablon yeterli gelmeyebilir. Farklı kullanım senaryoları için farklı şablonlar hazırlamak mantıklıdır:

  • ID 9000: Ubuntu 22.04 LTS minimal (web sunucuları için)
  • ID 9001: Ubuntu 22.04 LTS + Docker (konteyner workload’ları için)
  • ID 9002: Debian 12 minimal (veritabanı sunucuları için)
  • ID 9003: CentOS Stream 9 (kurumsal uygulamalar için)

Her şablonun kendi user-data dosyası ve standart boyutları olabilir. Yeni bir servis kurarken hangi şablondan klonlayacağınızı önceden belirlemiş olursunuz.

Şablon Güncelleme Stratejisi

Şablonlar zaman içinde eskir. Aylık veya üç aylık güncelleme döngüsü oluşturmanızı öneririm:

  • Mevcut şablonu silin
  • Güncel cloud imajı indirin
  • Aynı ID ile yeni şablon oluşturun
  • Test ortamında birkaç VM klonlayıp kontrol edin
  • Eski VM’leri etkilemeden yeni VM’ler güncel şablon üzerinden gelir

Bu döngüyü cron ile de otomatikleştirebilirsiniz ancak şablon güncelleme kritik bir operasyon olduğu için manuel onay adımı eklemek daha akıllıca.

Sonuç

Cloud-Init ile Proxmox entegrasyonu, altyapı yönetiminde gerçek anlamda oyun değiştirici bir yaklaşım. Bir kez şablonları hazırlayıp standart kullanım kalıplarınızı oturttuktan sonra onlarca VM’i dakikalar içinde hazır hale getirabiliyorsunuz. Bu sadece zaman kazanmak değil, aynı zamanda insan hatasını ortadan kaldırarak tutarlılık sağlamak anlamına da geliyor.

Küçük homelab ortamlarından kurumsal altyapılara kadar her ölçekte işe yarayan bu yaklaşımı bir kez alışkanlık haline getirdiğinizde, artık eski yöntemlere dönmek istemeyeceksiniz. Terraform entegrasyonu da eklenince GitOps yaklaşımıyla tüm VM yaşam döngüsünü kod olarak yönetmek mümkün hale geliyor.

İlk adım olarak test ortamınızda bir Ubuntu Cloud şablonu oluşturun, birkaç klonlama deneyin ve user-data dosyalarını kendi ihtiyaçlarınıza göre şekillendirmeye başlayın. Geri kalan her şey deneyimle yerli yerine oturacaktır.

Yorum yapın