ค้นหาเว็บไซต์

วิธีสร้างบทละครและ Playbooks แบบ Ansible - ตอนที่ 5


ใน ส่วนที่ 5 ของซีรีส์ Ansible นี้ เราจะอธิบายวิธีสร้าง Ansible Plays และ Playbooks โดยใช้โมดูล Ansible

Ansible มาพร้อมกับสคริปต์แบบสแตนด์อโลนที่เรียกว่า โมดูล ที่ใช้ใน คู่มือการเล่น สำหรับการดำเนินงานพิเศษบนโหนดระยะไกล

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

วัตถุประสงค์ของหัวข้อย่อยนี้คือเพื่อให้คุณเห็นภาพรวมของงานต่างๆ ที่สามารถทำได้โดย โมดูล Ansible:

การจัดการแพ็คเกจใน Linux

การจัดการแพ็คเกจเป็นหนึ่งในงานที่สำคัญที่สุดและบ่อยครั้งที่สุดที่ผู้ดูแลระบบดำเนินการ Ansible มาพร้อมกับโมดูลที่ช่วยให้คุณดำเนินงานการจัดการแพ็คเกจทั้งในระบบที่ใช้ RedHat และ Debian

พวกมันค่อนข้างเดาง่าย มี โมดูล apt สำหรับการจัดการแพ็คเกจ APT สำหรับ Debian, โมดูล yum เก่าสำหรับการจัดการแพ็คเกจ YUM และ โมดูล dnf ที่เกี่ยวข้องกับการกระจาย RHEL ที่ใหม่กว่า .

ด้านล่างนี้เป็นตัวอย่างเล็กๆ น้อยๆ ของวิธีการใช้โมดูลใน Playbook:

ตัวอย่างที่ 1: การติดตั้ง Apache Webserver บน RHEL 8

---
- name: install Apache webserver
  hosts: webservers

  tasks:
       - name: install httpd
         dnf:  
          name: httpd  
          State: latest

ตัวอย่างที่ 2: การติดตั้ง Apache Webserver บน Debian 10

---
- name: install Apache webserver
  hosts: databases

  tasks:
       - name: install Apache webserver
         apt:  
          name: apache2  
          State: latest

โมดูลการบริการ

โมดูลบริการช่วยให้ผู้ดูแลระบบสามารถเริ่ม หยุด อัปเดต อัปเกรด และโหลดบริการบนระบบได้

ตัวอย่างที่ 1: การเริ่มต้น Apache Webserver

---
- name: Start service httpd, if not started
  service:
    name: httpd
    state: started

ตัวอย่างที่ 2: การหยุด Apache Webserver

---
- name: Stop service httpd
  service:
    name: httpd
    state: stopped

ตัวอย่างที่ 3: การรีสตาร์ทอินเทอร์เฟซเครือข่าย enp2s0

---
- name: Restart network service for interface eth0
  service:
    name: network
    state: restarted
    args: enp2s0

โมดูลการคัดลอก

ตามชื่อที่แนะนำ โมดูลการคัดลอกจะคัดลอกไฟล์จากตำแหน่งหนึ่งบนเครื่องระยะไกลไปยังตำแหน่งอื่นบนเครื่องเดียวกัน

ตัวอย่างที่ 1: การคัดลอกไฟล์จาก Local ไปยัง Remote Linux

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

Playbook คัดลอกไฟล์กำหนดค่า tecmint.conf จากไดเรกทอรี /etc/files/ ไปยังไดเรกทอรี /srv/ เป็น tecmint ผู้ใช้ที่มีสิทธิ์ 0644

การอนุญาตสามารถแสดงได้โดยใช้การแสดงสัญลักษณ์ตามที่แสดงในบรรทัดสุดท้าย

ตัวอย่างที่ 2: การคัดลอกไฟล์จาก Local ไปยัง Remote Linux

