SSD Nodes Learn 🎉 VPS $5.50/aydan başlayan
Rehberler Matt ConnorYazan Matt Connor

Ansible erişilemeyen sunucuları yoksayma rehberi

Ansible unreachable hatası alan sunucuları ignore_unreachable ile nasıl yönetebileceğinizi öğrenin. Hangi sunucuların güncellemeleri kaçırdığını belirlemek için izleyin.

Erişilemeyen bir sunucu başarısız bir görev değildir

Ansible içinde erişilemeyen sunucuları yoksaymak için ignore_unreachable: true ayarını kullanırsınız ve bu anahtar çalışır. Önemli olan nokta, bunu ne zaman kullanacağınızı bilmektir; çünkü Ansible iki farklı sorunu iki farklı şekilde ele alır. Bir sunucuda çalışan ve hata döndüren görev bir başarısızlık (failure) durumudur. Ansible'ın hiçbir şekilde bağlantı kuramadığı sunucu ise erişilemez (unreachable) durumdadır. ignore_errors yalnızca ilk durumu kapsar. ignore_unreachable ise yalnızca ikinci durumu kapsar.

Play özetindeki fark aşağıdadır.

PLAY RECAP *********************************************************************
web1  : ok=7  changed=2  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0
web2  : ok=0  changed=0  unreachable=1  failed=0  skipped=0  rescued=0  ignored=0

Ansible, web1 ile bağlantı kurdu ve yedi görev çalıştırdı. web2, unreachable=1 ve failed=0 değerlerini gösterir; bu, sunucu üzerinde hiçbir işlemin çalışmadığı anlamına gelir. Ansible bağlantı sağlayamadığı için sunucuyu play kapsamından çıkardı ve geri kalan işlemlerle devam etti. Eğer bu play bir güvenlik güncelleştirmesi yüklüyorsa, sunucularınızdan biri bu güncellemeyi almamış demektir.

Bir ana makinenin erişilemez olmasının nedenleri

Erişilemez durumu, bağlantının herhangi bir modül ana makineye ulaşmadan başarısız olduğu anlamına gelir. Okunacak bir modül çıktısı yoktur, yalnızca bir bağlantı hatası mevcuttur ve bu hata makineye temas eden ilk görevde ortaya çıkar.

fatal: [web2]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 203.0.113.20 port 22: Connection refused", "unreachable": true}

msg alanı gerçek nedeni taşır. Karşılaşacağınız durumlar şunlardır:

  • Connection refused: TCP bağlantısı reddedildi, yani o portta dinleme yapan bir servis yok. sshd durdurulmuş veya SSH başka bir porta taşınmış ancak envanterinizde hala 22 numaralı port yazılı.
  • Connection timed out: Hiçbir yanıt alınamadı. Bir güvenlik duvarı paketleri düşürüyor veya sunucu kapalı. Her deneme, varsayılan olarak 10 saniye olan tam bağlantı zaman aşımı süresine mal olur.
  • Host key verification failed.: ~/.ssh/known_hosts içindeki anahtar, sunucunun sunduğu anahtarla eşleşmiyor. Yeniden kurulan bir VPS, IP adresini korur ancak yeni bir ana makine anahtarı alır; bu nedenle yeniden kurulum sonrası bu durum beklenir, diğer zamanlarda ise ciddidir.
  • Permission denied (publickey): SSH yanıt verdi ancak anahtarınızı reddetti. Port düzgün çalışıyor, bu bir kimlik doğrulama sorunudur; genellikle yanlış ansible_user veya yüklenmemiş bir anahtardan kaynaklanır.
  • Timeout (12s) waiting for privilege escalation prompt: Bağlantı başarılı oldu ancak become başarısız oldu. sudo, asla gelmeyecek bir parola bekliyor.

Eksik bir Python yorumlayıcısı, insanların bu listede olmasını beklediği ancak orada yer almayan bir nedendir. SSH bağlantısı kurulduğu için ana makine erişilebilirdir. Modülün çalışacak bir ortamı yoktur:

fatal: [db1]: FAILED! => {"changed": false, "module_stdout": "/bin/sh: 1: /usr/bin/python3: not found\r\n", "msg": "The module failed to execute correctly, you probably need to set the interpreter", "rc": 127}

Bu satır FAILED! ifadesini belirtir ve özet raporu bunu failed altında sayar, bu nedenle ignore_unreachable ona asla dokunmaz. O ana makine için ansible_python_interpreter ayarını yapın veya üzerine python3 kurun.

Bir play içerisinde ulaşılamayan sunucuları yok sayma

