Top
本案例要求准备ansible的基础环境:
启动6台虚拟机禁用selinux和firewalld编辑/etc/hosts配置yum扩展源并在管理节点安装ansible此方案需要准备六台主机,1台管理主机,5台托管主机,以实现批量程序部署,批量运行命令等功能,具体要求如表-1所示:
表-1
实现此案例需要按照如下步骤进行。
步骤一:基础环境准备
1)启动6台虚拟机,由于已经讲过怎么创建,这里不再在案例里体现
2)真机配置yum仓库
[root@room9pc01 ~]# tar -xf ansible_soft.tar.xz[root@room9pc01 ~]# cd ansible_soft/[root@room9pc01 ansible_soft]# mkdir /var/ftp/ansible[root@room9pc01 ansible_soft]# cp * /var/ftp/ansible[root@room9pc01 ansible_soft]# createrepo /var/ftp/ansibleSpawning worker 0 with 1 pkgsSpawning worker 1 with 1 pkgsSpawning worker 2 with 1 pkgsSpawning worker 3 with 1 pkgsSpawning worker 4 with 1 pkgsSpawning worker 5 with 1 pkgsWorkers FinishedSaving Primary metadataSaving file lists metadataSaving other metadataGenerating sqlite DBsSqlite DBs complete3)修改主机名(容易区分,6台机器都需要修改)这里以ansible主机为例子
[root@localhost ~]# echo ansible > /etc/hostname[root@localhost ~]# hostname ansible4)配置ip(6台机器都需要配置),这里以ansible主机为例子
[root@localhost ~]# vim /etc/sysconfig/network-scripts/ifcfg-eth0# Generated by dracut initrdDEVICE="eth0"ONBOOT="yes"IPV6INIT="no"IPV4_FAILURE_FATAL="no"NM_CONTROLLED="no"TYPE="Ethernet"BOOTPROTO="static"IPADDR=192.168.1.51PREFIX=24GATEWAY=192.168.1.254[root@localhost ~]# systemctl restart network[root@localhost ~]# ifconfigeth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500inet 192.168.1.51 netmask 255.255.255.0 broadcast 192.168.1.255ether 52:54:00:b2:69:9e txqueuelen 1000 (Ethernet)RX packets 234 bytes 16379 (15.9 KiB)RX errors 0 dropped 36 overruns 0 frame 0TX packets 31 bytes 2618 (2.5 KiB)TX errors 0 dropped 0 overruns 0 carrier 0 collisions 05)配置yum客户端,在管理节点ansible上面配置
[root@ansible ~]# vim /etc/yum.repos.d/local.repo[local_repo]name=CentOS-$releasever - Basebaseurl="ftp://192.168.1.254/system"enabled=1gpgcheck=1 [local]name=localbaseurl="ftp://192.168.1.254/ansible"enabled=1gpgcheck=0[root@ansible ~]# yum clean all[root@ansible ~]# yum repolist[root@ansible ~]# yum -y install ansible[root@ansible ~]# ansible --versionansible 2.4.2.0 //显示版本说明安装成功config file = /etc/ansible/ansible.cfgconfigured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']ansible python module location = /usr/lib/python2.7/site-packages/ansibleexecutable location = /usr/bin/ansiblepython version = 2.7.5 (default, Aug 4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]6)请在6台主机上面配置/etc/hosts,这里以ansible主机为例子
[root@ansible ansible]# cat /etc/hosts192.168.1.51 ansible192.168.1.52 web1192.168.1.53 web2192.168.1.54 db1192.168.1.55 db2192.168.1.56 cache本案例要求:
熟悉ansible配置文件定义主机,分组和子组练习自定义文件,多配置路径练习实现此案例需要按照如下步骤进行。
步骤一:ansible.cfg配置文件
[root@ansible ~]# cd /etc/ansible/[root@ansible ansible]# lsansible.cfg hosts roles[root@ansible ansible]# vim ansible.cfg#inventory = /etc/ansible/hosts //指定分组文件路径,主机的分组文件hosts[selinux] //组名称,selinux的相关选项在这个下面配置...[colors] //组名称,colors的相关选项在这个下面配置...步骤二:定义主机,分组和子组练习
1)静态主机的定义
[root@ansible ansible]# vim hosts[web]web1web2 [db]db[1:2] //1:2为db1到db2两台主机,1:20为db1到db20多台主机 [other]cache [root@ansible ansible]# ansible web --list-host //显示web组的主机hosts (2):web1web2[root@ansible ansible]# ansible db --list-host hosts (2):db1db2[root@ansible ansible]# ansible other --list-hosthosts (1):cache[root@ansible ansible]# ansible all --list-host //显示所有组的主机hosts (5):web1web2cachedb1db22)直接测试
[root@ansible ansible]# ansible cache -m ping //测试是否可以连接,若失败颜色为红色cache | UNREACHABLE! => {"changed": false,"msg": "Failed to connect to the host via ssh: ssh: Could not resolve hostname cache: Name or service not known\r\n","unreachable": true}3)修改后测试
[root@ansible ansible]# vi hosts[other]cache ansible_ssh_user="root" ansible_ssh_pass="a" [root@ansible ansible]# ansible other -m ping //测试成功,颜色为绿色cache | SUCCESS => {"changed": false,"ping": "pong"}4)不检测主机的sshkey,在第一次连接的时候不用输入yes
[root@ansible ansible]# vim ansible.cfg61 host_key_checking = False[root@ansible ansible]# vim hosts[web]web1web2 [web:vars] //web组:变量(vars不改),web组的多台机器共用一个用户名和密码ansible_ssh_user="root"ansible_ssh_pass="a"[root@ansible ansible]# ansible web -m pingweb2 | SUCCESS => {"changed": false,"ping": "pong"}web1 | SUCCESS => {"changed": false,"ping": "pong"}步骤三:定义子组
[root@ansible ansible]# vi hosts[app:children] //指定子分组(app可改:children不改),web,db是提前分好的组webdb [app:vars]ansible_ssh_user="root"ansible_ssh_pass="a"[root@ansible ansible]# ansible app --list-host //查看hosts (4):web1web2db1db2[root@ansible ansible]# ansible app -m ping //测试web1 | SUCCESS => {"changed": false,"ping": "pong"}web2 | SUCCESS => {"changed": false,"ping": "pong"}db1 | SUCCESS => {"changed": false,"ping": "pong"}db2 | SUCCESS => {"changed": false,"ping": "pong"}步骤四:多路径练习
自定义的ansible文件只在当前路径生效
1)多路径
[root@ansible ~]# mkdir aaa[root@ansible ~]# cd aaa/[root@ansible aaa]# vim myhost[app1]web1db1 [app2]web2db2 [app:children]app1app2 [other]cache [app:vars]ansible_ssh_user="root"ansible_ssh_pass="a"[root@ansible aaa]# touch ansible.cfg[root@ansible aaa]# grep -Ev "^#|^$" /etc/ansible/ansible.cfg[defaults]roles_path = /etc/ansible/roles:/usr/share/ansible/roleshost_key_checking = False[inventory][privilege_escalation][paramiko_connection][ssh_connection][persistent_connection][accelerate][selinux][colors][diff] [root@ansible aaa]# vim ansible.cfg[defaults]inventory = myhosthost_key_checking = False2)测试结果
[root@ansible aaa]# ansible app1 -m pingweb1 | SUCCESS => {"changed": false,"ping": "pong"}db1 | SUCCESS => {"changed": false,"ping": "pong"}[root@ansible aaa]# ansible app -m pingweb1 | SUCCESS => {"changed": false,"ping": "pong"}db1 | SUCCESS => {"changed": false,"ping": "pong"}db2 | SUCCESS => {"changed": false,"ping": "pong"}web2 | SUCCESS => {"changed": false,"ping": "pong"}[root@ansible aaa]# ansible app --list-hosthosts (4):web1db1web2db2[root@ansible aaa]# cd[root@ansible ~]# ansible app1 --list-host //切换到别的目录,测试失败[WARNING]: Could not match supplied host pattern, ignoring: app1 [WARNING]: No hosts matched, nothing to do hosts (0):本案例要求:
脚本输出主机列表实现此案例需要按照如下步骤进行。
步骤一:脚本输出主机列表
[root@ansible ~]# cd aaa[root@ansible aaa]# vim host.py#!/usr/bin/pythonimport jsonhostlist = {}hostlist["bb"] = ["192.168.1.52", "192.168.1.53"]hostlist["192.168.1.54"] = {"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"}hostlist["aa"] = {"hosts" : ["192.168.1.55", "192.168.1.56"],"vars" : {"ansible_ssh_user":"root","ansible_ssh_pass":"pwd"}}print(json.dumps(hostlist))[root@ansible aaa]# chmod 755 ./host.py步骤二:脚本输出样例(这样写输出的结果有些乱)
[root@ansible aaa]# ./host.py{"aa": {"hosts": ["192.168.1.55", "192.168.1.56"], "vars": {"ansible_ssh_user": "root", "ansible_ssh_pass": "a"}}, "192.168.1.54": {"ansible_ssh_user": "root", "ansible_ssh_pass": "a"}, "bb": ["192.168.1.52", "192.168.1.53"]}步骤三:可以用shell脚本输出
[root@ansible aaa]# vim my.sh#!/bin/bashecho '{ "aa": {"hosts":["192.168.1.55", "192.168.1.56"],"vars": {"ansible_ssh_user": "root","ansible_ssh_pass": "a"}},}'[root@ansible aaa]# chmod 755 my.sh[root@ansible aaa]# ./my.sh { "aa": { "hosts": ["192.168.1.55", "192.168.1.56"],"vars": { "ansible_ssh_user": "root", "ansible_ssh_pass": "a"}},}[root@ansible aaa]# vim ansible.cfg[defaults]inventory = my.shhost_key_checking = False[root@ansible aaa]# ansible aa -m ping192.168.1.55 | SUCCESS => {"changed": false,"ping": "pong"}192.168.1.56 | SUCCESS => {"changed": false,"ping": "pong"}步骤二:批量执行
1)查看负载
[root@ansible aaa]# ansible app -m command -a 'uptime' db1 | SUCCESS | rc=0 >>11:35:52 up 1:59, 2 users, load average: 0.00, 0.01, 0.01 web1 | SUCCESS | rc=0 >>11:35:52 up 2:00, 2 users, load average: 0.00, 0.01, 0.02 db2 | SUCCESS | rc=0 >>11:35:53 up 1:59, 2 users, load average: 0.00, 0.01, 0.03 web2 | SUCCESS | rc=0 >>11:35:52 up 1:59, 2 users, load average: 0.00, 0.01, 0.022)查看时间
[root@ansible aaa]# ansible app -m command -a 'date +%F\ %T'db1 | SUCCESS | rc=0 >>2018-09-06 11:42:18 web1 | SUCCESS | rc=0 >>2018-09-06 11:42:18 web2 | SUCCESS | rc=0 >>2018-09-06 11:42:18 db2 | SUCCESS | rc=0 >>2018-09-06 11:42:19本案例要求:
创建一对密钥给所有主机部署密钥实现此案例需要按照如下步骤进行。
步骤一:批量部署证书文件,给所有主机部署密钥
1)创建密钥
[root@ansible aaa]# cd /root/.ssh/[root@ansible .ssh]# vi /etc/ansible/hosts[web]web1web2 [db]db[1:2] [other]cache[root@ansible .ssh]# ansible all -m ping //直接ping会报错[root@ansible .ssh]# ssh-keygen -t rsa -b 2048 -N '' //创建密钥2)给所有主机部署密钥
[root@ansible .ssh]# ansible all -m authorized_key -a "user=root exclusive=true manage_dir=true key='$(< /root/.ssh/id_rsa.pub)'" -kSSH password: //输入密码[root@ansible .ssh]# ansible all -m ping //成功web2 | SUCCESS => {"changed": false,"ping": "pong"}db2 | SUCCESS => {"changed": false,"ping": "pong"}web1 | SUCCESS => {"changed": false,"ping": "pong"}cache | SUCCESS => {"changed": false,"ping": "pong"}db1 | SUCCESS => {"changed": false,"ping": "pong"}[root@ansible .ssh]# ssh web1 //不需要输入密码,可以直接登陆Last login: Thu Sep 6 11:49:00 2018 from 192.168.1.51[root@web1 ~]#本案例要求:
练习使用command , shell , raw, script模块实现此案例需要按照如下步骤进行。
步骤一:练习模块
ansible-doc //模块的手册,相当于man
ansible-doc -l //列出所有模块
ansible-doc 模块名 //查看指定模块的帮助信息
1)ping模块
[root@ansible .ssh]# ansible web1 -m pingweb1 | SUCCESS => {"changed": false,"ping": "pong"}2)command模块
[root@ansible .ssh]# ansible web1 -m command -a 'chdir=/tmp touch f1' //创建成功[root@web1 ~]# cd /tmp/[root@web1 tmp]# ls //在web1上面查看f13)shell模块
[root@ansible .ssh]# ansible web1 -m shell -a 'chdir=/tmp touch f2' //创建成功[root@web1 ~]# cd /tmp/[root@web1 tmp]# ls //在web1上面查看f24)raw模块
[root@ansible .ssh]# ansible web1 -m raw -a 'chdir=/tmp touch f3'//文件可以创建,但无法切换目录,文件在用户家目录下生成web1 | SUCCESS | rc=0 >>Shared connection to web1 closed.[root@web1 tmp]# cd /root/[root@web1 ~]# ls //在web1上面查看f35)script模块
对于太复杂的命令,可以写个脚本,然后用script模块执行
在web1主机上创建zhangsan3用户,修改zhangsan3的密码为123456,设置zhangsan3第一次登陆必须修改密码
用命令写:
[root@ansible .ssh]# ansible web1 -m shell -a 'useradd zhangsan3'[root@ansible .ssh]# ansible web1 -m shell -a 'echo 123456 | passwd --stdin zhangsan3'[root@ansible .ssh]# ssh -l zhangsan3 web1zhangsan3@web1's password: //输入zhangsan3的密码[root@ansible .ssh]# ansible web1 -m shell -a 'chage -d 0 zhangsan3'[root@ansible .ssh]# ssh -l zhangsan3 web1用脚本写,script模块执行:
[root@ansible .ssh]# vim user.sh#!/bin/bashuseradd zhangsan3echo 123456 | passwd --stdin zhangsan3chage -d 0 zhangsan3echo[root@ansible .ssh]# ansible web1 -m script -a './user.sh'web1 | SUCCESS => {"changed": true,"rc": 0,"stderr": "Shared connection to web1 closed.\r\n","stdout": "Changing password for user zhangsan3.\r\npasswd: all authentication tokens updated successfully.\r\n\r\n","stdout_lines": ["Changing password for user zhangsan3.","passwd: all authentication tokens updated successfully.",""]}[root@ansible .ssh]# ssh -l lisi web1lisi@web1's password:You are required to change your password immediately (root enforced)Last login: Thu Sep 6 14:51:33 2018 from 192.168.1.51WARNING: Your password has expired.You must change your password now and login again!Changing password for user lisi.Changing password for lisi.(current) UNIX password:本案例要求:
使用copy模块同步数据使用lineinfile模块编辑文件使用replace模块修改文件实现此案例需要按照如下步骤进行。
步骤一:模块练习
1)使用copy模块同步数据
src:要复制到进程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync
dest:必选项。进程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
backup:在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no
force:如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
[root@ansible .ssh]# ansible all -m shell -a 'cat /etc/resolv.conf'//查看/etc/resolv.confcache | SUCCESS | rc=0 >>; generated by /usr/sbin/dhclient-scriptnameserver 192.168.1.254search localhost db2 | SUCCESS | rc=0 >>; generated by /usr/sbin/dhclient-scriptnameserver 192.168.1.254search localhost web1 | SUCCESS | rc=0 >>; generated by /usr/sbin/dhclient-scriptnameserver 192.168.1.254search localhost web2 | SUCCESS | rc=0 >>; generated by /usr/sbin/dhclient-scriptnameserver 192.168.1.254search localhost db1 | SUCCESS | rc=0 >>; generated by /usr/sbin/dhclient-scriptnameserver 192.168.1.254search localhost [root@ansible .ssh]# vi /etc/resolv.confnameserver 172.40.1.10[root@ansible .ssh]# ansible all -m copy -a 'src=/etc/resolv.conf dest=/etc/resolv.conf' //复制本机的resolv.conf到其他主机[root@ansible .ssh]# ansible all -m shell -a 'cat /etc/resolv.conf'//查看有nameserver 172.40.1.10[root@ansible ~]# mkdir aa[root@ansible ~]# ansible all -m copy -a 'src=/root/aa dest=/root/a.log'//复制本机的目录/root/aa到其他机器的/root/a.log,复制目录只能少数批量执行同步[root@ansible ~]# ansible all -m shell -a 'ls -ld /root'db2 | SUCCESS | rc=0 >>dr-xr-x---. 4 root root 167 Sep 6 11:48 /root web2 | SUCCESS | rc=0 >>dr-xr-x---. 4 root root 167 Sep 6 11:48 /root cache | SUCCESS | rc=0 >>dr-xr-x---. 4 root root 177 Sep 6 14:35 /root db1 | SUCCESS | rc=0 >>dr-xr-x---. 4 root root 167 Sep 6 11:48 /root web1 | SUCCESS | rc=0 >>dr-xr-x---. 4 root root 177 Sep 6 14:35 /root2)使用lineinfile模块编辑文件
以行为基础,整行修改(整行被替换掉)
[root@ansible ~]# ansible cache -m lineinfile \-a 'path=/etc/sysconfig/network-scripts/ifcfg-eth0 \regexp="^ONBOOT=" line="ONBOOT=\"no\""' cache | SUCCESS => {"backup": "","changed": true,"msg": "line replaced"}3)使用replace模块修改文件
修改文件的某一部分(替换一行中匹配的内容),以正则表达式匹配为基础修改
[root@ansible ~]# ansible cache -m replace -a \'path=/etc/sysconfig/network-scripts/ifcfg-eth0 \regexp="^(ONBOOT=).*" replace="\1\"yes\""' cache | SUCCESS => {"changed": true,"msg": "1 replacements made"}本案例要求:
安装Apache并修改监听端口为8080修改ServerName配置,执行apachectl -t命令不报错设置默认主页hello world启动服务并设开机自启实现此案例需要按照如下步骤进行。
步骤一:熟悉模块
1)yum模块
[root@ansible ~]# ansible other -m yum -a 'name="lrzsz" state=removed'//lrzsz软件包名,removed=absent删除[root@ansible ~]# ansible other -m yum -a 'name="lrzsz,lftp" state=installed'//安装多个软件包,不写state默认为安装2)service模块
[root@ansible ~]# ansible other -m service -a 'name="sshd" enabled="yes" state="started"' //sshd服务名,开机启动同时启动这个服务3)setup模块
filter 过滤指定的关键字(可以过滤到我们需要的信息)
[root@ansible ~]# ansible cache -m setup -a 'filter=os'cache | SUCCESS => {"ansible_facts": {},"changed": false}[root@ansible ~]# ansible cache -m setup -a 'filter=ansible_distribution'cache | SUCCESS => {"ansible_facts": {"ansible_distribution": "CentOS"},"changed": false}步骤二:安装Apache
1)安装Apache服务设置开机自启
[root@ansible ~]# ansible cache -m yum -a 'name=httpd state=installed'[root@ansible ~]# ansible cache -m service -a 'name=httpd enabled=yes state=started'2)修改端口号为8080
[root@ansible ~]# ssh cacheLast login: Thu Sep 6 15:30:33 2018 from 192.168.1.51[root@cache ~]# cat /etc/httpd/conf/httpd.conf | grep ListenListen 80[root@ansible ~]# ansible cache -m lineinfile -a 'path="/etc/httpd/conf/httpd.conf" regexp="^Listen " line="Listen 8080"'cache | SUCCESS => {"backup": "","changed": true,"msg": "line replaced"}[root@ansible ~]# ssh cacheListen 8080步骤三:修改ServerName配置,执行apachectl -t命令不报错
1)没有修改之前
[root@cache ~]# apachectl -t //有报错AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 192.168.1.56. Set the 'ServerName' directive globally to suppress this messageSyntax OK2)修改之后
[root@ansible ~]# ansible cache -m lineinfile -a 'path="/etc/httpd/conf/httpd.conf" regexp="^ServerName " line="ServerName 0.0.0.0"'cache | SUCCESS => {"backup": "","changed": true,"msg": "line added"}[root@ansible ~]# ssh cacheLast login: Thu Sep 6 15:36:08 2018 from 192.168.1.51[root@cache ~]# apachectl -tSyntax OK步骤四:设置默认主页为hello world
[root@ansible ~]# ansible cache -m copy -a 'src=/root/index.html dest=/var/www/html/index.html' ///root/index.html这个页面可以自己写cache | SUCCESS => {"changed": true,"checksum": "22596363b3de40b06f981fb85d82312e8c0ed511","dest": "/var/www/html/index.html","gid": 0,"group": "root","md5sum": "6f5902ac237024bdd0c176cb93063dc4","mode": "0644","owner": "root","size": 12,"src": "/root/.ansible/tmp/ansible-tmp-1536219767.29-30682157793478/source","state": "file","uid": 0}