---
- name: Copy file with owner and permissions
  copy:
    src: /etc/files/tecmint.conf
    dest: /srv/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: u=rw, g=r, o=r

สิทธิ์ในตัวอย่างก่อนหน้านี้สามารถแสดงตามที่แสดงในบรรทัดสุดท้าย ผู้ใช้ได้รับสิทธิ์ อ่าน และ เขียน กลุ่มได้รับมอบหมายสิทธิ์ในการเขียน และส่วนที่เหลือของ โลกได้รับมอบหมายสิทธิ์ในการอ่าน

โมดูลไฟล์

โมดูลไฟล์ใช้เพื่อดำเนินการกับไฟล์หลายอย่าง รวมถึงการสร้างไฟล์และไดเร็กทอรี การกำหนดสิทธิ์ของไฟล์ และการตั้งค่าลิงก์สัญลักษณ์

ตัวอย่างที่ 1: ดำเนินการอนุญาตไฟล์ Linux

---
- name: Change file ownership, group, and permissions
  file:
    path: /etc/tecmint.conf
    owner: tecmint
    group: tecmint
    mode: '0644'

การเล่นข้างต้นจะสร้างไฟล์ชื่อ tecmint.conf ในไดเรกทอรี /etc โดยตั้งค่าสิทธิ์เป็น 0644

ตัวอย่างที่ 2: ลบไฟล์ Linux

---
- name: Remove file (delete file)
  file:
    path: /etc/tecmint.conf
    state: absent

การดำเนินการนี้จะลบหรือลบไฟล์ tecmint.conf

ตัวอย่างที่ 3: สร้างไดเร็กทอรี

---
- name: create a directory if it doesn’t exist
  file:
    path: /etc/mydirectory
    State: directory
    mode: '0777'

สิ่งนี้จะสร้างไดเรกทอรีในการตั้งค่าไดเรกทอรี /etc เป็น 0777

ตัวอย่างที่ 4: ลบไดเรกทอรีแบบวนซ้ำ

---
- name: Recursively deleting a  directory
  file:
    path: /etc/tecmint.conf
    state: absent

การเล่นข้างต้นจะลบไดเร็กทอรีซ้ำ

โมดูล Lineinfile

โมดูล lineinfile มีประโยชน์เมื่อคุณต้องการเปลี่ยนบรรทัดเดียวในไฟล์ สามารถแทนที่เส้นที่มีอยู่ได้

ตัวอย่างที่ 1: จัดการไฟล์ใน Linux

---
 - name: Ensure SELinux is set to enforcing mode
  lineinfile:
    path: /etc/selinux/config
    regexp: '^SELINUX='
    line: SELINUX=disabled

การเล่นด้านบนตั้งค่า SELINUX เป็น ปิดใช้งาน

SELINUX=disabled

ตัวอย่างที่ 2: แก้ไขไฟล์ใน Linux

---
- name: Add a line to a file if the file does not exist, without         passing regexp
  lineinfile:
    path: /etc/hosts
    line: 10.200.50.51 linux-console.net
    create: yes

ซึ่งจะเป็นการเพิ่มรายการ 10.200.50.51 linux-console.net ไปยังไฟล์ /etc/hosts

โมดูลเอกสารเก่า

โมดูล ไฟล์เก็บถาวร ใช้สำหรับการสร้างไฟล์เก็บถาวรแบบบีบอัดของไฟล์เดียวหรือหลายไฟล์ โดยถือว่าแหล่งที่มาของการบีบอัดนั้นมีอยู่บนปลายทางเป้าหมาย หลังจากเก็บถาวร ไฟล์ต้นฉบับสามารถลบหรือลบออกได้ในภายหลังโดยใช้คำสั่ง remove=True

ตัวอย่างที่ 1: สร้างไฟล์เก็บถาวร

- name: Compress directory /path/to/tecmint_dir/ into /path/to/tecmint.tgz
  archive:
    path: /path/to/tecmint_dir
    dest: /path/to/tecmint.tgz

