อัปเดต Elastic Stack โดยอัตโนมัติด้วย Ansible Playbooks
เผยแพร่แล้ว: 2022-03-11การวิเคราะห์บันทึกสำหรับเครือข่ายที่ประกอบด้วยอุปกรณ์หลายพันเครื่องเคยเป็นงานที่ซับซ้อน ใช้เวลานาน และน่าเบื่อ ก่อนที่ฉันจะตัดสินใจใช้ Elastic Stack เป็นโซลูชันการบันทึกแบบรวมศูนย์ มันพิสูจน์แล้วว่าเป็นการตัดสินใจที่ฉลาดมาก ฉันไม่เพียงมีที่เดียวในการค้นหาบันทึกทั้งหมดของฉัน แต่ฉันได้ผลลัพธ์ในการค้นหาเกือบทันที การแสดงภาพที่ทรงพลังซึ่งมีประโยชน์อย่างเหลือเชื่อสำหรับการวิเคราะห์และการแก้ไขปัญหา และแดชบอร์ดที่สวยงามที่ให้ภาพรวมที่มีประโยชน์ของเครือข่าย
Elastic Stack ออกคุณลักษณะใหม่ๆ ที่น่าทึ่งอย่างต่อเนื่อง ทำให้การพัฒนาเป็นไปอย่างรวดเร็ว โดยมักจะมีการเปิดตัวใหม่สองรายการทุกเดือน ฉันชอบที่จะทำให้สภาพแวดล้อมของฉันเป็นปัจจุบันอยู่เสมอเพื่อให้แน่ใจว่าฉันสามารถใช้ประโยชน์จากคุณลักษณะและการปรับปรุงใหม่ๆ ได้ นอกจากนี้เพื่อให้ปราศจากข้อบกพร่องและปัญหาด้านความปลอดภัย แต่สิ่งนี้ต้องการให้ฉันอัปเดตสภาพแวดล้อมอยู่ตลอดเวลา
แม้ว่าเว็บไซต์ Elastic จะเก็บรักษาเอกสารประกอบที่ชัดเจนและมีรายละเอียด รวมถึงกระบวนการอัปเกรดผลิตภัณฑ์ของตน การอัปเกรดด้วยตนเองเป็นงานที่ซับซ้อน โดยเฉพาะคลัสเตอร์ Elasticsearch มีขั้นตอนมากมายที่เกี่ยวข้องและต้องปฏิบัติตามคำสั่งที่เฉพาะเจาะจงมาก นั่นคือเหตุผลที่ฉันตัดสินใจทำให้กระบวนการทั้งหมดเป็นแบบอัตโนมัติเมื่อนานมาแล้ว โดยใช้ Ansible Playbooks
ในบทช่วยสอน Ansible นี้ ฉันจะอธิบายชุดของ Ansible Playbooks ที่พัฒนาขึ้นเพื่ออัปเกรดการติดตั้ง Elastic Stack ของฉันโดยอัตโนมัติ
Elastic Stack คืออะไร
Elastic Stack เดิมเรียกว่า ELK stack ประกอบด้วย Elasticsearch, Logstash และ Kibana จากบริษัทโอเพ่นซอร์ส Elastic ซึ่งรวมกันเป็นแพลตฟอร์มที่ทรงพลังสำหรับการจัดทำดัชนี ค้นหา และวิเคราะห์ข้อมูลของคุณ สามารถใช้งานได้หลากหลาย ตั้งแต่การบันทึกและการวิเคราะห์ความปลอดภัยไปจนถึงการจัดการประสิทธิภาพของแอปพลิเคชันและการค้นหาไซต์
Elasticsearch เป็นแกนหลักของสแต็ก เป็นเครื่องมือค้นหาและการวิเคราะห์แบบกระจายที่สามารถให้ผลการค้นหาที่ใกล้เคียงแบบเรียลไทม์ แม้จะเทียบกับข้อมูลที่เก็บไว้ปริมาณมหาศาล
Logstash เป็นไปป์ไลน์การประมวลผลที่ได้รับหรือรับข้อมูลจากแหล่งต่าง ๆ (ปลั๊กอินอินพุตอย่างเป็นทางการ 50 ตัวในขณะที่ฉันกำลังเขียน) แยกวิเคราะห์ กรองและแปลง และส่งไปยังเอาต์พุตที่เป็นไปได้อย่างน้อยหนึ่งรายการ ในกรณีของเรา เราสนใจปลั๊กอินผลลัพธ์ของ Elasticsearch
Kibana คือส่วนหน้าผู้ใช้และการดำเนินการของคุณ ช่วยให้คุณเห็นภาพ ค้นหา นำทางข้อมูลของคุณ และสร้างแดชบอร์ดที่ให้ข้อมูลเชิงลึกที่น่าอัศจรรย์แก่คุณ
Ansible คืออะไร
Ansible เป็นแพลตฟอร์มระบบอัตโนมัติด้านไอทีที่สามารถใช้ในการกำหนดค่าระบบ ปรับใช้หรืออัพเกรดซอฟต์แวร์ และจัดการงานด้านไอทีที่ซับซ้อน เป้าหมายหลักคือความเรียบง่ายและใช้งานง่าย ฟีเจอร์ที่ฉันโปรดปรานของ Ansible คือไม่มีเอเจนต์ หมายความว่าฉันไม่จำเป็นต้องติดตั้งและจัดการซอฟต์แวร์พิเศษใดๆ บนโฮสต์และอุปกรณ์ที่ฉันต้องการจัดการ เราจะใช้พลังของระบบอัตโนมัติของ Ansible เพื่ออัปเกรด Elastic Stack ของเราโดยอัตโนมัติ
ข้อจำกัดความรับผิดชอบและคำเตือน
playbooks ที่ฉันจะแบ่งปันที่นี่มีพื้นฐานมาจากขั้นตอนที่อธิบายไว้ในเอกสารของผลิตภัณฑ์อย่างเป็นทางการ มีไว้เพื่อใช้สำหรับการอัปเกรดเวอร์ชันหลักเดียวกันเท่านั้น ตัวอย่างเช่น: 5.x
→ 5.y
หรือ 6.x
→ 6.y
โดยที่ x
> y
การอัปเกรดระหว่างเวอร์ชันหลักมักต้องมีขั้นตอนเพิ่มเติม และคู่มือการใช้งานเหล่านั้นจะไม่ทำงานในกรณีเหล่านั้น
โดยไม่คำนึงถึง ให้อ่านบันทึกประจำรุ่นเสมอ โดยเฉพาะอย่างยิ่งส่วนการเปลี่ยนแปลงที่แตกหักก่อนใช้ playbooks เพื่ออัปเกรด ตรวจสอบให้แน่ใจว่าคุณเข้าใจงานที่ทำใน playbook และตรวจสอบคำแนะนำในการอัพเกรดเสมอเพื่อให้แน่ใจว่าไม่มีการเปลี่ยนแปลงที่สำคัญ
ต้องบอกว่าฉันใช้ playbook เหล่านั้น (หรือเวอร์ชันก่อนหน้า) ตั้งแต่เวอร์ชัน 2.2 ของ Elasticsearch โดยไม่มีปัญหาใดๆ ในขณะที่ฉันมี playbooks แยกต่างหากสำหรับแต่ละผลิตภัณฑ์ เนื่องจากพวกเขาไม่ได้ใช้หมายเลขเวอร์ชันเดียวกันกับที่พวกเขารู้
ต้องบอกว่าฉันไม่รับผิดชอบในทางใด ๆ ต่อการใช้ข้อมูลที่มีอยู่ในบทความนี้ของคุณ
สภาพแวดล้อมที่สมมติขึ้นของเรา
สภาพแวดล้อมที่ playbook ของเราจะใช้งานจะประกอบด้วยเซิร์ฟเวอร์ CentOS 7 6 ตัว:
- 1 x เซิร์ฟเวอร์ Logstash
- 1 x เซิร์ฟเวอร์ Kibana
- 4 x โหนด Elasticsearch
ไม่สำคัญว่าสภาพแวดล้อมของคุณมีจำนวนเซิร์ฟเวอร์ต่างกันหรือไม่ คุณสามารถสะท้อนให้เห็นตามนั้นในไฟล์สินค้าคงคลังและ playbook ควรจะทำงานโดยไม่มีปัญหา อย่างไรก็ตาม หากคุณไม่ได้ใช้การแจกแจงแบบ RHEL ฉันจะปล่อยให้มันเป็นแบบฝึกหัดให้คุณเปลี่ยนงานบางอย่างที่เป็นการแจกจ่ายเฉพาะ (ส่วนใหญ่เป็นของตัวจัดการแพ็คเกจ)
สินค้าคงคลัง
Ansible ต้องการสินค้าคงคลังเพื่อทราบว่าควรเรียกใช้ playbooks กับโฮสต์ใด สี่สถานการณ์สมมติของเรา เราจะใช้ไฟล์สินค้าคงคลังต่อไปนี้:
[logstash] server01 ansible_host=10.0.0.1 [kibana] server02 ansible_host=10.0.0.2 [elasticsearch] server03 ansible_host=10.0.0.3 server04 ansible_host=10.0.0.4 server05 ansible_host=10.0.0.5 server06 ansible_host=10.0.0.6
ในไฟล์สินค้าคงคลังของ Ansible [section]
ใด ๆ แสดงถึงกลุ่มของโฮสต์ สินค้าคงคลังของเรามีโฮสต์ 3 กลุ่ม: logstash
, kibana
และ elasticsearch
คุณจะสังเกตเห็นว่าฉันใช้เฉพาะชื่อกลุ่มใน playbooks นั่นหมายความว่าไม่สำคัญว่าจำนวนโฮสต์ในสินค้าคงคลังจะมากน้อยเพียงใด ตราบใดที่กลุ่มถูกต้อง เพลย์บุ๊กก็จะทำงาน
กระบวนการอัพเกรด
กระบวนการอัปเกรดจะประกอบด้วยขั้นตอนต่อไปนี้:
1) ดาวน์โหลดแพ็คเกจล่วงหน้า
2) การอัพเกรด Logstash
3) Rolling Upgrade ของคลัสเตอร์ Elasticsearch
4) อัพเกรดคิบานะ
เป้าหมายหลักคือการลดการหยุดทำงานให้น้อยที่สุด ส่วนใหญ่ผู้ใช้จะไม่สังเกตเห็น บางครั้ง Kibana อาจใช้งานไม่ได้สักสองสามวินาที นั่นเป็นที่ยอมรับของฉัน
หลัก Ansible Playbook
กระบวนการอัปเกรดประกอบด้วยชุดคู่มือการเล่นต่างๆ ฉันจะใช้คุณสมบัติ import_playbook ของ Ansible เพื่อจัดระเบียบ playbook ทั้งหมดในไฟล์ playbook หลักไฟล์เดียวที่สามารถเรียกให้ดูแลกระบวนการทั้งหมดได้
- name: pre-download import_playbook: pre-download.yml - name: logstash-upgrade import_playbook: logstash-upgrade.yml - name: elasticsearch-rolling-upgrade import_playbook: elasticsearch-rolling-upgrade.yml - name: kibana-upgrade import_playbook: kibana-upgrade.yml
ค่อนข้างง่าย มันเป็นเพียงวิธีการจัดระเบียบการดำเนินการของ playbooks ในลำดับเฉพาะอย่างใดอย่างหนึ่ง
ตอนนี้ มาพิจารณาว่าเราจะใช้ตัวอย่างคู่มือการเล่น Ansible ด้านบนอย่างไร ฉันจะอธิบายวิธีที่เราใช้ในภายหลัง แต่นี่คือคำสั่งที่ฉันจะดำเนินการเพื่ออัปเกรดเป็นเวอร์ชัน 6.5.4:
$ ansible-playbook -i inventory -e elk_version=6.5.4 main.yml
ดาวน์โหลดแพ็คเกจล่วงหน้า
ขั้นตอนแรกนั้นเป็นทางเลือกจริง ๆ เหตุผลที่ฉันใช้สิ่งนี้คือฉันพิจารณาแนวปฏิบัติที่ดีโดยทั่วไปในการหยุดบริการที่ทำงานอยู่ก่อนที่จะอัปเกรด ตอนนี้ หากคุณมีการเชื่อมต่ออินเทอร์เน็ตที่รวดเร็ว เวลาสำหรับตัวจัดการแพ็คเกจในการดาวน์โหลดแพ็คเกจนั้นอาจจะเล็กน้อย แต่นั่นไม่ใช่กรณีเสมอไป และฉันต้องการลดระยะเวลาที่บริการใด ๆ หยุดทำงานให้เหลือน้อยที่สุด นั่นเป็นวิธีที่ playbook เล่มแรกของฉันจะใช้ yum เพื่อดาวน์โหลดแพ็คเกจทั้งหมดล่วงหน้า ด้วยวิธีนี้เมื่อถึงเวลาอัปเกรด ขั้นตอนการดาวน์โหลดจะได้รับการดูแลแล้ว
- hosts: logstash gather_facts: no tasks: - name: Validate logstash Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+") - name: Get logstash current version command: rpm -q logstash --qf %{VERSION} args: warn: no changed_when: False register: version_found - name: Pre-download logstash install package yum: name: logstash-{{ elk_version }} download_only: yes when: version_found.stdout is version_compare(elk_version, '<')
บรรทัดแรกระบุว่าการเล่นนี้จะใช้กับกลุ่ม logstash
เท่านั้น บรรทัดที่สองบอกให้ Ansible ไม่ต้องรวบรวมข้อเท็จจริงเกี่ยวกับโฮสต์ สิ่งนี้จะเร่งการเล่น แต่ตรวจสอบให้แน่ใจว่าไม่มีงานใดในการเล่นจะต้องข้อเท็จจริงใด ๆ เกี่ยวกับโฮสต์
งานแรกในการเล่นจะตรวจสอบตัวแปร elk_version
ตัวแปรนี้แสดงถึงเวอร์ชันของ Elastic Stack ที่เรากำลังอัปเกรดเป็น ที่ถูกส่งผ่านไปเมื่อคุณเรียกใช้คำสั่ง ansible-playbook หากตัวแปรไม่ผ่านหรือไม่ใช่รูปแบบที่ถูกต้อง การเล่นจะประกันตัวทันที งานนั้นจะเป็นงานแรกในบทละครทั้งหมด เหตุผลก็คือเพื่อให้การเล่นถูกแยกออกมาหากต้องการหรือจำเป็น
งานที่สองจะใช้คำสั่ง rpm
เพื่อรับเวอร์ชันปัจจุบันของ Logstash และลงทะเบียนในตัวแปร version_found
ข้อมูลนั้นจะถูกนำไปใช้ในงานต่อไป บรรทัด args:
, warn: no
และ changed_when: False
มีไว้เพื่อทำให้ ansible-lint มีความสุข แต่ไม่จำเป็นอย่างยิ่ง
งานสุดท้ายจะรันคำสั่งที่ดาวน์โหลดแพ็คเกจล่วงหน้าจริง ๆ แต่เฉพาะในกรณีที่ Logstash เวอร์ชันที่ติดตั้งเก่ากว่าเวอร์ชันเป้าหมาย ไม่ใช่จุดดาวน์โหลดและรุ่นเก่าหรือรุ่นเดียวกันหากจะไม่ถูกใช้งาน
บทละครอีกสองรายการจะเหมือนกันโดยพื้นฐานแล้ว ยกเว้นว่าแทนที่จะเป็น Logstash พวกเขาจะดาวน์โหลด Elasticsearch และ Kibana ล่วงหน้า:
- hosts: elasticsearch gather_facts: no tasks: - name: Validate elasticsearch Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+") - name: Get elasticsearch current version command: rpm -q elasticsearch --qf %{VERSION} args: warn: no changed_when: False register: version_found - name: Pre-download elasticsearch install package yum: name: elasticsearch-{{ elk_version }} download_only: yes when: version_found.stdout is version_compare(elk_version, '<') - hosts: kibana gather_facts: no tasks: - name: Validate kibana Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+") - name: Get kibana current version command: rpm -q kibana --qf %{VERSION} args: warn: no changed_when: False register: version_found - name: Pre-download kibana install package yum: name: kibana-{{ elk_version }} download_only: yes when: version_found.stdout is version_compare(elk_version, '<')
การอัพเกรด Logstash
Logstash ควรเป็นองค์ประกอบแรกที่จะอัพเกรด นั่นเป็นเพราะว่า Logstash รับประกันว่าจะทำงานร่วมกับ Elasticsearch เวอร์ชันเก่าได้
งานแรกของการเล่นจะเหมือนกับงานที่ดาวน์โหลดล่วงหน้า:
- name: Upgrade logstash hosts: logstash gather_facts: no tasks: - name: Validate ELK Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+") - name: Get logstash current version command: rpm -q logstash --qf %{VERSION} changed_when: False register: version_found
งานสุดท้ายสองงานมีอยู่ในบล็อก:
- block: - name: Update logstash yum: name: logstash-{{ elk_version }} state: present - name: Restart logstash systemd: name: logstash state: restarted enabled: yes daemon_reload: yes when: version_found.stdout is version_compare(elk_version, '<')
เงื่อนไข when
รับประกันว่างานในบล็อกจะถูกดำเนินการก็ต่อเมื่อเวอร์ชันเป้าหมายใหม่กว่าเวอร์ชันปัจจุบัน งานแรกภายในบล็อกทำการอัพเกรด Logstash และงานที่สองเริ่มบริการใหม่

