Saturday, 17 December 2016

Làm quen với Ansible - module, ad-hoc command

Mình dùng SaltStack để quản lý cấu hình và tự động hoá hệ thống.
Mình muốn thử dùng Ansible để xem có gì hay ho, vì nhiều người bị ho và cứ hỏi là SaltStack hơn Ansible cái gì, nên mình đọc doc.


Mình không hiểu nổi tại sao có cái document to đùng và xinh đẹp ở đấy thì mọi người chả đọc, cứ đi tìm cái đâu đâu, kỳ 😶

Cài đặt Ansible

Nếu biết pip là gì thì dùng pip là nhanh gọn nhất,  vì Ansible viết bằng Python, cài bằng pip là điều hiển nhiên không cần bàn cãi. Chạy lệnh sau:
$ pip install ansible
...
Successfully installed ansible-2.1.0.0
Nếu thấy dòng trên sau khi chạy lệnh pip tức là đã thành công.

Nhận xét:
- Ansible khuyến khích người dùng cài từ bản develop checkout từ Ansible repo trên GitHub
- Nếu không được thì cài từ pip
- Nếu vẫn không được thì cài bằng các package manager của hệ thống như apt, yum...
- Phần hướng dẫn thì ít mà chú ý thì nhiều.


Ở đây mình cài lên máy mình để test chơi nên mình không cài vào "toàn hệ thống". Mình không chạy sudo và không muốn dùng file cấu hình đặt trong /etc/ansible. Để không ảnh hưởng đến "hệ thống", hãy dùng virtualenv của Python để tạo một environment rồi cài bằng pip. Xem hướng dẫn dùng virtualenv và pip tại đây.

Kiểm tra phiên bản Ansible

$ ansible --version
ansible 2.1.1.0
  config file =
  configured module search path = Default w/o overrides

Cú pháp câu lệnh cơ bản

ansible [options] destination
destination là tên của máy sẽ được chạy lệnh, tất cả thì dùng "all".
Mặc định Ansible sẽ tìm tên các máy / IP / cấu hình tương ứng trong file "inventory" /etc/ansible/hosts, hoặc thêm option -i rồi đường dẫn đến 1 file cấu hình khác để dùng file này.
Ansible sẽ kết nối đến các host được chỉ định (phải tồn tại trong file inventory) qua SSH, bài này thừa nhận bạn đã biết ssh vào một máy dùng public/private key.
Tạo một file tên ``hosts`` với nội dung là IP của máy ta sẽ thử nghiệm (tên gì cũng được cả). Ở đây là máy có địa chỉ IP 128.199.6.9
$ echo 128.199.6.9 > hosts

Chạy module

Để chạy một module trên máy đích, thêm tên module sau option -m. Ở đây sẽ thử module "ping" (kiểm tra xem kết nối đến máy đích có thành công không, không liên quan gì đến lệnh ping):
$ ansible -i hosts all -m ping
128.199.6.9 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh.",
    "unreachable": true
}
Rõ ràng đây là một kết quả không thành công.
Mặc định, Ansible sẽ truy cập vào máy đích với username trùng với user đang gọi lệnh ansible, trên máy mình đang dùng user ``hvn``, user này không có quyền truy cập vào máy đích:
$ id
uid=501(hvn) gid=20(staff) groups=20(staff)
Thêm option -u để chỉ định user khác cho máy đích, ở đây ta login vào máy đích bằng user ``root``:
$ ansible -i hosts all -m ping -u root
128.199.6.9 | SUCCESS => {
    "changed": false,
    "ping": "pong"
}

Chạy Ansible trên localhost

Để dùng Ansible chạy lệnh / quản lý chính máy đang dùng, sử dụng một option đặc biệt: -c local
và thay vì dùng "inventory" từ file chỉ định sau option "-i", ta dùng
-i 'localhost,'  # chú ý dấu ,
 $ ansible -i 'localhost,' -c local all -m ping
localhost | SUCCESS => {
    "changed": false,
    "ping": "pong"
}
SUCCESS là thành công. Bí quyết thành công là phải biết từ SUCCESS và hô thật to 🤑

Để hiện toàn bộ thông tin của máy (sau này sẽ sử dụng trong Ansible Playbook), dùng module "setup", lệnh dưới thêm "time" trước câu lệnh cần chạy để đo xem nó chạy mất bao lâu:
$ time ansible -i ./hosts all -u root -m setup | wc -l
     362

real    0m3.327s
user    0m0.865s
sys    0m0.476s
Nội dung trả về dài 362 dòng, máy được test là một máy ảo trên DigitalOcean đặt tại Singapore.

Lấy thông tin máy localhost bằng lệnh setup:
$ ansible -i 'localhost,' localhost -c local -m setup | grep distribution
        "ansible_distribution": "MacOSX",
        "ansible_distribution_version": "10.11.6",

Chạy ad-hoc command

ad-hoc hiểu nôm na là "tạm bợ", chạy 1 câu lệnh nào đó trên máy đích mà không cần lưu lại, tạm thời.
Chạy ad-hoc command là dùng Ansible để gọi câu lệnh bất kỳ trên máy đích.

Khi không chỉ định module sau -m, Ansible sẽ mặc định dùng module "command".
Nó thực hiện câu lệnh bất kỳ được đưa trong option "-a" (argument sẽ được sử dụng với module đã chỉ định), nhưng không thực hiện các tính năng riêng của shell như pipeline ``|`` hay redirect ``>`` hoặc "<", các biến riêng của shell vẫn dùng OK.
$ ansible -i ./hosts -u root all -a 'hostname'
128.199.239.206 | SUCCESS | rc=0 >>
hvn-dev-vm

$ ansible -i ./hosts all -u root -a 'ps xau | wc -l'
128.199.6.9 | FAILED | rc=1 >>
error: garbage option

Usage:
 ps [options]

 Try 'ps --help <simple|list|output|threads|misc|all>'
  or 'ps --help <s|l|o|t|m|a>'
 for additional help text.

For more details see ps(1). # không thành công do module command không hiểu dấu | 
Để chạy câu lệnh và sử dụng tính năng của shell như pipeline ``|``, chỉ định module shell:
$ time ansible -i ./hosts all -u root -m shell -a 'ps xau | wc -l'
128.199.239.206 | SUCCESS | rc=0 >>
136

real    0m2.225s
user    0m0.655s
sys    0m0.351s
Chú ý dùng single quote (dấu ')sau option ``-a`` để tránh shell đang dùng trên máy hiện tại expand các biến trước khi gửi tới máy đích.

Tới đây ta đã biết:
- Cài đặt
- Chỉ định 1 file inventory bất kỳ.
- Chạy Ansible trên localhost
- Chạy một module bất kỳ
- Chạy lệnh từ xa bằng module shell.

Bài tiếp sẽ khám phá Ansible Playbook để cài đặt các phần mềm trên Ubuntu.

Tham khảo:
http://docs.ansible.com/ansible/intro_installation.html
http://docs.ansible.com/ansible/intro_getting_started.html
http://docs.ansible.com/ansible/intro_adhoc.html
http://docs.ansible.com/ansible/intro_inventory.html

Hết.
HVN at http://www.familug.org/ and http://pymi.vn