Görev düzeyinde, anahtar kelime modülün yanında yer alır:

- name: Read the package list, and do not stop if the host is down
  ansible.builtin.command: dpkg -l
  register: packages
  changed_when: false
  ignore_unreachable: true

Play düzeyinde ise play içerisindeki her görev için varsayılan değeri belirler ve tek bir görev bunu tekrar değiştirebilir:

- name: Opportunistic fleet maintenance
  hosts: all
  ignore_unreachable: true
  tasks:
    - name: This runs, cannot connect, and the play carries on
      ansible.builtin.ping:

    - name: This one still ends the play for a host that is down
      ansible.builtin.ping:
      ignore_unreachable: false

Arka planda nelerin değiştiğini bilmek önemlidir. ignore_unreachable ayarlandığında, sunucu play içerisinden çıkarılmaz; bu nedenle sonraki her görev tekrar bağlanmayı dener ve aynı şekilde başarısız olur. Bu denemelerin her biri, ansible.cfg içerisindeki timeout değiştirilmediği sürece 10 saniye olan bağlantı zaman aşımını bekler. Ölü bir sunucuya karşı yirmi görevlik bir play, çalışma süresine yaklaşık 200 saniye ekler ve log dosyasına yirmi adet kırmızı satır düşer.

Bu yüzden bir kez kontrol edin ve ardından o sunucuyu temiz bir şekilde durdurun:

- name: Opportunistic fleet maintenance
  hosts: all
  gather_facts: false
  tasks:
    - name: Check that the host answers before doing any work
      ansible.builtin.ping:
      register: reachable
      ignore_unreachable: true

    - name: End the play for this host if it never answered
      ansible.builtin.meta: end_host
      when: reachable.unreachable | default(false)

    - name: Gather facts now that the connection is known good
      ansible.builtin.setup:

    - name: Refresh the package index
      ansible.builtin.apt:
        update_cache: true
      become: true

Bu yöntem, her görev için bir tane yerine, ölü sunucu başına yalnızca bir bağlantı denemesi yapılmasını sağlar. Ansible 2.8 ile eklenen end_host, mevcut sunucu için play'i başarısız olarak işaretlemeden sonlandırır. unreachable anahtarı, kayıtlı sonuç üzerinde yalnızca bağlantı başarısız olduğunda mevcuttur; bu nedenle default(false), yanıt veren her sunucuda koşulun geçerli kalmasını sağlar. Play düzeyinde veri toplama (fact gathering) kapalıdır, çünkü aksi takdirde örtük Gathering Facts görevi, kopuk bağlantıyla karşılaşan ilk görev olurdu; oysa siz bunun kendi ping göreviniz olmasını istersiniz.

ignore_unreachable hem bir play anahtar kelimesidir hem de bir görev anahtar kelimesidir. Bir rolün içine gömmek yerine, okuyucunun görebileceği şekilde playbook içerisinde tutun; çünkü bu ayar, bir çalıştırmanın hangi sunucuları eksik bırakabileceğine karar verir. Playbook ve roller arasındaki ayrım, bu tür bir ayarın hangi katmanda yer alması gerektiğini ele alır.

Neden ignore_errors burada yanlış araçtır

Ansible belgeleri bu sınırlama konusunda oldukça nettir. ignore_errors "yalnızca görev çalışabildiğinde ve 'failed' değerini döndürdüğünde işe yarar. Tanımlanmamış değişken hatalarını, bağlantı başarısızlıklarını, yürütme sorunlarını (örneğin eksik paketler) veya sözdizimi hatalarını görmezden gelmesini sağlamaz."

Bir bağlantı hatası asla failed: true ile bir görev sonucu haline gelmez. Bu durum ayrı bir bayrak olarak gelir ve Ansible bu bayrağa göre öncelikli işlem yapar: sunucu unreachable listesine alınır ve play dışına çıkarılır. Bir play içindeki on iki görevin tamamına ignore_errors: true ekleseniz bile, SSH portu kapalı olan bir sunucu ilk görevde durmaya devam eder. Bu konu, alandaki en yaygın kafa karışıklığıdır ve özellikle ilk playbook'unuzu bir VPS üzerinde yazmayı öğrenirken oluşturduğunuz eski playbook'larınızda bu ifadeyi aratmanız (grep) faydalı olacaktır.

Hata ayıklamayı bastırmadan önce yapın