Elasticsearch Cluster Rolling Upgrade
เพื่อให้แน่ใจว่าจะไม่มีการหยุดทำงานของคลัสเตอร์ Elasticsearch เราต้องทำการอัพเกรดแบบต่อเนื่อง ซึ่งหมายความว่าเราจะอัปเกรดครั้งละหนึ่งโหนด โดยเริ่มต้นการอัพเกรดของโหนดใดๆ หลังจากที่เราแน่ใจว่าคลัสเตอร์อยู่ในสถานะสีเขียว (สมบูรณ์สมบูรณ์) เท่านั้น
ตั้งแต่เริ่มเล่น คุณจะสังเกตเห็นบางสิ่งที่แตกต่างออกไป:
- name: Elasticsearch rolling upgrade hosts: elasticsearch gather_facts: no serial: 1
ที่นี่เรามี serial: 1
. พฤติกรรมเริ่มต้นของ Ansible คือการดำเนินการเล่นกับหลายโฮสต์พร้อมกัน จำนวนโฮสต์พร้อมกันที่กำหนดไว้ในการกำหนดค่า บรรทัดนี้ทำให้แน่ใจว่าการเล่นจะดำเนินการกับโฮสต์ครั้งละหนึ่งโฮสต์เท่านั้น
ต่อไป เรากำหนดตัวแปรสองสามตัวที่จะใช้ในการเล่น:
vars: es_disable_allocation: '{"transient":{"cluster.routing.allocation.enable":"none"}}' es_enable_allocation: '{"transient":{"cluster.routing.allocation.enable": "all","cluster.routing.allocation.node_concurrent_recoveries": 5,"indices.recovery.max_bytes_per_sec": "500mb"}}' es_http_port: 9200 es_transport_port: 9300
ความหมายของตัวแปรแต่ละตัวจะมีความชัดเจนตามที่ปรากฏในบทละคร
เช่นเคย งานแรกคือการตรวจสอบเวอร์ชันเป้าหมาย:
tasks: - name: Validate ELK Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+")
งานต่อไปนี้จำนวนมากจะประกอบด้วยการเรียก REST กับคลัสเตอร์ Elasticsearch สามารถดำเนินการเรียกกับโหนดใดก็ได้ คุณสามารถดำเนินการกับโฮสต์ปัจจุบันในการเล่นได้ แต่บางคำสั่งจะถูกดำเนินการในขณะที่บริการ Elasticsearch หยุดทำงานสำหรับโฮสต์ปัจจุบัน ดังนั้น ในงานต่อไป เราตรวจสอบให้แน่ใจว่าได้เลือกโฮสต์อื่นเพื่อเรียกใช้ REST สำหรับสิ่งนี้ เราจะใช้โมดูล set_fact และตัวแปรกลุ่มจากคลัง Ansible
- name: Set the es_host for the first host set_fact: es_host: "{{ groups.elasticsearch[1] }}" when: "inventory_hostname == groups.elasticsearch[0]" - name: Set the es_host for the remaining hosts set_fact: es_host: "{{ groups.elasticsearch[0] }}" when: "inventory_hostname != groups.elasticsearch[0]"
ต่อไป เราตรวจสอบให้แน่ใจว่าบริการอยู่ในโหนดปัจจุบันก่อนที่จะดำเนินการต่อ:
- name: Ensure elasticsearch service is running systemd: name: elasticsearch enabled: yes state: started register: response - name: Wait for elasticsearch node to come back up if it was stopped wait_for: port: "{{ es_transport_port }}" delay: 45 when: response.changed == true
เช่นเดียวกับในละครก่อนหน้านี้ เราจะตรวจสอบเวอร์ชันปัจจุบัน ยกเว้นคราวนี้ เราจะใช้ Elasticsearch REST API แทนการรัน rpm เราสามารถใช้คำสั่ง rpm ได้เช่นกัน แต่ฉันต้องการแสดงทางเลือกนี้
- name: Check current version uri: url: http://localhost:{{ es_http_port }} method: GET register: version_found retries: 10 delay: 10
งานที่เหลืออยู่ภายในบล็อกที่จะดำเนินการได้ก็ต่อเมื่อเวอร์ชันปัจจุบันเก่ากว่าเวอร์ชันเป้าหมาย:
- block: - name: Enable shard allocation for the cluster uri: url: http://localhost:{{ es_http_port }}/_cluster/settings method: PUT body_format: json body: "{{ es_enable_allocation }}"
ตอนนี้ หากคุณทำตามคำแนะนำของฉันและอ่านเอกสารประกอบ คุณจะสังเกตเห็นว่าขั้นตอนนี้ควรตรงกันข้าม: เพื่อปิดใช้งานการจัดสรรส่วนแบ่งข้อมูล ฉันชอบที่จะวางงานนี้ไว้ที่นี่ก่อนในกรณีที่ชาร์ดถูกปิดใช้งานก่อนหน้านี้ด้วยเหตุผลบางประการ นี่เป็นสิ่งสำคัญเนื่องจากงานต่อไปจะรอให้คลัสเตอร์กลายเป็นสีเขียว หากปิดใช้การจัดสรรชาร์ด คลัสเตอร์จะยังคงเป็นสีเหลืองและงานจะหยุดทำงานจนกว่าจะหมดเวลา
ดังนั้น หลังจากที่แน่ใจว่าเปิดใช้งานการจัดสรรส่วนแบ่งข้อมูลแล้ว เราตรวจสอบให้แน่ใจว่าคลัสเตอร์อยู่ในสถานะสีเขียว:
- name: Wait for cluster health to return to green uri: url: http://localhost:{{ es_http_port }}/_cluster/health method: GET register: response until: "response.json.status == 'green'" retries: 500 delay: 15
หลังจากเริ่มบริการโหนดใหม่ คลัสเตอร์อาจใช้เวลานานกว่าจะกลับมาเป็นสีเขียว นั่นคือสาเหตุของการ retries: 500
และ delay: 15
หมายความว่าเราจะรอ 125 นาที (500 x 15 วินาที) เพื่อให้คลัสเตอร์กลับสู่สีเขียว คุณอาจต้องปรับเปลี่ยนหากโหนดของคุณมีข้อมูลจำนวนมากจริงๆ สำหรับกรณีส่วนใหญ่ก็มากเกินพอ
ตอนนี้ เราสามารถปิดใช้งานการจัดสรรส่วนแบ่งข้อมูลได้:
- name: Disable shard allocation for the cluster uri: url: http://localhost:{{ es_http_port }}/_cluster/settings method: PUT body_format: json body: {{ es_disable_allocation }}
และก่อนที่จะปิดบริการ เราดำเนินการล้างข้อมูลการซิงค์ที่ไม่บังคับ แต่แนะนำ ไม่ใช่เรื่องแปลกที่จะได้รับข้อผิดพลาด 409 สำหรับดัชนีบางตัวเมื่อเราทำการซิงค์ฟลัช เนื่องจากสามารถเพิกเฉยได้อย่างปลอดภัย ฉันจึงเพิ่ม 409 ลงในรายการรหัสสถานะความสำเร็จ
- name: Perform a synced flush uri: url: http://localhost:{{ es_http_port }}/_flush/synced method: POST status_code: "200, 409"
ตอนนี้โหนดนี้พร้อมที่จะอัปเกรดแล้ว:
- name: Shutdown elasticsearch node systemd: name: elasticsearch state: stopped - name: Update elasticsearch yum: name: elasticsearch-{{ elk_version }} state: present
เมื่อบริการหยุดลง เรารอให้ชาร์ดทั้งหมดได้รับการจัดสรรก่อนที่จะเริ่มโหนดอีกครั้ง:
- name: Wait for all shards to be reallocated uri: url=http://{{ es_host }}:{{ es_http_port }}/_cluster/health method=GET register: response until: "response.json.relocating_shards == 0" retries: 20 delay: 15
หลังจากที่ชาร์ดได้รับการจัดสรรใหม่ เราจะเริ่มบริการ Elasticsearch ใหม่และรอให้พร้อมโดยสมบูรณ์:
- name: Start elasticsearch systemd: name: elasticsearch state: restarted enabled: yes daemon_reload: yes - name: Wait for elasticsearch node to come back up wait_for: port: "{{ es_transport_port }}" delay: 35 - name: Wait for elasticsearch http to come back up wait_for: port: "{{ es_http_port }}" delay: 5
ตอนนี้ เราตรวจสอบให้แน่ใจว่าคลัสเตอร์เป็นสีเหลืองหรือสีเขียวก่อนเปิดใช้งานการจัดสรรชาร์ดอีกครั้ง:
- name: Wait for cluster health to return to yellow or green uri: url: http://localhost:{{ es_http_port }}/_cluster/health method: GET register: response until: "response.json.status == 'yellow' or response.json.status == 'green'" retries: 500 delay: 15 - name: Enable shard allocation for the cluster uri: url: http://localhost:{{ es_http_port }}/_cluster/settings method: PUT body_format: json body: "{{ es_enable_allocation }}" register: response until: "response.json.acknowledged == true" retries: 10 delay: 15
และเรารอให้โหนดฟื้นตัวเต็มที่ก่อนที่จะดำเนินการต่อไป:
- name: Wait for the node to recover uri: url: http://localhost:{{ es_http_port }}/_cat/health method: GET return_content: yes register: response until: "'green' in response.content" retries: 500 delay: 15
แน่นอน อย่างที่ฉันพูดไปก่อนหน้านี้ บล็อกนี้ควรจะทำงานก็ต่อเมื่อเราอัปเกรดเวอร์ชันจริงๆ เท่านั้น:
when: version_found.json.version.number is version_compare(elk_version, '<')
Kibana อัพเกรด
องค์ประกอบสุดท้ายที่จะอัพเกรดคือ Kibana
อย่างที่คุณคาดไว้ งานแรกไม่แตกต่างจากการอัปเกรด Logstash หรือการเล่นล่วงหน้า ยกเว้นคำจำกัดความของตัวแปรเดียว:
- name: Upgrade kibana hosts: kibana gather_facts: no vars: set_default_index: '{"changes":{"defaultIndex":"syslog"}}' tasks: - name: Validate ELK Version fail: msg="Invalid ELK Version" when: elk_version is undefined or not elk_version is match("\d+\.\d+\.\d+") - name: Get kibana current version command: rpm -q kibana --qf %{VERSION} args: warn: no changed_when: False register: version_found
ฉันจะอธิบายตัวแปร set_default_index
เมื่อเราไปถึงงานที่ใช้มัน
งานที่เหลือจะอยู่ภายในบล็อกที่จะดำเนินการก็ต่อเมื่อ Kibana เวอร์ชันที่ติดตั้งเก่ากว่าเวอร์ชันเป้าหมายเท่านั้น สองงานแรกจะอัปเดตและรีสตาร์ท Kibana:
- name: Update kibana yum: name: kibana-{{ elk_version }} state: present - name: Restart kibana systemd: name: kibana state: restarted enabled: yes daemon_reload: yes
และสำหรับคิบานะก็น่าจะเพียงพอแล้ว น่าเสียดาย ด้วยเหตุผลบางอย่าง หลังจากการอัปเกรด Kibana สูญเสียการอ้างอิงถึงรูปแบบดัชนีเริ่มต้น สิ่งนี้ทำให้ต้องขอผู้ใช้คนแรกที่เข้าถึงหลังจากการอัปเกรดเพื่อกำหนดรูปแบบดัชนีเริ่มต้น ซึ่งอาจทำให้เกิดความสับสน เพื่อหลีกเลี่ยงปัญหานี้ ให้รวมงานเพื่อรีเซ็ตรูปแบบดัชนีเริ่มต้น ในตัวอย่างด้านล่าง มันคือ syslog
แต่คุณควรเปลี่ยนเป็นอะไรก็ได้ที่คุณใช้ ก่อนตั้งค่าดัชนี เราต้องตรวจสอบให้แน่ใจว่า Kibana พร้อมใช้งานและพร้อมที่จะให้บริการตามคำขอ:
- name: Wait for kibana to start listening wait_for: port: 5601 delay: 5 - name: Wait for kibana to be ready uri: url: http://localhost:5601/api/kibana/settings method: GET register: response until: "'kbn_name' in response and response.status == 200" retries: 30 delay: 5 - name: Set Default Index uri: url: http://localhost:5601/api/kibana/settings method: POST body_format: json body: "{{ set_default_index }}" headers: "kbn-version": "{{ elk_version }}"
บทสรุป
Elastic Stack เป็นเครื่องมือที่มีค่า และฉันแนะนำให้คุณลองดูถ้าคุณยังไม่ได้ใช้งาน มันยอดเยี่ยมอย่างที่มันเป็นและปรับปรุงอย่างต่อเนื่อง มากจนอาจเป็นเรื่องยากที่จะติดตามการอัปเกรดอย่างต่อเนื่อง ฉันหวังว่า Ansible Playbooks เหล่านั้นอาจมีประโยชน์สำหรับคุณเช่นเดียวกับฉัน
ฉันทำให้มันพร้อมใช้งานบน GitHub ที่ https://github.com/orgito/elk-upgrade ฉันแนะนำให้คุณทดสอบในสภาพแวดล้อมที่ไม่ใช่การผลิต
หากคุณเป็นนักพัฒนา Ruby on Rails ที่ต้องการรวม Elasticsearch ไว้ในแอพของคุณ ลองดู Elasticsearch สำหรับ Ruby on Rails: บทช่วยสอนเกี่ยวกับ Chewy Gem โดย Core Toptal Software Engineer Arkadiy Zabazhanov