Các mẹo giúp tăng tốc độ thực thi của Ansible

1965
15-03-2018
Các mẹo giúp tăng tốc độ thực thi của Ansible

Ansible là một công cụ khá tiện lợi và không yêu cầu thiết lập phức tạp (bạn không cần cài đặt trước bất kỳ phần mềm hoặc tác nhân nào trên các managed host). Trong hầu hết các trường hợp, bạn sẽ sử dụng kết nối 'ssh' để cấu hình máy chủ. Tuy nhiên, một trong những nhược điểm của lớn sự đơn giản này là tốc độ.

Tùy thuộc vào môi trường và quy trình làm việc, Playbook Ansible có thể hoạt động với tốc độ chậm đáng báo động: nó thực hiện tất cả các mạch logic cục bộ, tạo ra các tác vụ "package", gửi nó đến các host từ xa, thực thi, chờ kết quả, đọc kết quả, phân tích và chuyển sang nhiệm vụ tiếp theo. Bài viết sau đâyBizfly Cloud sẽ gửi đến các bạn một số cách để tăng tốc độ các tác vụ trên.

Phương pháp kiểm tra:

Nếu bạn không thể đo lường nó, bạn không thể cải thiện nó. Vì vậy, chúng ta sẽ viết một tập lệnh nhỏ để đếm thời gian thực hiện.

Kiểm tra playbook test.yml:

---

- hosts: all

# gather_facts: no

tasks:

- name: Create directory

file:

path: /tmp/ansible_speed

state: directory

- name: Create file

copy:

content: SPEED

dest: /tmp/ansible_speed/speed

- name: Remove directory

file:

path: /tmp/ansible_speed

state: absent

Tập lệnh đo thời gian time_test.sh:

 #!/bin/bash
