自动化运维-ansible

一.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='月光光照大床
' 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