Kalıcı hale gelen bir bastırma işlemi, sistem filosunun zamanla kontrolden çıkmasına neden olur; çünkü kimsenin erişemediği bir sunucu, aynı zamanda kimsenin yama yapmadığı bir sunucudur. Öncelikle bu sırayı takip edin. Buradaki her komut yalnızca okuma işlemi gerçekleştirir.

  1. ansible web2 -i inventory.ini -m ansible.builtin.ping -o, bir modülü tek bir ana bilgisayar üzerinde çalıştırır ve tek bir satır çıktı verir.
  2. Aynı komuta -vvvv ekleyin. Ansible, hedef kullanıcı, port, özel anahtar ve ilettiği seçenekler dahil olmak üzere oluşturduğu tam ssh komutunu yazdırır.
  3. Bu ssh komutunu -v ile kendiniz çalıştırın. Eğer standart ssh bağlantı kuramıyorsa, sorun Ansible'ın alt katmanındadır ve hiçbir playbook anahtar kelimesi bunu düzeltemez.
  4. msg dizisini okuyun ve yukarıdaki liste ile karşılaştırın. Connection refused ve Connection timed out iki farklı noktayı işaret eder; biri SSH servisini, diğeri ise ağ yolunu gösterir.
  5. Host key verification failed. için, ssh-keygen -F web2.example.com ile ne depoladığınıza bakın. Eğer sunucu yeniden oluşturulduysa, eski girişi ssh-keygen -R web2.example.com ile silin ve sağlayıcı konsolundan doğruladıktan sonra yeni anahtarı kabul edin. ansible.cfg içinde host_key_checking = False ayarını yapmak hatayı giderir, ancak aynı zamanda farklı bir makinenin o adreste yanıt verdiğini size bildirecek olan denetimi de devre dışı bırakır.
  6. Permission denied (publickey) için, Ansible'ın ne kullanması gerektiğini düşündüğünü doğrulayın. ansible-inventory -i inventory.ini --host web2, ansible_user ve ansible_port dahil olmak üzere geçerli değişkenleri yazdırır.
  7. SSH çalışıyor ancak modüller çalışmıyorsa, ansible web2 -m ansible.builtin.raw -a 'command -v python3 || echo none' ile yorumlayıcıyı kontrol edin. raw modülü, komutu kabuk (shell) üzerinden çalıştırır ve hedefte python bulunmasına gerek duymaz.

Ancak bu adımlardan sonra ana bilgisayarı görmezden gelmek bir alışkanlık değil, bilinçli bir karar haline gelir.

Özet, ulaşılamayanları ayrı sayar ve CI genellikle bunu gözden kaçırır

ansible-playbook, başarı durumunda 0, en az bir ana bilgisayar başarısız olduğunda 2 ve en az bir ana bilgisayara ulaşılamadığında 4 koduyla çıkar. Bu iki değer kaynak kodda bit bayraklarıdır; dolayısıyla başarısız bir ana bilgisayar ve ulaşılamayan bir ana bilgisayar içeren bir çalışma 6 koduyla çıkar. ansible komutu aynı kodları döndürür. Bunlar, Ağustos 2026 itibarıyla ansible-core kaynak kodu üzerinden doğrulanmıştır.

Şimdi ignore_unreachable: true ayarını yapın ve aynı yedi görevli oyun kitabını (playbook) aynı ölü ana bilgisayara karşı çalıştırın:

PLAY RECAP *********************************************************************
web1  : ok=7  changed=2  unreachable=0  failed=0  skipped=0  rescued=0  ignored=0
web2  : ok=7  changed=0  unreachable=0  failed=0  skipped=0  rescued=0  ignored=7

web2, unreachable=0 ve yedi görev ok bildirir ve çalışma 0 koduyla çıkar. Anahtar kelime ayarlandığında Ansible, unreachable sütununu dolduran dark sayacı yerine, o ana bilgisayar için ok ve ignored sayaçlarını artırır. Kırmızı UNREACHABLE! satırları yine de yazdırılır; bu nedenle günlük dürüst kalırken özet ve çıkış kodu gerçeği yansıtmaz.

Playbook'u çalıştıran ve yalnızca $? değerini kontrol eden bir CI işi, bu çalışmayı başarılı olarak işaretler ve özet kısmında hiçbir makineye ulaşılamadığına dair bir bilgi yer almaz. Erişilebilirlik kontrolünü, oyun kitabından önce kendi başına bir adım haline getirin:

ansible all -i inventory.ini -m ansible.builtin.ping -o