This compresses the /path/to/tecmint_dir  directory to /path/to/tecmint.tgz

ตัวอย่างที่ 2: สร้างไฟล์เก็บถาวรและลบออก

- name: Compress regular file /path/to/tecmint into /path/to/foo.gz and remove it
  archive:
    path: /path/to/tecmint
    dest: /path/to/tecmint.tgz
    remove: yes

ในการเล่นข้างต้น ไฟล์ต้นฉบับ /path/to/tecmint จะถูกลบหลังจากการเก็บถาวรเสร็จสมบูรณ์

ตัวอย่างที่ 3: สร้างไฟล์เก็บถาวร

- name: Create a bz2 archive of /path/to/tecmint
  archive:
    path: /path/to/tecmint
    format: bz2

ซึ่งจะสร้างไฟล์บีบอัดในรูปแบบ bz2 จากไฟล์ /path/to/tecmint

โมดูล Git

โมดูลจะจัดการการชำระเงิน git ของที่เก็บซอฟต์แวร์

ตัวอย่างที่ 1: ตรวจสอบที่เก็บ Git

- git:
    repo: 'https://foosball.example.org/path/to/repo.git'
    dest: /srv/checkout
    version: release-0.22

โมดูลคำสั่ง

โมดูล command หนึ่งในโมดูลที่ใช้บ่อยที่สุด ใช้ชื่อคำสั่งและตามด้วยรายการอาร์กิวเมนต์ในภายหลัง คำสั่งนี้เป็นการส่งผ่านแบบเดียวกับที่คุณพิมพ์ในเชลล์ Linux

ตัวอย่างที่ 1: เรียกใช้คำสั่ง

- name: Executing a command using the command module
  command: cat helloworld.txt

ตัวอย่างที่ 2: ตรวจสอบเวลาทำงานของ Remote Linux

---
 - name: Check the remote host uptime
    hosts: servers
    tasks:
      - name: Execute the Uptime command over Command module
        register: uptimeoutput
        command: "uptime"

- debug:
          var: uptimeoutput.stdout_lines

โมดูลคำสั่งดึงข้อมูลสถานะการออนไลน์ของเซิร์ฟเวอร์ระยะไกล

ตัวแปรเพื่อดึงผลลัพธ์ของการรันคำสั่ง

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

รีจิสเตอร์แบบ ansible ใช้สำหรับจับเอาต์พุตของงานและบันทึกเป็นตัวแปร หลังจากนั้นตัวแปรจะมี stdout ของงาน

ตัวอย่างเช่น สมมติว่าคุณต้องการตรวจสอบการใช้งานดิสก์ของโหนดที่ได้รับการจัดการในไดเรกทอรีรากที่เกี่ยวข้องโดยใช้คำสั่ง df -Th / คุณจะใช้โมดูล 'command' เพื่อกำหนดคำสั่งและ 'register' เพื่อบันทึกเอาต์พุต std ในตัวแปร

ในการแสดงคำสั่ง คุณจะใช้โมดูล 'debug' ควบคู่ไปกับค่าส่งคืน stdout

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout

ตอนนี้เรามาเริ่ม Playbook กันดีกว่า ในกรณีนี้ เราได้ตั้งชื่อ Playbook ของเราว่า check_disk_space.yml

ansible-playbook check_disk_space.yml

อย่างที่คุณเห็น ผลลัพธ์ที่ได้จะสับสนวุ่นวายและทำให้ยากต่อการติดตาม

หากต้องการจัดแนวเอาต์พุตและทำให้อ่านง่ายขึ้น ให้แทนที่ค่าที่ส่งคืน stdout ด้วย stdout_lines

---

 - hosts: all
   become: yes

   tasks:
     - name: Execute /boot usage on Hosts
       command: 'df -Th /'
       register: df

     - debug: var=df.stdout_lines

ใช้เงื่อนไขเพื่อควบคุมการดำเนินการเล่น

