Ansible วิธีเล่นการแจ้งเตือนซ้ำ

ขณะนี้ฉันกำลังเปลี่ยนจาก puppet เป็น Ansible และฉันสับสนเล็กน้อยกับแนวคิดบางอย่างหรืออย่างน้อย ansible ทำงานอย่างไร

ข้อมูลบางอย่างเกี่ยวกับการตั้งค่า:

ฉันใช้ตัวอย่างจาก Ansible Best Practices และได้วางโครงสร้างโครงการของฉันโดยมีบทบาทหลายอย่าง (playbooks ) และอื่นๆ

ฉันใช้ Vagrant เพื่อจัดเตรียมและกล่องคือ Saucy64 VBox

ความสับสนเกิดขึ้นที่ไหน:

เมื่อฉันจัดเตรียมและรัน Ansible งานต่างๆ จะเริ่มดำเนินการ จากนั้นจะมีการแจ้งเตือนจำนวนมาก

ตัวอย่าง:

งานสุดท้าย:

TASK: [mysql | delete anonymous MySQL server user for localhost] ************** 
<127.0.0.1> REMOTE_MODULE mysql_user user='' state=absent 
changed: [default] => {"changed": true, "item": "", "user": ""}

จากนั้นการแจ้งเตือนครั้งแรก:

NOTIFIED: [timezone | update tzdata] ****************************************** 
<127.0.0.1> REMOTE_MODULE command /usr/sbin/dpkg-reconfigure --frontend noninteractive tzdata
changed: [default] => {"changed": true, "cmd": ["/usr/sbin/dpkg-reconfigure", "--frontend", "noninteractive", "tzdata"], "delta": "0:00:00.224081", "end": "2014-02-03 22:34:48.508961", "item": "", "rc": 0, "start": "2014-02-03 22:34:48.284880", "stderr": "\nCurrent default time zone: 'Europe/Amsterdam'\nLocal time is now:      Mon Feb  3 22:34:48 CET 2014.\nUniversal Time is now:  Mon Feb  3 21:34:48 UTC 2014.", "stdout": ""}

ตอนนี้ทุกอย่างเรียบร้อยดี เมื่อบทบาทเพิ่มขึ้น การแจ้งเตือนก็ติดขัดมากขึ้นเรื่อยๆ

มาถึงปัญหาแล้ว

เมื่อการแจ้งเตือนล้มเหลว การจัดเตรียมจะหยุดตามปกติ แต่แล้วสแต็กการแจ้งเตือนก็ว่างเปล่า! ซึ่งหมายความว่าการแจ้งเตือนทั้งหมดว่าจะไม่ถูกดำเนินการหลังจากที่เกิดข้อผิดพลาด!

หากเป็นเช่นนั้น หากคุณเปลี่ยนการตั้งค่า vhosts สำหรับ apache และมีการแจ้งเตือนให้บริการ apache โหลดซ้ำ สิ่งนี้จะหายไป

ลองยกตัวอย่าง (หลอก lang):

- name: Install Apache Modules
  notify: Restart Apache

- name: Enable Vhosts
  notify: Reload Apache

- name: Install PHP
  command: GGGGGG # throws an error

เมื่อดำเนินการข้างต้น:

  1. ติดตั้งโมดูล Apache แล้ว
  2. Vhosts ถูกเปิดใช้งาน
  3. PHP พยายามติดตั้งและล้มเหลว
  4. สคริปต์ออก
  5. (การแจ้งเตือนอยู่ที่ไหน?)

ณ จุดนี้ทุกอย่างดูสมเหตุสมผล แต่อีกครั้ง Ansible พยายามที่จะฉลาด (ไม่!*) ซ้อนการแจ้งเตือน ดังนั้นการโหลดซ้ำและรีสตาร์ท apache จะส่งผลให้มีการรีสตาร์ท apache เพียงครั้งเดียวเมื่อสิ้นสุดการจัดเตรียม นั่นหมายความว่าการแจ้งเตือนทั้งหมดจะล้มเหลว!!!

ตอนนี้มาถึงที่นี่สำหรับบางคนนี่ก็เป็นเรื่องปกติเช่นกัน พวกเขาจะบอกว่าเพิ่งเรียกใช้การจัดเตรียมอีกครั้ง และการแจ้งเตือนจะเริ่มทำงาน ดังนั้นในที่สุด apache จะถูกโหลดใหม่และไซต์จะกลับมาทำงานอีกครั้ง ไม่เป็นเช่นนั้น