Bu, her ana bilgisayar için bir satır yazdırır ve herhangi bir ana bilgisayara ulaşılamazsa 4 koduyla çıkar; bu da işlem hattına (pipeline) başarısız olması için bir neden sunar ve günlükte isimleri görmenizi sağlar. ping, hedef üzerinde çalışan bir Python yorumlayıcısına ihtiyaç duyar; bu nedenle sadece bağlantıdan biraz daha fazlasını doğrular ki genellikle istenen de budur. Ardından, ayakta olan ana bilgisayarların değişikliklerini alabilmesi için playbook'u ignore_unreachable ile çalıştırın.

any_errors_fatal ve toplu işlem genelinde max_fail_percentage

Bu iki anahtar kelime, filo genelinde bir sorun oluştuğunda ne yapılacağına karar verir ve ulaşılamayan sunucuları birbirinden farklı şekilde ele alırlar.

any_errors_fatal: true, ulaşılamayan bir sunucuya tepki verir. Ansible, mevcut görevi toplu işlemin geri kalanında tamamlar ve ardından o toplu işlemdeki tüm sunucular için oynatmayı durdurur. Bunu, yalnızca koordineli bir şema değişikliği gibi hep ya da hiç mantığıyla çalışması gereken durumlarda kullanın.

max_fail_percentage: 30, ulaşılamayan bir sunucuya tepki vermez. Kontrol mekanizması, başarısız olan sunucu sayısını toplu işlem boyutuna böler; ulaşılamayan sunucular ayrı bir listede tutulduğu için bu sayıya hiçbir zaman dahil edilmezler. Dördü ulaşılamayan on sunucu max_fail_percentage: 10 altında çalışmaya devam ederken, bir görevde başarısız olan iki sunucu oynatmayı durdurur. Dokümantasyon bir tuzak noktasına daha dikkat çeker: "Belirlenen yüzdeye eşit olunmamalı, bu yüzde aşılmalıdır." serial: 4 ile dört sunucudan ikisinin başarısız olması durumunda durdurma işlemi için 50 değil, 49 yazılmalıdır.

Ulaşılamayan sunucuların çalışmayı kendi başlarına durdurduğu bir durum mevcuttur. Toplu işlemdeki her sunucu başarısız olmuş veya ulaşılamaz durumdaysa, Ansible üzerinde çalışacak başka bir sunucu kalmadığı için oynatmayı NO MORE HOSTS LEFT ile sonlandırır.

serial: tüm filoda değişiklikleri kademeli uygulama

- name: Rolling nginx config update
  hosts: webservers
  serial: 2
  max_fail_percentage: 25
  tasks:
    - name: Deploy the site config
      ansible.builtin.template:
        src: site.conf.j2
        dest: /etc/nginx/conf.d/site.conf
        owner: root
        mode: "0644"
      become: true
      notify: Reload nginx
  handlers:
    - name: Reload nginx
      ansible.builtin.service:
        name: nginx
        state: reloaded
      become: true

serial: 2, tüm işlemi önce iki sunucu üzerinde çalıştırır, tamamlar ve ardından sonraki iki sunucuya geçer. serial: "25%", grubun boyutuyla orantılı olarak ölçeklenir. serial: [1, 5, 10] listesi, canary (erken uyarı) yapısıdır: önce bir sunucu, sonra beş, sonra on sunucu işlenir; kalan sunucular ise son gruptaki sayı kadar parçalar halinde çalıştırılır. max_fail_percentage her bir grup için ayrı ayrı ölçülür, bu nedenle ikisi birlikte çalışır. İlk makinede hata oluşursa, işlem kırk makineyi bozmadan durur. tek bir kontrol makinesinden Linux sunucu filosunu yönetmeyi tek bir komutla güvenli kılan özellik budur.

Erişilemeyen sunucuların ne zaman göz ardı edileceği, ne zaman edilmeyeceği

Fırsatçı işler için bu sunucuları göz ardı edin. Bir veri toplama çalışması veya saatlik sapma kontrolü, kapalı olan bir sunucuyu atladığında hiçbir şey kaybetmez; çünkü bir sonraki geçişte bu sunucu tekrar yakalanır. ignore_unreachable: true oyun seviyesi burada doğru cevaptır; ping adımıyla eşleştirildiğinde atlanan isimler birinin okuyabileceği bir yere düşer.

Güvenlik yaması çalışması için bu sunucuları asla göz ardı etmeyin. Bu çalışmanın değeri, her sunucunun düzeltmeye sahip olduğunun garantisidir; erişilemeyen durumunu bastırmak, "bir sunucu hala savunmasız" gerçeğini temiz ve yeşil bir özet haline getirir. İki haftadır erişilemeyen sunucu, muhtemelen en geride kalmış sunucudur. Bırakın o çalışma 4 hata koduyla sonlansın ve bir kişi durumu incelesin.