เช่นเดียวกับในภาษาการเขียนโปรแกรม คำสั่งแบบมีเงื่อนไข จะถูกใช้เมื่อผลลัพธ์ที่เป็นไปได้มากกว่าหนึ่งรายการ มาดูคำสั่งเงื่อนไขที่ใช้กันทั่วไปบางส่วนใน Playbooks ของ Ansible กัน

เมื่อมีคำสั่ง

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

when: condition

เมื่อตรงตามเงื่อนไข งานจะถูกดำเนินการบนระบบรีโมต

ลองดูตัวอย่างบางส่วน:

ตัวอย่างที่ 1: การใช้ When Operator

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian”

การเล่นข้างต้นจะติดตั้งเว็บเซิร์ฟเวอร์ Nginx บนโฮสต์ที่ใช้ตระกูล Distros ของ Debian

คุณยังสามารถใช้ตัวดำเนินการ OR และ AND ควบคู่ไปกับคำสั่ง when แบบมีเงื่อนไข

ตัวอย่างที่ 2: การใช้ AND Operator กับ When

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” and
           ansible_distribution_version == “18.04”

เมื่อใช้ตัวดำเนินการ AND จะต้องตอบสนองทั้งสองคำสั่งจึงจะสามารถดำเนินการได้

การเล่นด้านบนจะติดตั้ง Nginx บนโหนดที่ใช้ระบบปฏิบัติการตระกูล Debian ซึ่งเป็นเวอร์ชัน 18.04 แน่นอนว่านี่คือ Ubuntu 18.04

ตัวอย่างที่ 3: การใช้หรือตัวดำเนินการกับเมื่อใด

ด้วยตัวดำเนินการ OR งานจะถูกดำเนินการหากตรงตามเงื่อนไขข้อใดข้อหนึ่ง

---
- hosts: all

  tasks:
  - name: Install Nginx on Debian
     apt: name=nginx state=present
     when: ansible_os_family == “Debian” or
	      Ansible_os_family == “SUSE”

การเล่นด้านบนจะติดตั้งเว็บเซิร์ฟเวอร์ Nginx บนระบบปฏิบัติการตระกูล Debian หรือ SUSE หรือทั้งสองอย่าง

หมายเหตุ: ตรวจสอบให้แน่ใจว่าใช้เครื่องหมายเท่ากับคู่ == เมื่อทดสอบเงื่อนไข

เงื่อนไขในลูป

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

ใน Playbook ด้านล่าง เรามีอาร์เรย์ชื่อ แพ็คเกจ ซึ่งมีรายการแพ็คเกจที่ต้องติดตั้ง งานเหล่านี้จะดำเนินการทีละงานหากตั้งค่าส่วนคำสั่ง required เป็น True

---
 - name: Install Software packages
    hosts: all
    vars:
	packages:
    • name: nginx
required: True
    • name: mysql
required: True
    • name: apache
required: False



   tasks:
    • name: Install “{{ item.name }}”on Debian
apt: 
 name: “{{ item.name }}”
 state: present 
When: item.required == True
loop: “{{ packages }}”  

กำหนดค่าการจัดการข้อผิดพลาด

บางครั้ง งานล้มเหลวเมื่อเรียกใช้ playbooks สมมติว่าคุณกำลังใช้งาน 5 งานบนเซิร์ฟเวอร์ 3 เครื่องดังที่แสดงใน Playbook ด้านล่าง หากเกิดข้อผิดพลาดกับงานที่ 3 (การเริ่มต้น MySQL) บนเซิร์ฟเวอร์ 2 Ansible จะหยุดดำเนินงานที่เหลือบนเซิร์ฟเวอร์ 2 และพยายามทำงานที่เหลือให้เสร็จสิ้นบนเซิร์ฟเวอร์ที่เหลือ

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>

- name: Install MySQL database
<< some code >>

- name: Start MySQL
<< some code >>

