生产实践:
使用shell脚本调用ansible执行批量操作
学习技巧:
Shell 脚本调用ansible、Ansible常用模块使用
脚本内容:
生产中如果没有平台支持,在中控批量操作远程主机是很常用的,如果已经做好ssh互信认证用pssh这种就很方便,没有提前做好认证用ansible更合适,但是根据经验其实都是混用。pssh,ansible,saltstack,脚本,哪个更适用就用哪个或者组合使用。以下是几个shell调用 ansible 2.9.25 执行批量操作的脚本,用的比较随意可以优化。
ansilbe_shell.sh:使用ansible shell模块批量执行命令
#!/bin/bash #set -x set -e if [ $# -lt 2 ]; then echo "Usage: ansible_shell <host1,hosts2,hostgroup> <commands>" exit fi hosts="*$1" shift 1 commands="$*" #commands=${*:2} # ansible_sudo_pass也可以在ansible主机配置文件里写,这里就无需加-e写了 if [ -n "${commands}" ]; then ansible $hosts -m shell -a "$commands;echo ' '" -e "ansible_sudo_pass=xxx" 2>/dev/null fi exit
ansible_sync.sh:使用ansible synchronize模块批量往远程主机推文件或文件夹,也可以将远程文件拉回本地
#!/bin/bash ############################################################################## # $Name: ansible_syncfile.sh # $Version: v1.0 # $Function: Used to synchronize host's files # $Author: Zhihe An # $Create Date: 20230524 ############################################################################## set -e if [[ $# -lt 4 || "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then echo "Usage: ansible_syncfile <host1,hosts2,hostgroup> <src file> <dst file> <mode>[pull|push]" exit fi hosts="$1" # 获取执行主机列表 host_list=$(ansible $hosts --list-hosts 2>/dev/null | sed '1d') src_file="$2" dest_file="$3" sync_mode="$4" # list servers echo -e "\nYou will \033[31m$sync_mode files\033[0m by these servers:\n" ansible $hosts --list-hosts 2>/dev/null echo "" read -p "Are you sure?(y|n) " ans echo "" if [[ "$ans" != @("y"|"Y"|"Yes"|"yes") ]]; then echo -e "\033[31m已取消操作...\033[0m" exit fi # 注意mode参数:指定同步的方向,在推模式下,本地主机或委托是源;在拉模式下,上下文中的远程主机是源 # rsync同步的方式为push、pull,默认是推送push,从本机推送给远程主机,从『控制机』到『目标机』;pull表示从远程主机上拿文件,从『目标机』到『控制机』 if [[ "$sync_mode" == "pull" && -e "$dest_file" ]]; then # 将远端文件拉到指定目录 if [[ -n $host_list ]]; then for host in ${host_list[@]}; do [[ ! -e "$dest_file/$host" ]] && mkdir -p $dest_file/$host ansible $host -m synchronize -a "src=$src_file dest=$dest_file/$host/ rsync_path=/usr/bin/rsync mode=pull" -e "ansible_sudo_pass=xxx" 2>/dev/null sleep 1 done [[ $? = 0 ]] && echo "文件下载完成,请进入$dest_file中查看" fi elif [[ "$sync_mode" == "push" && -e "$src_file" ]]; then # 将文件推到远端机器指定目录 ansible $hosts -m synchronize -a "src=$src_file dest=$dest_file rsync_path=/usr/bin/rsync" -e "ansible_sudo_pass=xxx" 2>/dev/null [[ $? = 0 ]] && echo "文件推送完成" else echo "文件同步失败,请检察文件路径是否存在或主机是否匹配!" fi exit
ansible_copy.sh:使用ansible copy模块往远程主机推文件
#!/bin/bash set -e if [ $# -lt 3 ]; then echo "Usage: ansible_copy <host_list> <src file> <dst file>" exit fi hosts="*$1*" src_file="$2" dst_file="$3" args=${*:4} # list servers echo -e "\nYou will copy \033[31m$src_file\033[0m to these servers:\n" ansible $hosts --list-hosts 2>/dev/null echo "" read -p "Are you sure?(y|n) " ans echo "" if [[ "$ans" != @("y"|"Y"|"Yes"|"yes") ]]; then echo -e "\033[31m已取消操作...\033[0m" exit fi if [ -e "$src_file" ]; then ansible $hosts -m copy -a "src=$src_file dest=$dst_file owner=root group=root mode=0755" -e "ansible_sudo_pass=xxx" $args 2>/dev/null fi exit
ansible_script.sh:使用ansible script模块在远程主机执行脚本
#!/bin/bash if [ $# -lt 3 ]; then echo "usage: $0 <inventory file> <all|host1,host2,host3> <script file>" exit fi inventory=$(readlink -fn $1) hosts="$2" script_file=$(readlink -fn $3) if [ -f "$script_file" ]; then ansible -i $inventory $hosts -m script -a "$script_file" fi
pk:执行ansible-playbook,主机列表通过host_list变量传到playbook中,如:pk check_adcu.yaml *6666* -t date -v
echo "[[ -f ~/.bash_aliases ]] && source ~/.bash_aliases" >> ~/.bash_profile cat >> ~/.bash_profile << EOF # 执行ansible playbook by anzhihe 20230522 pk() { if [[ $# -lt 2 || "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then echo "usage: pk <playbook file> <all|host1,hosts2,hostgroup> [args]" # exit fi pkfile="$(readlink -fn $1)" hosts="$2" #shift 2 args=${*:3} if [ -f "${pkfile}" ]; then eval "ansible-playbook ${pkfile} --extra-vars "ansible_sudo_pass=xxx" -e "host_list=$hosts" "$args"" 2>/dev/null fi } function nps() { if [[ "$1" == "-h" || "$1" == "--help" || -z "$1" ]]; then python3 /home/anzhihe/op/python/ops.py -h 2>/dev/null else python3 /home/anzhihe/op/python/ops.py -nps $1 2>/dev/null fi } EOF source ~/.bash_profile && source ~/.bash_aliases
参考: