通过ansible批量管理Linux服务器:配置Inventory和批量执行命令

通过ansible批量管理Linux服务器:配置Inventory和批量执行命令

2023年6月25日发(作者:)

通过ansible批量管理Linux服务器:配置Inventory和批量执⾏命令ansible是⼀款⽐较新的⾃动化运维⼯具,基于Python开发,集合了众多运维⼯具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运⾏命令等功能。ansible是基于模块⼯作的,本⾝没有批量部署的能⼒。真正具有批量部署的是ansible所运⾏的模块,ansible只是提供⼀种框架。主要包括:(1)、连接插件connection plugins:负责和被监控端实现通信;(2)、host inventory:指定操作的主机,是⼀个配置⽂件⾥⾯定义监控的主机;(3)、各种模块:核⼼模块、command模块、⾃定义模块;(4)、借助于插件完成记录⽇志邮件等功能;(5)、playbook:剧本执⾏多个任务时,⾮必需可以让节点⼀次性运⾏多个任务。ansible的安装部署我这⾥就不讲了,可以参考官⽅⽂档。这⾥我将分成三个部分进⾏讲解:1、配置Inventory,2、批量执⾏命令,3、playbook作业。系统环境:服务器ansible主机远程机器1远程机器2IP地址192.168.2.203192.168.2.205192.168.2.208操作系统Centos 7 64位Centos 7 64位Centos 7 64位所需软件ansiblehttpdhttpd⼀、ansible常⽤的五个命令⼆、创建ssh key授权ansible是通过ssh⽅式管理远程服务器的,所以⾸先需要先打通ssh通道。我们在管理⼤批量服务器时,为了避免远程操作时重复输⼊密码,最好使⽤sshd服务的安全密钥验证⽅式。通过ssh-keygen来管理密钥,即使在创建密钥时设置了密码,执⾏过ssh-add之后,会创建⼀个新的会话,以后的每次连接都⽆须输⼊密钥密码了。建议使⽤ssh key授权⽅式,并且不要设置密钥密码,这样可以更好地实现⾃动化。ssh-keygen # 创建公钥和私钥⽂件ssh-copy-id 192.168.2.205 # 将公钥⽂件copy到远程主机上ssh-copy-id 192.168.2.208ssh-agent bash # 通过ssh-agent来管理密钥ssh-add ~/.ssh/id_rsa # 将私钥交给ssh-agent管理,避免每次连接都需要输⼊密钥密码三、配置Inventory⽂件默认的Inventory⽂件是/etc/ansible/hosts,格式与windows的ini配置⽂件类似1、按IP地址来配置例如:我现在有2台主机,IP地址分别为192.168.2.205和192.168.2.208,并且两台主机都是web服务器,那么可以定义⼀个web_server组,如下:[web_server]192.168.2.205192.168.2.208如果修改了ssh端⼝号的话,可以按如下⽅式来定义:[web_server]192.168.2.205:5210192.168.2.208:5210如果我有⼀台主机IP为192.168.2.203不属于任何组,可以按如下⽅式来定义:192.168.2.203[web_server]192.168.2.205192.168.2.208给主机设置⼀个别名,在这个例⼦中,通过“webserver1”别名,会连接192.168.2.205。Webserver1 ansible_ssh_port=5210 ansible_ssh_host=192.168.2.205Webserver2 ansible_ssh_port=5210 ansible_ssh_host=192.168.2.208可以单独设置连接⽤户名和连接类型:[web_server]192.168.2.203 ansible_connection=local192.168.2.205:5210 ansible_connection=ssh ansible_ssh_user=xuad192.168.2.208:5210 ansible_connection=ssh ansible_ssh_user=andyxu2、按主机名配置按主机名配置和按IP地址配置⼀样,只需把IP改成主机名即可,例如:[web_server][db_server]::5210[targets] ansible_connection=localother1:5210 ansible_connection=ssh ansible_ssh_user=xuadOther2:5210 ansible_connection=ssh ansible_ssh_user=andyxu例如有⼀组db服务器,分别为到,共50台db服务器[db_server]db[1:50].:5210如果是到,共6台db服务器[db_server]db[a:f].:52103、给主机设置变量分配变量给主机很简单,这些变量定义后可在playbooks中使⽤。[web_server] http_port=80 pathname=/etc/httpd/ http_port=8081 pathname=/etc/nginx/4、给组分配变量下⾯例⼦是给web_server组定义两个变量,http_port和pathname。[web_server][web_server:vars]http_port=80pathname=/etc/httpd/5、把⼀个组作为另⼀个组的⼦成员下⾯例⼦是把web_server和db_server两个组分配给some_server组,作为some_server组的⼦组,并分配变量给some_server组使⽤,再把some_server组分配给user_server组,作为user_server组的⼦组。[web_server]192.168.2.205192.168.2.208[db_server]::5210[some_server:children]web_serverdb_server[some_server:vars]http_port=80nginx_port=8080pathname=/etc/ansible/xuad=[user_server:children]some_serverother_serverNorthserver6、分⽂件定义主机和组变量假设有⼀台主机为192.168.2.205,属于web_server组,现在分别给web_server组和192.168.2.205主机定义变量,那么hosts⽂件增加如下内容:/etc/ansible/group_vars/web_server/etc/ansible/host_vars/192.168.2.205创建group_vars和host_vars⽬录mkdir /etc/ansible/group_varsmkdir /etc/ansible/host_vars然后编辑web_server⽂件,可按如下内容定义变量,注意:号后⾯有个空格。vim /etc/ansible/group_vars/web_serverhttp_port: 80http_path: /data/httpd/ntp_server: _server: 再编辑192.168.2.205⽂件,可按如下内容定义变量vim /etc/ansible/host_vars/192.168.2.205nginx_port: 8081nginx_path: /data/nginx/db_server: 还有更进⼀步的运⽤,可以为⼀个主机或者⼀个组创建⼀个⽬录,⽬录名就是主机名或组名,⽬录中可以创建多个⽂件,⽂件中的变量都会被读取为主机或组的变量,host⽂件内容如下:/etc/ansible/group_vars/web_server/192.168.2.205/etc/ansible/group_vars/db_server/entory⽂件的参数可以查看ansible官⽅⽂档,下⾯我们来看官⽅⽂档的⼀个主机⽂件的例⼦,并说明每⾏都是什么意思。#给some_host主机定义了ssh连接的端⼝号和⽤户名some_host ansible_ssh_port=2222 ansible_ssh_user=manager#连接aws_host主机时将通过以下定义的私钥⽂件进⾏验证aws_host ansible_ssh_private_key_file=/home/example/.ssh/#给freebasd_host主机指定了python的路径freebsd_host ansible_python_interpreter=/usr/local/bin/python#给ruby_module_host主机指定了ruby运⾏的路径ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3ansible还可以从外部获取Inventory配置信息,获取途径有以下⼏种:1、从云端拉取inventory2、从LDAP获取配置3、从cobbler获取配置4、从CMDB获取配置从外部获取inventory配置的⽅法我这⾥就不讲了,有兴趣的可以查看官⽅⽂档。四、ansible批量执⾏命令⾸先在inventory的配置⽂件/etc/ansible/hosts⾥定义⼀个主机组,内容如下:vim /etc/ansible/hosts(1)我们先来ping⼀下,看下两台主机的连通情况ansible web_server -m ping(2)查看web_server组下有哪些主机ansible web_server --list(3)查看⼀台主机的内存使⽤情况命令格式:ansible <主机或主机组> -a “shell命令”注:执⾏⼀条命令使⽤-a参数,后⾯跟shell命令ansible 192.168.2.205 -a "free -h"(4)在web_server组批量创建⼀个普通⽤户ansible web_server -a "useradd andy"(5)重启所有主机的httpd服务命令格式:ansible <主机组> -m <模块名称> -a <指定执⾏参数>注:使⽤all参数就是对hosts⽂件⾥配置的所有主机执⾏命令ansible all -m service -a "name=httpd state=restarted"也可以使⽤ansible all -a "systemctl restart httpd"语句,结果是⼀样的,但输出信息不同,可⾃⾏测试看看。(6)查看多个组下各主机指定⽤户的UID和GID命令格式:ansible <主机组1>:<主机组2>:<主机组3> -a "shell命令"ansible http1:http2 -a "id andy"(7)排除⼀个特定组,在web_server组下的不属于http1组的主机的/tmp⽬录下新建⼀个⽂件命令格式:ansible '<主机组1>:!<主机组2>' -a "shell命令"注:执⾏命令的主机属于webserver组,但不属于http1组ansible 'web_server:!http1' -a "touch /tmp/"此时ansible会给出⼀个警告信息,意思是说ansible已经内置有file模块,建议使⽤file模块创建⽂件,如果想取消警告信息,可以修改配置⽂件,把command_warnings参数改成False,就不会再给出警告信息了。其实创建⽂件可以使⽤下⾯这条命令,结果是⼀样的,关于模块的使⽤后⾯会讲到。ansible 'web_server:!http1' -m file -a "dest=/tmp/ state=touch"(8)指定两个组的交集,查看属于web_server组⼜属于http1组的主机的负载情况注:!表⽰属于前⾯的组但不属于后⾯的组;&表⽰即属于前⾯的组也属于后⾯的组。ansible 'web_server:&http1' -a "uptime"(9)在即属于web_server组⼜属于http2组但不属于http1组的主机删除/tmp/⽂件内容ansible 'web_server:!http1:&http2' -a "rm -f /tmp/"(10)通配符使⽤,查看以http开头的所有组的主机的字符编码ansible http* -a "cat /etc/"(11)查看以http开头的所有组和web_server组的所有主机的磁盘使⽤情况ansible http*:web_server -a "df -h"(12)查看web_server组的第⼀台主机的hostnameansible web_server[0] -a "hostname"(13)查看web_server组的前5台主机的当前⽇期和时间ansible web_server[0:4] -a "date '+%Y-%m-%d %H:%M:%S'"(14)正则表达式使⽤,查看以web或者http开头的组的主机的httpd服务的进程PIDansible '~(web|http)*' -a "pidof httpd"(15)其它正则表达式例⼦ansible '~(web|http)2' -a "pidof sshd" # web2或者http2主机或者组ansible '~(^web)*' -a "pidof sshd" # 以web开头的主机或者组ansible '~(web|db).*.' -a "pidof sshd" # web.*.或者db.*.主机或者组(16)如果不想使⽤ssh-agent,想通过密码验证的⽅式使⽤ssh,可以在执⾏ansible命令时使⽤--ask-pass或-k参数。ansible web_server -a "shell命令" --ask-passansible web_server -a "shell命令" -k(17)批量重启服务器,加-f 10选项可以fork出10个⼦进程(bash),以并⾏的⽅式执⾏reboot命令,即每次重启10个ansible web_server -a "/sbin/reboot" -f 10(18)在执⾏ansible命令时,默认是以当前⽤户的⾝份去执⾏,如果想以指定的⽤户执⾏命令,需添加-u username选项ansible web_server -a "shell命令" -u username # ssh安全密钥验证⽅式ansible web_server -a "shell命令" -u username -k # ssh账号密码验证⽅式(19)以sudo去执⾏命令如果设置了sudo不需要输⼊密码的话,可不加--ask-sudo-pass;如果sudo需要输⼊密码的话,必须加--ask-sudo-pass参数。建议设置成sudo不需要输⼊密码,这样更容易实现⾃动化。ansible web_server -a "shell命令" -u username --sudoansible web_server -a "shell命令" -u username --sudo --ask-sudo-pass(20)也可以通过-sudo-user或-U选项,使⽤sudo切换到其它⽤户,⽽不是root⽤户ansible web_server -a "shell命令" -u username -U otheruser [--ask-sudo-pass]ansible有许多模块,默认是“command”,也就是命令模块,我们前⾯执⾏的那些语句都是以command模块执⾏的,下⾯来看⼀个例⼦。(21)统计⽆法登陆系统的⽤户数量,即nologin⽤户数ansible web_server -a "grep '/sbin/nologin' /etc/passwd | wc -l"发现执⾏后会报错,⽆法得到我们想要的结果这是因为command模块不⽀持shell命令的变量、管道符等,如果你想使⽤shell相关的这些东西,可以使⽤shell模块,⽤-m参数指定要运⾏的模块即可。ansible web_server -m shell -a "grep '/sbin/nologin' /etc/passwd | wc -l"(22)查看模块的帮助信息ansible-doc shell(23)查看web_server组各主机的ip地址ansible web_server -m shell -a "/sbin/ifconfig | grep 'inet ' | awk '{print $2}' | sed -e '/127.0.0.1/d'"注:shell模块使⽤awk命令时需要使⽤转义符*(24)查看web_server组各主机的PATH变量内容ansible web_server -m shell -a 'echo $PATH'注意:如果使⽤双引号"echo $PATH",会求出PATH变量在当前系统的值,这就牵扯到shell引号的规则了。*在下图中我们明显看到双引号和单引号执⾏的结果是不⼀样的,单引号是远程机器的结果,⽽双引号实际是ansible本地机器的结果。(25)Ansible能够以并⾏的⽅式同时scp⼤量的⽂件到多台机器,将本地hosts⽂件copy到web_server组的所有主机的/tmp⽬录下命令格式:ansible <主机或主机组> -m copy -a "src=<本地⽬录或⽂件> dest=<远程⽬录或⽂件>"ansible web_server -m copy -a "src=/etc/hosts dest=/tmp/"(26)使⽤file模块修改⽂件的属主和权限,这⾥可以替换为copy模块,是等效的命令格式:ansible <主机或主机组> -m file -a "dest=<远程⽬录或⽂件> mode=<权限> owner=<所属⽤户> group=<所属⽤户组>"ansible web_server -m file -a "dest=/tmp/hosts mode=600"ansible web_server -m file -a "dest=/tmp/hosts mode=600 owner=xuad group=xuad"ansible web_server -a "ls -lh /tmp/hosts"(27)使⽤file模块创建⽬录,与执⾏mkdir -p效果类似ansible web_server -m file -a "dest=/tmp/test mode=755 owner=xuad group=xuad state=directory"(28)使⽤file模块创建⽂件,与执⾏touch效果类似ansible web_server -m file -a "dest=/tmp/ mode=755 owner=xuad group=xuad state=touch"(29)使⽤file模块创建⼀个软链接⽂件ansible web_server -m file -a "src=/root/ dest=/tmp/ state=link"(30)删除⽬录(递归删除)和删除⽂件,absent表⽰删除ansible web_server -m file -a "dest=/tmp/test state=absent"ansible web_server -m file -a "dest=/tmp/ state=absent"Ansible提供对yum和apt的⽀持,下⾯是关于yum的⽰例(31)确认⼀个软件包已经安装,但不去升级它ansible web_server -m yum -a "name=wget state=present"(32)将⼀个软件包升级到最新版本ansible web_server -m yum -a "name=wget state=latest"(33)卸载⼀个软件包,将wget卸载ansible web_server -m yum -a "name=wget state=removed"(34)确认⼀个软件包没有安装,确认wget已经不在了ansible web_server -m yum -a "name=wget state=absent"(35)安装⼀个软件包,通过yum⽅式安装wgetansible web_server -m yum -a "name=wget state=installed"(36)删除⼀个⽤户,删除andy⽤户ansible web_server -m user -a "name=andy state=absent"(37)确认⼀个⽤户是否存在,不存在则创建此⽤户ansible web_server -m user -a "name=andy state=present"(38)创建⼀个新⽤户,并指定⽤户组和家⽬录ansible web_server -m user -a "name=andy groups=xuad home=/home/andy1"(39)创建⼀个新⽤户,并设置密码ansible web_server -m user -a 'name=andy password="<crypted password here>"'注:是经过sha-512加密算法加密后的值,需要安装passlib,密码值要⽤双引号括起来,外⾯⽤单引号通过以下⽅式⽣成sha-512算法密码pip install passlibpython -c "from import sha512_crypt; import getpass; print sha512_t(s())"(40)我们有时需要⽤git下载⼀个软件项⽬,可以使⽤git模块ansible web_server -m git -a "repo=/ dest=/srv/myapp version=HEAD"(41)服务的启动、重启、停⽌,enabled=yes表⽰加⼊开机启动ansible web_server -m service -a "name=httpd state=started"ansible web_server -m service -a "name=httpd enabled=yes state=started"ansible web_server -m service -a "name=httpd state=restarted"ansible web_server -m service -a "name=httpd state=stopped"长时间运⾏的操作可以放到后台执⾏,需要加--do-stuff参数,ansible会检查任务的状态,在主机上执⾏的同⼀个任务会分配同⼀个jobid。(42)后台执⾏命令,最多运⾏3600秒,-B 表⽰后台执⾏的最长时间ansible all -B 3600 -a "/usr/bin/long_running_operation --do-stuff"(43)检查任务运⾏的状态,使⽤async_status模块,上⾯执⾏后台命令后会返回⼀个job id,将这个id传给async_status模块ansible all -m async_status -a "jid=488359623657.1326"(44)后台执⾏命令,最多运⾏1800秒,即30分钟,-P表⽰每60秒检查⼀次状态,默认15秒ansible all -B 1800 -P 60 -a "/usr/bin/long_running_operation --do-stuff"(45)查看⼀台主机的系统信息ansible 192.168.2.205 -m setup注:这些系统信息变量可以直接在playbook⾥⾯调⽤(46)查看⼀台主机的⽇期和时间信息ansible 192.168.2.205 -m setup -a 'filter=ansible_date_time'(47)查看⼀台主机的内存相关信息ansible 192.168.2.205 -m setup -a 'filter=ansible_*_mb'(48)查看⼀台主机的⽹卡信息ansible 192.168.2.205 -m setup -a 'filter=ansible_ens3[0-5]'(49)计划任务模块cron,每6个⼩时同步⼀次时间ansible web_server -m cron -a 'name="modify ntp server" minute=0 hour="*/6" job="/usr/sbin/ntpdate "'ansible的cron模块实际上就是在远程主机上创建了⼀条crontab(⾃动计划任务),我们到远程主机上执⾏crontab -e看⼀下(50)系统重启后⾃动执⾏⼀个脚本ansible web_server -m cron -a 'name="a job for reboot" special_time=reboot job="/root/"'(51)删除⼀个计划任务ansible web_server -m cron -a 'name="a job for reboot" state=absent'(52)挂载分区ansible web_server -m mount -a 'name=/data src=/dev/sdb1 fstype=ext4 opts=rw state=mounted'(53)卸载分区ansible web_server -m mount -a 'name=/data state=unmounted'(54)确保⼀个分区是挂载状态,如果不是则挂载ansible web_server -m mount -a 'name=/data src=/dev/sdb1 fstype=ext4 state=present'关于playbook的内容请继续关注我的后续博⽂,谢谢!

发布者:admin,转转请注明出处:http://www.yc00.com/web/1687691401a32073.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信