- name: Install Nginx
<< some code >>

- name: Start Nginx
<< some code >>

หากคุณต้องการความสอดคล้องในการดำเนินการ Playbook เช่น หยุดการดำเนินการ Playbook หากเซิร์ฟเวอร์ตัวใดตัวหนึ่งล้มเหลว ให้เพิ่มตัวเลือก

---
 - name: Install Software packages
   hosts: server1, server2, server3
   any_errors_fatal:  true
   tasks:

ด้วยวิธีนี้ หากงานหนึ่งล้มเหลวบนเซิร์ฟเวอร์เดียว Ansible จะหยุดการดำเนินการ Playbook ทั้งหมดบนเซิร์ฟเวอร์ทั้งหมดและออก

หากคุณต้องการให้ Playbook ละเว้นข้อผิดพลาดและดำเนินการชุดงานที่เหลือต่อไป ให้ใช้ตัวเลือก ignore_errors: True

---
 - name: Install Software packages
   hosts: server1, server2, server3
   tasks:
- name: Install dependencies
<< some code >>
     ignore_errors: True

สร้าง Playbooks เพื่อกำหนดค่าระบบให้เป็นสถานะที่ระบุ

ในส่วนนี้ เราจะดูตัวเลือกเพิ่มเติมบางอย่างที่พร้อมใช้งานเมื่อเรียกใช้ Playbook

เริ่มต้นด้วยโหมด ตรวจสอบ หรือตัวเลือก ทดลองรัน ตัวเลือกการทดลองรันหรือโหมดตรวจสอบจะใช้เมื่อเรียกใช้ Playbook เพื่อตรวจสอบว่าจะพบข้อผิดพลาดใดๆ หรือไม่ และจะมีการเปลี่ยนแปลงใดๆ ในโฮสต์ที่ได้รับการจัดการหรือไม่ อย่างไรก็ตาม มันไม่ได้ทำการเปลี่ยนแปลงใด ๆ กับโหนดระยะไกล

ตัวอย่างเช่น หากต้องการเรียกใช้ Playbook ชื่อ httpd.yml ที่จะติดตั้งและเริ่มเรียกใช้เว็บเซิร์ฟเวอร์ Apache:

ansible-playbook httpd.yml --check

ตัวเลือกอื่นที่เราต้องดูคือตัวเลือก --start-at-task ใช้เมื่อระบุชื่อของงานที่ Playbook ควรเริ่มต้นหรือเริ่มต้น

ยกตัวอย่าง: Playbook ด้านล่างระบุ 2 งาน: การเล่นครั้งแรกจะติดตั้งเว็บเซิร์ฟเวอร์ Apache และครั้งที่สองจะติดตั้งยูทิลิตี้ htop

---
 - name: Install httpd

   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

- name: Install htop

      yum:  
      name: htop
      state: started

หากคุณต้องการข้ามการติดตั้งเว็บเซิร์ฟเวอร์ Apache และติดตั้งยูทิลิตี้ htop แทน:

ansible-playbook playbook.yml --start-at-task “Install htop”

สุดท้ายนี้ คุณสามารถแท็กงานหรือการเล่นของคุณได้โดยเพิ่มตัวเลือก แท็ก ลงใน Playbook ของคุณตามที่แสดง สิ่งนี้มีประโยชน์เมื่อคุณมี Playbook ที่ค่อนข้างใหญ่ และคุณต้องการรันงานเฉพาะจาก Playbook ทั้งหมด

---
 - name: Install httpd
   tags: Install and start
   hosts: all
   tasks:
    yum:	 
name: httpd
     state: Installed

   tags: Install

    • service: 
name: httpd
state: started
ansible-playbook playbook.yml -tags "Install"

หากต้องการละเว้นแท็ก ให้ใช้ตัวเลือก --skip-tags ตามที่แสดง

ansible-playbook playbook.yml --skip-tags "Install"
บทสรุป

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