Her iki durumda da tek bir kural geçerlidir: durdurmayı bastırın, kaydı asla. Eğer bir sunucu atlandıysa, özet içinde, CI günlüğünde veya bir izleme uyarısında bunu belirten bir şey olmalıdır. Ansible, bir sunucunun varlığını yalnızca üzerinde bir oyun çalıştırıldığı saniyeler boyunca bilir; bu nedenle bir sunucunun Salı gününden beri kapalı olduğunu öğrenmek için kötü bir yerdir. Bu iş izleme sistemine aittir ve Zabbix kuran bir Ansible playbook ile tüm filoyu kapsayan bir görünüm bir öğleden sonra elde edilebilir.

FAQ

Ansible'da ignore_errors ve ignore_unreachable arasındaki fark nedir?

ignore_errors: true, ana makinede çalışan ve hata döndüren (örneğin sıfırdan farklı bir çıkış koduyla sonlanan komutlar) bir göreve uygulanır. ignore_unreachable: true ise Ansible'ın bağlantı kuramadığı ve hiçbir modülün çalışmadığı bir ana makineye uygulanır. Bu iki parametre görev sonucundaki farklı alanları okur ve birbirlerinin kapsadığı durumları karşılamazlar. Ansible belgelerinde belirtildiği üzere ignore_errors, "tanımlanmamış değişken hatalarını, bağlantı başarısızlıklarını, yürütme sorunlarını (örneğin eksik paketler) veya sözdizimi hatalarını görmezden gelmez"; kapalı bir SSH portu ise bir bağlantı başarısızlığıdır.

ignore_unreachable, ana makineyi play özetinden gizler mi?

Aslında evet. Bu anahtar kelime ayarlandığında, Ansible o ana makineyi unreachable altında saymayı bırakır ve görev başına bir kez ok ve ignored olarak sayar; ardından çalışma 0 çıkış koduyla sonlanır. fatal: [host]: UNREACHABLE! satırları yazdırılmaya devam eder, bu nedenle özet ve çıkış kodu hatalı olsa bile günlük kayıtları doğrudur. ignored sütununu izleyin veya ansible all -m ansible.builtin.ping -o komutunu ayrı bir adım olarak çalıştırın; böylece ulaşılamayan bir ana makine yine de sıfırdan farklı bir çıkış kodu üretir.

Bir ana makineye ulaşılamadığında ansible-playbook hangi çıkış kodunu döndürür?

4 değerini döndürür. En az bir başarısız ana makine içeren bir çalışma 2 döndürür; bu iki değer bit bayrağı olduğu için hem başarısızlık hem de ulaşılamayan ana makine içeren bir çalışma 6 döndürür. Sorunsuz bir çalışma 0 döndürür. Bu kodlar, Ağustos 2026 itibarıyla ansible-core kaynak kodları üzerinden doğrulanmıştır. ignore_unreachable: true ayarını yapmak 4 değerini kaldırır; bu nedenle yalnızca çıkış kodunu test eden bir pipeline, atlanan bir makineyi göremez.

Yanıt vermeyen bir ana makine için play'in geri kalanını nasıl atlarım?

İlk görevi ansible.builtin.ping kullanarak ignore_unreachable: true ve register: reachable ile yapılandırın, ardından when: reachable.unreachable | default(false) koşulu altında ansible.builtin.meta: end_host ile devam edin. end_host, o ana makine için play'i başarısız olarak işaretlemeden sonlandırır. Play üzerinde gather_facts: false ayarını yapın, böylece ping işleminiz bağlantı kopukluğunu tespit eden görev olur. Bu desen kullanılmadığında, yanıt vermeyen ana makine play içinde kalmaya devam eder ve sonraki her görev tekrar bağlantı zaman aşımını bekler.

Güvenlik yaması sırasında ulaşılamayan ana makineleri görmezden gelmeli miyim?

Hayır. Bir yama çalışması, her ana makinenin güncellemeyi aldığından emin olmanızı sağladığı için değerlidir; ulaşılamayan ana makineleri görmezden gelmek, bu garantiyi yeşil bir özetle değiştirir. Çalışmanın 4 koduyla sonlanmasına izin verin, yanıt vermeyen ana makinelerin isimlerini okuyun ve bunları düzeltin. Hata gizleme, bir sonraki geçişte kaçırılanların yakalanacağı tekrarlanan fırsatçı çalışmalar için uygundur.

#ansible#playbooks#error-handling#inventory#automation