# calculate the mean average of wall clock time from multiple /usr/bin/time results.
# credits to https://stackoverflow.com/a/8216082/2795592
cat /dev/null > time.log
for i in `seq 1 10`; do
echo "Iteration $i: $@"
/usr/bin/time -p -a -o time.log $@
rm -rf /home/ubuntu/.ansible/cp/*
done
file=time.log
cnt=0
if [ ${#file} -lt 1 ]; then
echo "you must specify a file containing output of /usr/bin/time results"
exit 1
elif [ ${#file} -gt 1 ]; then
samples=(`grep --color=never real ${file} | awk '{print $2}' | cut -dm -f2 | cut -ds -f1`)
for sample in `grep --color=never real ${file} | awk '{print $2}' | cut -dm -f2 | cut -ds -f1`; do
cnt=$(echo ${cnt} ${sample} | bc -l)
done
# Calculate the 'Mean' average (sum / samples).
mean_avg=$(echo ${cnt}/${#samples[@]} | bc -l)
mean_avg=$(echo ${mean_avg} | cut -b1-6)
printf " Samples:\t%s \n\tMean Avg:\t%s\n\n" ${#samples[@]} ${mean_avg}
grep --color=never real ${file}
fi

Bạn có thể thực hiện playbook 10 lần và thu được thời gian thực hiện trung bình.

Ghép kênh SSH

LAN connection: before 7.68s, after 2.38s  

WAN connection: before 26.64s, after 10.85s  

Điều đầu tiên cần kiểm tra là việc ghép kênh SSH có được bật hay không. Điều này cho phép tăng tốc rất nhanh bởi vì Ansible có thể tái sử dụng các phiên SSH thay vì đàm phán một phiên mới (thực sự nhiều hơn một) cho mỗi công việc. Ansible đã bật cài đặt này theo mặc định. Nó có thể được thiết lập trong tập tin cấu hình như sau:[ssh_connection]

ssh_args = -o ControlMaster=auto -o ControlPersist=60s

Tuy nhiên, hãy cẩn thận khi ghi đè lên ssh_args - nếu bạn không đặt ControlMaster và ControlPersist trong khi ghi đè, Ansible sẽ "quên" việc sử dụng chúng.

Để kiểm tra xem việc ghép kênh SSH có được sử dụng hay không, hãy bắt đầu tùy chọn Ansible with -vvvv:

ansible test -vvvv -m ping

Bạn sẽ thấy các yêu cầu cài đặt trong output:

SSH: EXEC ssh -vvv -C -o ControlMaster=auto -o ControlPersist=60s ... -o ControlPath=/home/ubuntu/.ansible/cp/7c22

Sau đó thiết lập master socket multiplex:

Trying existing master

Control socket "/home/ubuntu/.ansible/cp/7c223265ce" does not exist

setting up multiplex master socket

Ngoài ra, bạn có thể kiểm tra các tập tin socket có mặt trong ControlPath trong vòng 60 giây sau khi kết nối (trong ví dụ này: /home/ubuntu/.ansible/cp/7c223265ce).

Cảnh báo: nếu bạn làm việc trong một số môi trường giống hệt nhau từ một máy chủ Ansible controll host (ví dụ: màu xanh / xanh lá cây hoặc stage / prod), thì nên cẩn thận với nó.

Ví dụ: bạn đã thực hiện kiểm tra trên production servers (ví dụ: các bước cấu hình được thực hiện trong check-mode). Và bây giờ bạn mở socket chủ trỏ tới production servers. Sau đó, bạn cập nhật môi trường stage (có cùng host name như production) và bùm…, mội thứ đều biến mất.  Để ngăn điều này xảy ra, hãy luôn close / clean các session chính khi chuyển đổi môi trường hoặc thiết lập cài đặt "ControlPath" duy nhất cho từng môi trường.

Pipelining

LAN: before 2.38s, after 1.96s

WAN: before 10.85s, after 5.23s 

Các mẹo giúp tăng tốc độ thực thi của Ansible - Ảnh 1.

CPU khi có và không có pipelining

Sau đây là luồng công việc mặc định của việc thực thi module

- Tạo tệp Python với module và các tham số của nó để thực thi từ xa

- Kết nối thông qua SSH để phát hiện thư mục home của user từ xa

- Kết nối thông qua SSH để tạo thư mục công việc tạm thời

- Kết nối qua SSH để tải lên tệp Python qua SFTP

- Kết nối thông qua SSH để thực thi Python-file và dọn dẹp temp dir

- Nhận kết quả của module từ output tiêu chuẩn SSH

- Nếu bạn chỉ sử dụng các module Ansible gốc và các box mục tiêu hiện hành, bạn có thể bật chế độ pipelining.

- Sau đây là các thông số:

[ssh_connection]

pipelining = true

Dưới đây là quy trình làm việc với chế độ pipelining được bật:

Tạo tệp Python với module và các tham số của nó để thực hiện từ xa

Kết nối thông qua SSH để thực thi trình thông dịch Python

Gửi nội dung tệp Python tới input tiêu chuẩn của trình thông dịch

Nhận kết quả của module từ output tiêu chuẩn

Kết quả: bạn sẽ có một kết nối SSH thay vì bốn và nhận được tăng tốc đáng kể, đặc biệt là trên các kết nối WAN.

Để kiểm tra xem pipelining có đang được sử dụng hay không, gọi ra Ansible với verbose output, ví dụ:

ansible test -vvv -m ping

Nếu bạn thấy một số ssh call:

SSH: EXEC ssh ...

SSH: EXEC ssh ...

SSH: EXEC sftp ...

SSH: EXEC ssh ... python ... ping.py

Và pipelining KHÔNG được sử dụng nếu chỉ có một `ssh` call duy nhất:

SSH: EXEC ssh ... python && sleep 0

Sau đó pipelining sẽ hoạt động.

Theo mặc định, cài đặt này bị tắt trong Ansible vì có thể xung đột với requirettysetting cho sudo. Tại thời điểm viết bài viết này requiretty bị vô hiệu hóa trên Ubuntu và RHEL image trong Amazon EC2 cloud, vì vậy bạn có thể yên tâm mở pipelining trên bản phân phối này.

PreferredAuthentications và UseDNS

LAN: before 1.96s, after 1.92s 

WAN: before 5.23s, after 4.92s 

UseDNS

UseDNS là một thiết lập SSH-server (/etc/ssh/sshd_config file) buộc máy chủ kiểm tra bản ghi PTR của máy khách khi kết nối. Nó có thể gây ra kết nối bị chậm, đặc biệt là với các DNS server bị chậm ở phía máy chủ. Trong bản phân phối Linux hiện hành, cài đặt này được tắt theo mặc định.

PreferredAuthentications

Đây là một thiết lập SSH-client thông báo cho máy chủ về các phương thức xác thực ưu tiên. Theo mặc định, Ansible sử dụng: -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey Vì vậy, nếu GSSAPIAuthenticationis được kích hoạt trên máy chủ (tại thời điểm viết nó được bật trong RHEL EC2 AMI), nó sẽ được dùng làm tùy chọn đầu tiên, buộc máy khách và máy chủ thực hiện tra cứu bản ghi PTR. Nhưng trong hầu hết các trường hợp, chúng tôi chỉ muốn sử dụng khóa công khai auth. Chúng ta có thể buộc Ansible làm như vậy bằng cách thay đổi ansible.cfg

[ssh_connection]

ssh_args = -o ControlMaster=auto -o ControlPersist=60s -o

PreferredAuthentications=publickey

Điều này giúp loại bỏ các bước không cần thiết và tăng tốc độ kết nối ssh chủ ban đầu.

Facts Gathering

LAN: before 1.96s, after 1.47s 

WAN: before 4.92s, after 4.77s 

Khi bắt đầu thực thi playbook, Ansible thu thập thông tin xác thực về hệ thống từ xa (đây là hành vi mặc định cho ansible-playbook nhưng không liên quan đến các lệnh ad-hoc ansible).

Nó tương tự như gọi ra module "setup", do đó đòi hỏi thêm một bước giao tiếp ssh. Nếu bạn không cần bất kỳ sự kiện nào trong playbook (ví dụ: test playbook), bạn có thể vô hiệu hóa việc thu thập thông tin:

gather_facts: no

Nếu bạn thường chạy playbook theo các sự kiện, nhưng việc thu thập thực tế làm chậm hoạt động, xem xét thiết lập external fact-caching backend. Ví dụ, bạn định nghĩa Redis backend, thu thập dữ kiện theo công việc định kỳ hàng giờ và vô hiệu hóa Facts Gathering trong playbook của mình để theo các sự kiện được lưu trong bộ nhớ cache. WAN → LAN Before 4.77s, after 1.47s  

Kết nối WAN của bạn có thể có các thông số về độ trễ và băng thông tốt, tuy nhiên kết nối LAN vẫn là tốt hơn. Nếu bạn quản lý vô số máy chủ, ví dụ như ở vùng Amazon EC2 eu-west-1, bạn có thể kỳ vọng một sự tăng tốc đáng kể nếu máy điều khiển Ansible của bạn cũng nằm trong vùng đó. 

Quy tắc chung là di chuyển máy chủ điều khiển đến gần hơn các hệ thống được quản lý. Pull-mode Before 1.47s, after 1.25s  Bạn cần tốc độ cao hơn? Thực thi playbooks cục bộ trên các máy chủ từ xa có công cụ ansible-pull. Bạn có thể đọc về nó trong tài liệu Ansible chính thức. 

Nó hoạt động như sau: Sao chép quy định repo vào thư mục con cục bộ.  Thực thi playbook được chỉ định với kết nối cục bộ (tùy chọn `-c local`).  Nếu tên của playbook bị bỏ qua, hãy thử thực hiện: local.yml

 Một trong những quy trình công việc là thực hiện ansible-pull --only-if-changed dưới dạng cron job: nó sẽ giám sát kho đích và nếu có sự thay đổi, hãy sử dụng playbook.

Fork 

Cho đến thời điểm này, chúng ta đã thảo luận cách tăng tốc độ thực thi playbook trên một máy chủ từ xa cụ thể. Nhưng nếu bạn chạy playbook với hàng chục hoặc hàng trăm máy chủ, bạn cứ hình dung hiệu suất nội bộ Ansible sẽ giống như một nút thắt cổ chai. Ví dụ, khi có số cấu hình sẵn của các nhánh - số lượng máy chủ có thể tương tác đồng thời. Bạn có thể thay đổi giá trị này trong tệp ansible.cfg:

[defaults]

forks = 20

Giá trị mặc định 5 là tương đối cẩn thận. Bạn có thể thử nghiệm với cài đặt này tùy thuộc vào tài nguyên CPU và băng thông mạng cục bộ. Một điều nữa về Fork là nếu bạn có rất nhiều máy chủ để làm việc cùng với số lượng fork khả dụng thấp, các phiên ssh-master chính của bạn có thể bị hết hạn giữa các tác vụ. 

Ansible sử dụng Linear theo mặc định, thực hiện một nhiệm vụ cho mỗi máy chủ và sau đó tiến hành công việc tiếp theo. Bằng cách này, nếu thời gian giữa việc thực thi tác vụ trên máy chủ đầu tiên và trên máy chủ cuối cùng lớn hơn ControlPersist thì socket chính sẽ hết hạn vào lúc Ansible bắt đầu thực hiện nhiệm vụ sau trên máy chủ đầu tiên, do đó kết nối ssh mới sẽ được yêu cầu. 

Poll Interval 

Khi module được thực hiện trên máy chủ từ xa, Ansible bắt đầu thăm dò kết quả. Phần thấp hơn là khoảng thời gian giữa các lần thăm dò ý kiến, phần cao hơn là CPU load trên máy chủ điều khiển Ansible. Nhưng chúng tôi muốn có CPU có sẵn cho số nhánh lớn hơn (xem ở trên). Bạn có thể tinh chỉnh khoảng thời gian thăm dò trong ansible.cfg:

[defaults]

internal_poll_interval = 0.001

Nếu bạn chạy các job "chậm" (như là backup) trên nhiều máy chủ, bạn có thể muốn tăng khoảng thời gian đến 0,05 để sử dụng ít CPU hơn. Như vậy, có vẻ như không có thêm mục nào trong check-list môi trường và tăng tốc chỉ khả thi khi tối ưu hóa mã playbook của bạn.

Tổng kết

Hy vọng bài viết trên sẽ giúp bạn tăng tốc độ thiết lập của mình. Chúc các bạn thành công!

Theo Bizfly Cloud chia sẻ


SHARE
Hỗ trợ kỹ thuật
Kinh doanh, CSKH