ในการรันสคริปต์ครั้งที่สองหลังจากโค้ดสำหรับการติดตั้ง php ได้รับการแก้ไขแล้ว การแจ้งเตือน จะไม่ทำงาน เนื่องจากการออกแบบ ทำไม

นี่คือเหตุผล: Ansible จะมีงานที่ดำเนินการสำเร็จ โดยทำเครื่องหมายเป็นเสร็จสิ้น/เป็นสีเขียว ดังนั้นจึงไม่ลงทะเบียนการแจ้งเตือนใดๆ สำหรับงานเหล่านี้ การจัดเตรียมจะสำเร็จ และเพื่อที่จะทริกเกอร์การแจ้งเตือน และด้วยเหตุนี้ apache จึงรีสตาร์ท คุณสามารถดำเนินการอย่างใดอย่างหนึ่งต่อไปนี้:

  1. เรียกใช้คำสั่งโดยตรงไปยังเซิร์ฟเวอร์ผ่าน ansible หรือ ssh
  2. แก้ไขสคริปต์เพื่อทริกเกอร์งาน
  3. เพิ่มงานแยกต่างหากสำหรับสิ่งนั้น
  4. ทำลายอินสแตนซ์ของกล่องและการจัดเตรียมใหม่

สิ่งนี้ค่อนข้างน่าหงุดหงิดเพราะต้องมีการล้างกล่องทั้งหมด หรือฉันไม่เข้าใจบางอย่างอย่างถูกต้องด้วย Ansible

มีวิธีอื่นในการ 'เรียกคืน'/เล่นซ้ำ/บังคับให้ดำเนินการการแจ้งเตือนหรือไม่

  • ฉลาดอาจทำเครื่องหมายงานว่าไม่สมบูรณ์แล้วรีสตาร์ทการแจ้งเตือนหรือแยกคิวโดยให้การแจ้งเตือนเป็นงานของตนเอง*

person Jimmy Kane    schedule 03.02.2014    source แหล่งที่มา


คำตอบ (2)


ใช่ นั่นคือหนึ่งในข้อบกพร่องของ Ansible ที่จะพูดเมื่อเปรียบเทียบกับ Puppet Puppet มีความชัดเจนและไม่ผิดพลาดเหมือน Ansible (หรือ Chef) สำหรับเรื่องนั้น มีทั้งข้อดีและข้อเสีย เช่น Puppet ใช้เวลาเล็กน้อยก่อนที่จะเริ่มทำงานเนื่องจากจำเป็นต้องรวบรวมแค็ตตาล็อก

ดังนั้น คุณพูดถูกหากสคริปต์ Ansible ของคุณเกิดข้อผิดพลาด การอัปเดตการแจ้งเตือนของคุณจะไม่เกิดขึ้น วิธีเดียวที่เราจะแก้ไขได้คือการใช้คำสั่งแบบมีเงื่อนไข ใน Playbook ของคุณ คุณสามารถทำสิ่งนี้ได้:

- name: My cool playbook
  hosts: all

  vars:
      force_tasks: 0

  tasks:
    - name: Apache install
      action: apt pkg=$item state=latest
      with_items:
       - apache2
       - apache2-mpm-prefork

    - name: Restart apache
      action: service name=apache2 state=restart
      when: force_tasks

จากนั้นเมื่อคุณเรียกใช้ Playbook คุณสามารถส่ง force_tasks เป็นตัวแปรสภาพแวดล้อมได้:

ansible-playbook -i my_inventory -e "force_tasks=True" my_ansible_playbook.yml

คุณสามารถทำสิ่งนี้ได้ในลักษณะเดียวกันโดยใช้แท็ก

person Rico    schedule 07.02.2014
comment
แทงค์ ริโก้. นั่นคือแนวทางที่ฉันเกือบจะทำ ฉันไม่ได้เพิ่มเป็นตัวแปร แต่เป็นแท็ก ฉันรู้สึกว่ามันพอดีตัวมากขึ้น - person Jimmy Kane; 08.02.2014

เรียกใช้ ansible-playbook ด้วยแฟล็ก --force-handlers สิ่งนี้จะบอก Ansible ให้เรียกใช้ตัวจัดการที่อยู่ในคิวแม้ว่างานจะล้มเหลวและการประมวลผลเพิ่มเติมหยุดลง นักพัฒนา Ansible วางแผนที่จะเพิ่มสิ่งนี้เป็นตัวเลือกให้กับไฟล์ ansible.cfg เพื่อให้สามารถตั้งค่าได้ทั่วโลกและลืมไปเลย ฉันไม่รู้ว่ากรอบเวลานั้นคือเท่าไร

person John McNulty    schedule 06.03.2015