一.ansible的前戏
1.ansible与saltstack对比
相同点:都是为了同时在多台机器上执行相同的命令;
都是python开发;
不同点:
agent(salt 控制节点需要安装salt-master,被控节点需要安装salt-minion,而ansible不需要,它通过ssh来连接并控制被控节点)
配置(salt配置麻烦,ansible基本不用配置)
学习路线(salt比较陡峭,ansible比较平缓)
第三方工具(salt比较少)
开源社区的对接(salt比较少)
现有用户(salt还是比ansible少一些)
二次开发扩展的能力(ansible比较差,尤其是2.0以后)
大规模开发(200以内一样,200以上salt会好一些,我们也可以对ansible做一些配置使其在200以上追上salt)
Windows的支持(salt会很好多)
2.准备工作
准备四台干净的虚拟机,如下:
192.168.85.132 (主控节点,下面三个为被控节点)
192.168.85.133
192.168.85.134
192.168.85.135
3.安装ansible(只有主控节点192.168.85.132安装)
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo # 下载epel源,因为ansible需要从epel源下载 yum install -y ansible # 安装ansible
ansible安装后有一下文件
hosts文件详解:
# This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # 用#来表示注释 # - Blank lines are ignored # 空白行被忽略 # - Groups of hosts are delimited by [header] elements # 主机组 需要在【】下面 # - You can enter hostnames or ip addresses #可以写主机名或者ip地址 # - A hostname/ip can be a member of multiple groups # 一台主机可以在多个组里面 # ...... # www[001:006].example.com # 表示从www001到www006的机器 # ......
4.ansible连接并控制被控节点
ssh的认证方式
-密码连接:即ssh root@192.168.xx,xxx,然后输入密码提交
-秘钥提交:ssh秘钥登录方式如下:
ssh-keygen #用来生成ssh的秘钥对,一直回车即可 ssh-copy-id 192.168.85.133 #复制秘钥到远程主机,回车输入yes,再回车输入远程主机登录密码 ssh 192.168.85.85.133 #通过此命令就可以登录远程主机
如果想ssh连接被控节点,需在hosts中先添加被控制节点地址
ansible 192.168.85.133 -m ping
当想连接操作多台服务器时,可以将服务器分组添加到hosts文件中
5.ansible的命令帮助
ansible <host-pattern> [options] -a MODULE_ARGS 模块参数 -m MODULE_NAME 模块名称 -f forks 指定一次执行的机器,用于高并发 -C 测试 --list-host 查看运行的机器 -V 输出详情的信息
获取文档
ansible-doc --help -s 指定模块名称 -l 列出所有的模块
操作日志
/var/log/message
二.ansible命令相关模块
1.command模块
执行远程命令,但是不支持特殊字符 <> |!;$&
ansible web -a 'ls /' ansible web -a 'pwd' ansible wen -a 'chdir=/tmp pwd' #切换目录执行命令,使用场景是编译安装时使用 ansible web -a 'creates=/tmp pwd' #用来判断/tmp目录是否存在,存在就不执行操作 ansible web -a 'creates=/data pwd' #因为data不存在,所有才会执行pwd命令 ansible web -a 'removes=/tmp pwd' #用来判断tmp目录是否存在,存在就执行操作 ansible web -a 'removes=/data pwd' #因为data不存在,所有才不会执行
查看用户是否创建成功
tail -1 /etc/passwd tail -1 /etc/shadow id wudabing #查看用户id echo '123'|passwd --stdin wudabing #设置密码
2.shell模块
执行远程主机的python或shell脚本,支持特殊字符
ansible web -m shell -a 'echo "123" | passwd --stdin wudabing' # 批量创建密码 ansible 192.168.85.133 -m shell -a 'bash a.sh' # 执行远程文件方式一 ansible 192.168.85.133 -m shell -a '/root/a.sh' #执行远程文件方式二,文件必须有执行权限 ansible 192.168.85.133 -m shell -a '/root/a.py' # 执行远端的Python脚本
3.script模块
在远程主机执行主控端的shell/python脚本,使用相对路径
ansible web -m script -a '/root/m.sh' #执行本地的文件,执行管控机上的文件 ansible web -m script -a 'removes=/root/m.sh /root/m.sh' #用来判断被管控机上是不是存在文件,如果存在就执行,不存在就不执行 ansible web -m script -a 'creates=/root/a.sh /root/m.sh' #用来判断被管控机上是不是存在文件,如果存在,就不执行
三.ansible文件相关模块
1.copy模块
backup 备份,以时间戳结尾 dest 目的地址 group 文件的属组 mode 文件的权限 r 4 w 2 x 1 owner 文件的属主 src 源文件 # 通过md5码来判断是否需要复制 ansible db -m copy -a 'src=/root/m.sh dest=/tmp/a.sh' #复制本地文件的到远程主机 ansible db -m copy -a 'src=/root/m.sh dest=/tmp/a.sh mode=755' #修改文件的权限 ansible web -m copy -a 'src=/root/m.sh dest=/tmp/a.sh mode=755 owner=wudabing' 修改文件的属主 ansible web -m copy -a 'src=/etc/init.d dest=/tmp/ mode=755 owner=wudabing' # 复制本地目录到远程主机,如果改变文件的属性,则文件夹内的文件也会被改变 ansible web -m copy -a 'src=/etc/init.d/ dest=/tmp/ mode=755 owner=wudabing' # 复制本地目录内的所有文件到远程主机 ansible web -m copy -a "content='月光光照大床\n' dest=/tmp/b.txt" # 直接将文本内容注入到远程主机的文件中
2.file模块
当源文件变化时,软链接和硬链接文件都会跟着变化
inode #硬盘的地址 id #获取到的时内存的地址 ln -s a.py b.py #创建软链接 ln a.py c.py #创建硬链接
file的使用
ansible db -m file -a 'path=/lzmly2 state=directory' #在远程机器上创建文件夹 ansible db -m file -a 'path=/root/q.txt state=touch' #用来在远程机器上创建文件 ansible db -m file -a 'path=/tmp/f src=/etc/fstab state=link' #创建软连接src是源地址,path是目标地址 ansible db -m file -a 'path=/tmp/f state=absent' #用来删除文件或者文件夹
3.fetch模块
dest 目的地址 src 源地址 ansible web -m fetch -a 'src=/var/log/cron dest=/tmp' # 下载被控节点的文件,每台机器创建一个文件夹,并保留原来的目录结构
四.ansible软件相关模块
1.yum模块
rpm和yum的区别
rpm:redhat package manage
yum:可以解决依赖关系
yum源配置
[epel] name=Extra Packages for Enterprise Linux 7 - $basearch #名字 baseurl=http://mirrors.aliyun.com/epel/7/$basearch #rpm源的地址,可以写http,https,ftp,Samba,file: failovermethod=priority enabled=1 # 是否开启,1代表开启,0表示关闭 gpgcheck=0 #是否校验签名,1代表校验,0表示校验 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
disablerepo #禁用源 enablerepo #启用源 name #包名 state install (`present' or `installed', `latest'), or remove (`absent' or `removed') ansible web -m yum -a 'name=wget' # 安装wget ansible web -m yum -a 'name=python2-pip' # 安装python2-pip ansible web -m yum -a 'name=wget state=absent' # 卸载软件包 ansible web -m yum -a 'name="@Development Tools"' # 安装包组
2.pip模块
pip install #安装包 pip freeze > a.txt #将python的环境打包到文件中 pip install -r a.txt #安装文件中的包 pip list #查看所有的已安装成功的包 ansible web -m pip -a 'name=flask' # 安装flask模块
3.service模块
ps -ef|grep nginx #查看进程 ss -tnlp #查看端口信息 systemctl start nginx #centos7 service nginx start #centos6 systemctl enable nginx #centos7 开机自启动 chkconfig nginx on # centos6开机自启动
ansible web -m service -a 'name=nginx state=started' # 启动nginx ansible web -m service -a 'name=nginx state=stopped' # 关闭nginx
4.计划任务cron模块
* * * * * job 分 时 日 月 周 任务 0 */2 * * * job 每隔两个小时 0 12,13 * * * job 12点和13点 0 12-17 * * * job 12点到17点 0 12-17/2 * * 1,3,6,0 周1,周3,周6,周7 12点到17点每隔两个小时 crontab -e # 编辑计划任务 crontab -l # 查看计划任务 crontab -r # 删除计划任务 ***请勿使用*****来表示时间
ansible中cron的参数及使用
day 天 disabled 禁用 hour 小时 job 任务 minute 分钟 month 月 name 任务名字 weekday 周 ansible db -m cron -a 'minute=26 job="touch /tmp/xzmly.txt" name=touchfile' # 新建一个计划任务 ansible db -m cron -a 'name=touchfile state=absent' # 删除一个计划任务 ansible db -m cron -a 'minute=26 job="touch /tmp/xzmly.txt" name=touchfile disabled=yes' # 禁用计划任务,以#表示禁用
五.ansible用户相关模块
在linux中的正常运维操作
用户: 管理员 root 0 普通用户 系统用户 不能登录 1-999 centos7 1-499 centos6 登录用户 可以登录 1000-65535 centos7 500-65535 centos6 用户组: 管理员组 root 0 系统用户组 1-999 centos7 1-499 centos6 登录用户组 1000-65535 centos7 500-65535 centos6 -d 指定用户的家目录 -g 指定用户的组 -G 执行用户的附加组 -s 指定登录后使用的shell -r 创建一个系统组 useradd -r wusir 创建系统用户, 从999倒序 useradd -s /sbin/nologin liu 创建的是普通用户,从1000开始升序 useradd -d /opt/liu liu 创建用户时指定用户的家目录 useradd -u 3000 liu # 创建用户并指定用户的uid userdel liu 删除用户 userdel -r liu 删除用户并删除用户的家目录 groupadd wudabing 创建用户组 groupdel wudabing 删除用户组
1.use模块
group 组 groups 附加组 home 家目录 name 用户名 password 密码 remove ? shell 用户登录后使用的shell system 创建一个系统用户 uid 用来指定用户的id state 状态 ansible db -m user -a 'name=wulaoshi uid=4000 home=/opt/wulaoshi groups=root shell=/sbin/nologin' #创建一个用户,并指定用户的id,用户的家目录,用户的附加组,用户的shell ansible db -m user -a 'name=wulaoshi state=absent' #删除用户但是不删除用户的家目录 ansible db -m user -a 'name=wulaoshi3 state=absent remove=yes' # 删除用户并删除用户的家目录
2.group模块
gid 组的id name 组名 system 系统组 state ansible db -m group -a 'name=wulaoshi system=yes' #创建系统组 ansible db -m group -a 'name=wulaoshi state=absent' # 删除组
六.ansible-playbook剧本
在使用ansible-playbook时,我们会应用到一个编程语言--yaml,ansible-playbook应用的就是.yanl或.yml的文件,和写配置文件的xml,ini语言类似.
其中表达字典:key:value;列表:[ ] -
1.ansible-playbook命令格式
文件执行顺序:从上往下
特性:幂等性,不管执行多少遍,结果都是一样的.
ansible-playbook [options] playbook.yml [playbook2 ...] -C, --check # 检查,白跑,干跑 -f FORKS, --forks=FORKS #用来做并发 --list-hosts # 列出主机列表 --syntax-check # 语法检查
简单用法
- hosts: web #web为被控节点机组 tasks: - name: creategroup #任务名 group: name=liuqingyang #此行,group为模块名,对应的value为命令 - name: createuser #任务名 user: name=wudabing #user为模块名
2.传参
vi p1.yml
- hosts: web tasks: - name: create{{ user }} #参数 user: name={{ user}}
第一种方式
ansible-play -e 'user=wudabing' p1.yml #直接传参运行
第二种方式
[web] 192.168.85.133 user=wudabing1 192.168.85.134 user=wudabing2 #在hosts文件,机组中直接设置参数值
第三种方式
[web;vars] #表示组的参数 user=wudabing3
第四种方式
- hosts: web vars: - user: wudabing4 #在要运行的yml文件中设置参数值 tasks: - name: create{{ user }} #参数 user: name={{ user}}
第五种方式
- hosts: web tasks: - name: sum shell: echo 5 register: user - name: createuser user: name={{user.stdout}} #继承其他运行结果作为参数值
传参方式的优先级
-e > playbook yum文件 > hosts文件
3.条件判断
可以判断以下情况,不同条件做出不同操作
不同的系统; 不同的版本; 不同的环境; 不同的用户.
- hosts: db remote_user: root tasks: - name: createfile copy: content="宝塔镇河妖" dest=/tmp/a.txt when: a=="3" - name: cratefile copy: content="月光光,照大床" dest=/tmp/a.txt when: a=="4"
4.tags
在anible-playbook -t 指定tag
- hosts: web tasks: - name: installnginx yum: name=nginx tags: installnginx #为任务添加标签 - name: copyfile copy: src=/etc/nginx/nginx.conf dest=/etc/nginx/nginx.conf tags: copyfile #为任务添加标签 - name: start service: name=nginx state=started tags: start #为任务添加标签
ansible-playbook -t copyfile p.yml #只运行标签为copyfile的任务
5.循环with_item
通常你想在一个任务中干很多事,比如创建一群用户,安装很多包,或者重复一个轮询步骤直到收到某个特定结果.
标准循环:
- hosts: web tasks: - name: createuser user: name={{item}} with_items: -liu1 -liu2 -liu3 -name: creategroup group: name={{item}} with_items: -wu1 -wu2 -wu3
嵌套循环:
- hosts: all remote_user: root tasks: - name: add user user: name={{ item[0] }} groups={{ item[1] }} with_items: - ["old1","old2"] - ["nginx,docker"]
6.template模块
- hosts: web tasks: - name: installredis yum: name=redis - name: copyfile template: src=/etc/redis.conf dest=/etc/redis.conf - name: start service: name=redis state=started 配置文件: bind {{ ansible_default_ipv4.address }}
之所以在拷贝配置文件用template模块不用copy,因为copy模块不能代替bind后的参数,template模块可以代替.
ps:写相对路径:在当前目录下新建一个templates目录,然后把文件放在templates目录里面,比如src=templates.j2
7.handlers
Handlers 也是一些 task 的列表,通过名字来引用,它们和一般的 task 并没有什么区别。
Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行。
不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。
Handlers 最佳的应用场景是用来重启服务,或者触发系统重启操作.除此以外很少用到了。
- hosts: web tasks: - name: installredis yum: name=redis - name: copyfile template: src=redis.conf dest=/etc/redis.conf tags: copyfile notify: restart handler: - name: restart service: name=redis state=restarted
8.roles
特点:目录清晰;可以相互调用
roles文件夹:
文件夹里面要是创建的每一个角色,每一个角色一个文件夹,每一个角色里面都有tasks(必须的),templates,files,handlers,vars目录,每个目录都要有main.yml文件,通过import_tasks来调用,其中templates文件夹中的文件可以通过相对路径来调用.
来源:https://www.cnblogs.com/liuqingyang/p/10409548.html