Bir sunucuyu klonladıktan sonra hâlâ konsola girip hostname yazıyor, kullanıcı açıyor, SSH anahtarı yapıştırıp statik IP tanımlıyorsanız otomasyonun yarısında durmuşsunuz demektir. cloud-init ile otomatik VM kurulumu bu son yarıyı da kapatır: makine ilk kez açıldığında kendi adını, ağını, kullanıcılarını, SSH anahtarlarını ve hatta çalıştıracağı ilk komutları hipervizörden okuyup kendi kendine uygular. Sonuç, qm clone ve qm start arasına sıkışan tek bir yapılandırma komutuyla tamamen hazır bir sunucudur.
Bu yazıda cloud-init'in nasıl çalıştığını, bir dağıtımın resmî bulut imajından Proxmox'ta nasıl şablon üreteceğinizi, kullanıcı/anahtar/ağ ayarlarını hem panelden hem komut satırından nasıl vereceğinizi ve kendi user-data dosyanızı nasıl yazacağınızı göstereceğim. Sonda da cloud-init'in "çalışmıyor" göründüğü klasik durumları ve her birinin gerçek sebebini toplayacağım — çoğu zaman sorun cloud-init'te değil, imajın durumundadır.
cloud-init Nasıl Çalışıyor#
cloud-init, bulut imajlarının içine kurulu gelen bir ilk açılış yapılandırma aracıdır. Makine açıldığında çevresine bakar ve bir veri kaynağı (datasource) arar: bir sanal CD-ROM, özel bir ağ adresi ya da bir yapılandırma sürücüsü. Proxmox, ide2 üzerine bağladığı küçük bir ISO imajıyla NoCloud veri kaynağını sunar; cloud-init bu ISO'daki user-data, meta-data ve network-config dosyalarını okur ve uygular.
İşleyiş dört aşamaya bölünür ve bu aşamaları bilmek hata ayıklarken çok işinize yarar:
| Aşama | Ne yapar | Ne zaman çalışır |
|---|---|---|
init-local | Veri kaynağını bulur, ağ yapılandırmasını yazar | Ağ açılmadan önce |
init | Kullanıcılar, SSH anahtarları, hostname | Ağ açıldıktan sonra |
config | Paket kurulumu, dosya yazma, yapılandırma modülleri | Sistem servisleri hazırken |
final | runcmd komutları, kapanış mesajı | Açılışın sonunda |
En önemli kural şudur: cloud-init yalnızca ilk açılışta çalışır. Bunu takip etmek için durumunu /var/lib/cloud/ altında saklar. Bir makineyi şablona dönüştürmeden önce bu durumu temizlemezseniz, o şablondan üretilen tüm klonlar "ben zaten yapılandırıldım" diyerek hiçbir şey yapmaz. Şablon hazırlığının tamamı için Proxmox'ta VM şablonu ve klonlama yazısına bakın; oradaki temizlik adımı bu yazının önkoşuludur.
Bulut İmajından Şablon Oluşturma#
cloud-init kullanmanın en pratik yolu, dağıtımların yayımladığı hazır bulut imajlarını kullanmaktır. Bu imajlar zaten cloud-init kurulu, minimal ve otomatik disk büyütmeye hazır gelir; sıradan bir ISO'dan kurulum yapıp cloud-init eklemekten çok daha az iş çıkarır.
Debian, Ubuntu, Rocky ve AlmaLinux resmî bulut imajlarını .qcow2 biçiminde yayımlar. Akış şöyledir:
# 1) İmajı indir (dağıtımın resmî bulut imajı deposundan)
cd /var/lib/vz/template/iso
wget https://cloud.debian.org/images/cloud/bookworm/latest/debian-12-genericcloud-amd64.qcow2
# 2) Boş bir makine kabuğu oluştur (disk YOK, sonra ekleyeceğiz)
qm create 9100 --name debian12-cloud --memory 2048 --cores 2 \
--net0 virtio,bridge=vmbr0 --ostype l26 --scsihw virtio-scsi-single
# 3) İmajı diske aktar
qm importdisk 9100 debian-12-genericcloud-amd64.qcow2 local-lvm
# 4) Aktarılan diski SCSI olarak bağla ve önyükleme sırasını ayarla
qm set 9100 --scsi0 local-lvm:vm-9100-disk-0
qm set 9100 --boot order=scsi0
# 5) cloud-init sürücüsünü ekle - bu satır olmadan hiçbir ayar makineye ulaşmaz
qm set 9100 --ide2 local-lvm:cloudinit
# 6) Seri konsol ekle - bulut imajları çıktıyı buraya verir
qm set 9100 --serial0 socket --vga serial0
# 7) Guest agent'ı etkinleştir
qm set 9100 --agent enabled=1
# 8) Şablona dönüştür
qm template 9100
Beşinci adım en sık atlanan ve en çok kafa karıştıran adımdır: --ide2 local-lvm:cloudinit satırı olmadan Proxmox'un cloud-init sekmesindeki tüm ayarlar makineye hiç ulaşmaz, çünkü onları taşıyacak sanal sürücü yoktur. Altıncı adımdaki seri konsol da önemlidir; bulut imajları grafik konsola çıktı vermez, konsolu açtığınızda kara ekran görürsünüz ve bunun bir arıza olduğunu sanırsınız.
Kullanıcı, SSH Anahtarı ve Ağ Ayarları#
Şablon hazır olduğunda klon üretip ayarları vermek tek bir komut zincirine iner. Proxmox, cloud-init'in en sık kullanılan alanlarını doğrudan makine yapılandırmasına açar:
# Şablondan klon üret
qm clone 9100 160 --name web-01 --full
# Kullanıcı adı ve SSH anahtarı
qm set 160 --ciuser yonetici
qm set 160 --sshkeys /root/.ssh/id_ed25519.pub
# Statik IP ve ağ geçidi (DHCP için: ip=dhcp)
qm set 160 --ipconfig0 ip=185.12.34.56/24,gw=185.12.34.1
# DNS sunucuları ve arama alan adı
qm set 160 --nameserver "1.1.1.1 9.9.9.9" --searchdomain firmaniz.com
# Diski büyüt - cloud-init ilk açılışta dosya sistemini de genişletir
qm resize 160 scsi0 +30G
qm start 160
Buradaki en değerli davranış, disk büyütmedir: qm resize sanal diski büyütür, cloud-init'in growpart modülü ise ilk açılışta bölümü ve dosya sistemini otomatik genişletir. Yani klasik kurulumda elle yapmanız gereken growpart + resize2fs adımı kendiliğinden hallolur.
Parola ayarlamak için --cipassword alanı da vardır ama kullanmamanızı öneririm: parola cloud-init sürücüsüne yazılır ve makine yapılandırmasında görülebilir. SSH anahtarıyla giriş yapıp parola girişini kapalı tutmak her zaman daha sağlıklıdır. Güçlü bir parola üretmeniz gereken durumlarda şifre üretici aracımızı kullanabilirsiniz.
Ayarların makineye gerçekten ulaştığını, üretilen yapılandırmayı dökerek görebilirsiniz:
# Proxmox'un ürettiği cloud-init verisini gör
qm cloudinit dump 160 user
qm cloudinit dump 160 network
# Değişiklikten sonra sürücüyü yenile (makine kapalıyken)
qm cloudinit update 160
Kendi user-data Dosyanızı Yazmak#
Panelin sunduğu alanlar temel ihtiyaçları karşılar ama paket kurmak, dosya yazmak ya da ilk açılışta komut çalıştırmak isterseniz kendi user-data dosyanızı vermeniz gerekir. Bu dosya YAML biçimindedir ve ilk satırı mutlaka #cloud-config olmalıdır.
#cloud-config
hostname: web-01
manage_etc_hosts: true
timezone: Europe/Istanbul
users:
- name: yonetici
groups: [sudo]
shell: /bin/bash
sudo: "ALL=(ALL) NOPASSWD:ALL"
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... [email protected]
# Parola ile SSH girişini kapat
ssh_pwauth: false
disable_root: true
package_update: true
package_upgrade: true
packages:
- nginx
- ufw
- fail2ban
- qemu-guest-agent
write_files:
- path: /etc/nginx/conf.d/güvenlik.conf
content: |
server_tokens off;
add_header X-Content-Type-Options nosniff;
permissions: "0644"
runcmd:
- [systemctl, enable, --now, qemu-guest-agent]
- [ufw, allow, "22/tcp"]
- [ufw, allow, "80,443/tcp"]
- [ufw, --force, enable]
- [systemctl, restart, nginx]
final_message: "Sunucu hazır - $UPTIME saniyede açıldı"
Bu dosyayı Proxmox'ta kullanmak için bir snippet olarak saklamanız ve makineye cicustom ile bağlamanız gerekir:
# Snippet dizinini etkinleştirin (Datacenter > Storage > local > Content: Snippets)
mkdir -p /var/lib/vz/snippets
cp user-data-web.yaml /var/lib/vz/snippets/
# Makineye özel user-data'yı bağla
qm set 160 --cicustom "user=local:snippets/user-data-web.yaml"
⚠️ Dikkat: cicustom ile user verdiğinizde Proxmox'un ciuser/sshkeys alanları devre dışı kalır — artık kullanıcıyı ve anahtarı YAML dosyasının kendisinde tanımlamanız gerekir. Ağ ayarını panelden vermeye devam etmek isterseniz yalnızca user= kısmını özelleştirin, network= kısmına dokunmayın.
YAML yazarken girinti hataları en sık karşılaşılan sorundur; dosyayı göndermeden önce söz dizimini doğrulamak zaman kazandırır. Yapılandırma dosyalarını hızlıca kontrol etmek için JSON formatlayıcı gibi araçlar YAML'ın JSON karşılığını doğrulamada yardımcı olabilir.
Doğrulama ve Hata Ayıklama#
Makine açıldığında cloud-init'in ne yaptığını görmek için üç yer vardır ve sırayla bakmak en verimlisidir:
# 1) Genel durum - "status: done" görmek istersiniz
cloud-init status --long
# 2) Aşama aşama ne oldu, ne kadar sürdü
cloud-init analyze show | head -20
# 3) Hata varsa ayrıntısı burada
tail -50 /var/log/cloud-init-output.log
grep -i -E "error|traceback|fail" /var/log/cloud-init.log | tail -20
cloud-init status çıktısı status: disabled diyorsa, veri kaynağı bulunamamış demektir — büyük ihtimalle makinede cloud-init sürücüsü (ide2) tanımlı değildir. status: done diyor ama ayarlar uygulanmamışsa, imaj daha önce yapılandırılmış ve durum dosyaları temizlenmemiştir.
Bir makinede cloud-init'i sıfırlayıp yeniden çalıştırmak isterseniz:
# Durumu temizle ve makineyi yeniden başlat
cloud-init clean --logs --seed
reboot
Makinenin IP'sini ve konuk durumunu Proxmox arayüzünden görebilmek için guest agent'ın çalışıyor olması gerekir; bunu runcmd içinde etkinleştirmeyi ihmal etmeyin. Ayrıntılar için QEMU Guest Agent kurulumu yazısına bakabilirsiniz.
Sık Yapılan Hatalar ve Tuzaklar#
| Belirti | Sebep | Çözüm |
|---|---|---|
| Cloud-init sekmesindeki ayarlar hiç uygulanmıyor | ide2 cloud-init sürücüsü eklenmemiş | qm set <id> --ide2 <depo>:cloudinit |
| Klonlarda hiçbir ayar çalışmıyor | Şablon temizlenmemiş, durum "done" | Şablon öncesi cloud-init clean --logs |
| Konsol kapkara, çıktı yok | Bulut imajı seri konsola yazıyor | --serial0 socket --vga serial0 |
| SSH anahtarı çalışmıyor | Anahtar dosyası yanlış biçimde veya cicustom alanları geçersiz kılmış | qm cloudinit dump <id> user ile doğrula |
| Disk büyütüldü ama boş alan görünmüyor | growpart modülü yok veya devre dışı | Konukta growpart /dev/sda 1 && resize2fs /dev/sda1 |
| Ayarları değiştirdim, makinede değişmedi | cloud-init ilk açılışta çalışır | Ayarı değiştirip cloud-init clean sonrası yeniden başlat |
| Statik IP verdim ama makine ağa çıkmıyor | Ağ geçidi aynı alt ağda değil | ipconfig0 içindeki gw değerini kontrol et |
Bu tablodaki en sinsi satır sondan ikincisidir. İnsanlar cloud-init'i bir yapılandırma yönetimi aracı sanır ve ayarı değiştirip makineyi yeniden başlatınca değişmesini bekler. cloud-init böyle çalışmaz: ilk açılış aracıdır. Çalışan bir makinenin yapılandırmasını sürekli yönetmek istiyorsanız doğru araç Ansible gibi bir yapılandırma yönetimi sistemidir; Ansible ile sunucu otomasyonu yazısı ikisinin nasıl birlikte kullanıldığını açıklar. Tipik düzen şudur: cloud-init makineyi ayağa kaldırır ve SSH erişimini hazırlar, Ansible geri kalan her şeyi yönetir.
Bir başka tuzak, runcmd içinde uzun süren işler çalıştırmaktır. Bu komutlar açılışın son aşamasında sırayla çalışır ve makine, hepsi bitene kadar tam hazır sayılmaz. Onlarca paket derleyen bir runcmd, ilk açılışı dakikalarca uzatır. Uzun işleri sonraya bırakıp yapılandırma yönetimine devretmek daha sağlıklıdır.
Son olarak user-data içine sır yazmaktan kaçının. Bu dosya cloud-init sürücüsünde saklanır ve makine içinden /var/lib/cloud/instance/user-data.txt yolunda okunabilir. Veritabanı parolası ya da API anahtarı gibi değerleri buraya değil, ilk açılıştan sonra güvenli bir sır yönetimi kanalıyla iletin.
Sıkça Sorulan Sorular#
cloud-init her açılışta çalışır mı#
Hayır, varsayılan olarak yalnızca ilk açılışta tam yapılandırmayı uygular. Sonraki açılışlarda bazı modüller (örneğin ağ) yeniden değerlendirilir ama kullanıcı oluşturma, paket kurma ve runcmd gibi adımlar tekrarlanmaz. Bunu takip eden şey /var/lib/cloud/ altındaki durum dosyalarıdır. Yeniden çalıştırmak isterseniz cloud-init clean ile durumu temizleyip makineyi yeniden başlatmanız gerekir.
Kendi ISO'mdan kurduğum makinede cloud-init kullanabilir miyim#
Kullanabilirsiniz ama ek iş gerekir: önce konuk sisteme cloud-init paketini kurmanız, ardından makineye cloud-init sürücüsünü eklemeniz ve şablona dönüştürmeden önce durumu temizlemeniz gerekir. Yine de dağıtımların resmî bulut imajlarını kullanmak çok daha az sorun çıkarır; o imajlar zaten minimal, cloud-init kurulu ve otomatik disk büyütmeye hazır gelir.
Cloud-init sekmesindeki ayarlar neden uygulanmıyor#
En yaygın iki sebep var. Birincisi, makinede cloud-init sürücüsü tanımlı değildir — qm config çıktısında ide2: ...cloudinit satırını arayın. İkincisi, imaj daha önce yapılandırılmış ve durum "done" olarak kaydedilmiştir; bu durumda cloud-init hiçbir şey yapmadan çıkar. cloud-init status --long çıktısı hangi durumda olduğunuzu doğrudan söyler.
user-data ile Proxmox panelinin alanlarını birlikte kullanabilir miyim#
Kısmen. cicustom ile user= verdiğinizde panelin kullanıcı ve SSH anahtarı alanları devre dışı kalır; bu bilgileri artık YAML dosyanızda tanımlamanız gerekir. Ağ tarafı ayrıdır: network= özelleştirmesi yapmazsanız panelden verdiğiniz ipconfig0 ayarları geçerli kalır. Pratikte en rahat düzen, ağı panelden, kullanıcı ve paketleri user-data'dan yönetmektir.
cloud-init ile Ansible arasındaki fark nedir#
cloud-init bir ilk açılış aracıdır: makineyi sıfırdan kullanılabilir hâle getirir ve işini bitirir. Ansible ise sürekli yapılandırma yönetimi yapar; istediğiniz zaman çalıştırıp sistemin istenen duruma geldiğini garanti eder. İkisi rakip değil tamamlayıcıdır. Yaygın düzen şudur: cloud-init kullanıcıyı ve SSH anahtarını kurar, ondan sonrasını Ansible devralır.
Windows makinelerde cloud-init kullanılır mı#
Windows'ta cloud-init'in bir sürümü mevcuttur ancak Linux'taki kadar yaygın ve olgun değildir. Windows dünyasında karşılığı genellikle sysprep ile hazırlanmış bir imaj ve bir unattend.xml yanıt dosyasıdır; bazı kurulumlarda Cloudbase-Init tercih edilir. Proxmox'un cloud-init sürücüsü Windows konuklarda beklediğiniz gibi çalışmayabilir, bu yüzden Windows şablonlarını sysprep akışıyla hazırlamak daha güvenilirdir.
Kapanış#
cloud-init, şablon üretmeyle birlikte kullanıldığında sunucu kurulumunu dakikalardan saniyelere indirir. Aklınızda kalması gereken dört alışkanlık şunlar: bulut imajı kullanın (ISO'dan kurmayın), makineye cloud-init sürücüsünü eklemeyi asla unutmayın, şablona dönüştürmeden önce mutlaka cloud-init clean çalıştırın ve cloud-init'i sürekli yapılandırma aracı değil, ilk açılış aracı olarak görün.
Bu otomasyonu kendi altyapınızda kurmak istiyorsanız tam root erişimli VDS ve sanal sunucu paketlerimizle kendi Proxmox düğümünüzü çalıştırabilir, esnek ölçeklenme gerektiren projelerde bulut sunucu tarafına bakabilirsiniz. Şablon hazırlama, otomasyon ve güncelleme döngüsünü devretmek isterseniz sunucu yönetimi hizmetimiz bu işi baştan sona üstlenir.