Ansible记录

# 


# 前戏:

ansible

openpyxl



puppet

ansible

saltstack



# ansible

批量在远程主机上执行命令

python2.7编写

## 安装

第一步:下载epel源

```shell
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
```

第二步:安装

```shell
yum install -y ansible
```

## ansible 命令格式

```shell
Usage: ansible <host-pattern> [options]
-a MODULE_ARGS 模块参数
-C, --check  检查语法
-f FORKS 并发
--list-hosts 列出主机列表
-m MODULE_NAME 模块名字
```

ssh 认证方式

- 密码
- 秘钥
  - ssh-keygen 生成密钥对
  - ssh-copy-id 复制公钥到远程主机
  - 私钥加密,公钥解密

  查看ansible生成的文件

```shell
rpm -ql ansible
/etc/ansible
/etc/ansible/ansible.cfg  # ansible 配置文件
/etc/ansible/hosts
/etc/ansible/roles
```

## ping 走的是ICMP协议

## ansible第一条命令

```shell
ansible 192.168.12.26 -m ping  ping 一台机器
ansible 192.168.12.26,192.168.12.28 -m ping ping多台机器
ansible all -m ping ping所有机器
ansible web -m ping ping 一个组
ansible 'web:!db' -m ping ping web中有但是db中没有
ansible "web:&db" -m ping ping web和db的并集
ansible "web:db" -m ping  ping web和db的交集

```

hosts文件内容

```shell
# 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.example.com
```

### host-pattern格式

- 单个的机器
- 多个的机器,逗号隔开
- 全部机器,all
- 可以写一个分组
- 可以写多个分组
  - 并集
    - 逗号隔开
    - 冒号隔开
  - 交集,:&隔开
  - 差集: :!隔开

## ansible-doc 查看模块帮助信息

```shell
 ansible-doc [-l|-F|-s] [options] [-t <plugin type> ] [plugin]
 -j 以json格式显示所有模块信息
 -l 列出所有的模块
 -s 显示模块的摘要信息
 # 直接显示模块的所有帮助信息

```

ansible 特性: 幂等性 不管执行几次,结果都是一样的

# 命令相关

## command

```shell
ansible web -a 'ls'
ansible web -a 'chdir=/tmp pwd'  # 先切换目录,在执行相应的命令,一般情况下在编译时候使用
ansible web -a 'creates=/tmp pwd' # 如果creates的文件存在,则不执行后面的操作
ansible web -a 'removes=/tmp pwd' # 如果removes的文件存在,则执行后面的操作
ansible web -a 'removes=/tmp mkdir /data' # 会执行后面的mkdir命令
ansible web -a 'creates=/data2 mkdir /data2' #会执行后面的mkdir命令

```

补充

```shell
查看用户是否被创建成功
tail -1 /etc/passwd     -1最后一条显示
tail -1 /etc/shadow
id xxxx
  非交互式设置密码
```

## shell 

```shell
<>|;& $ 这些特殊字符command不支持
ansible web -m shell -a 'echo "1" | passwd --stdin alex' 设置alex的密码
ansible 192.168.12.25 -m shell -a '/root/a.sh' 执行shell脚本,前提是脚本有可执行权限
ansible 192.168.12.25 -m shell -a '/root/a.py' 执行python脚本,前提是脚本有可执行权限

```

## script

```shell
ansible db -m script -a '/root/m.sh' 执行管控机上的文件
ansible web -m script -a 'creates=/root/a.sh /root/m.sh' # 查看的是被管控机上的文件是否存在
```

# 文件相关的模块

## copy

```shell
 ansible db -m copy -a "dest=/tmp/a.sh src=/root/m.sh" 复制文件到远程主机
 ansible db -m copy -a "dest=/tmp/a.sh src=/root/m.sh backup=yes" 复制文件并备份远程文件
 ansible web -m copy -a "dest=/tmp/a.sh src=/root/m.sh owner=alex mode=700" 修改复制后的文件的属主和权限
 ansible web -m copy -a "src=/etc/init.d dest=/tmp" 复制目录到远程主机
 ansible web -m copy -a "src=/etc/init.d/ dest=/tmp" 复制目录里面的文件到远程主机
 ansible web -m copy -a "src=/etc/ansible dest=/tmp owner=alex" 复制目录到远程主机,并修改目录的属主,并且里面文件的属主也被修改了
 ansible web -m copy -a "content='大弦嘈嘈如急雨,小弦切切如私语' dest=/tmp/b.txt"  直接将content里面的内容添加到dest的文件里面
```

## file 

### 补充

```shell\
ln -s 原文件地址 目标文件地址   创建软连接
ln 创建硬链接
```

```shell
ansible cache -m file -a "path=/tmp/wupeiqi  state=directory" 创建一个目录
ansible cache -m file -a "path=/tmp/wupeiqi.txt  state=touch" 创建一个文件
ansible cache -m file -a "path=/tmp/t  state=link src=/etc/init.d" 创建软连接 path是目标文件 src是源文件
ansible cache -m file -a "path=/tmp/t  state=absent " 删除文件
```

## 今日内容总结

```shell
ansible 安装 epel源

```

host-pattern格式

- 单个主机
- 多个主机
- all
- 一个组
- 多个组
  - 交集 'web:&db'
  - 并集 'web:db'
  - 差集 'web:!db'

命令相关的模块

- command 不支持特殊字符  <>;!$|&
- shell
- script 执行管控机上的脚本

文件相关的模块

- copy 

  - content
  - dest
  - src
  - onwer
  - group
  - mode
  - backup

- file

  - path
  - state
    - directory
    - touch
    - file
    - absent
    - link
    - hard
  - src
    - link
    - hard

 

2

# 今日内容回顾

ansible 安装 epel源

host-pattern的格式

-  单台机器
- 多台机器
- 全部机器
- 单个分组
- 多个分组
  - 交集 'web:&db'
  - 并集 
    - 'web:db'
    - web,db
  - 差集 'web:!db'
- 命令相关
  - command 不支持特殊字符<>|!;$
  - shell
  - script
- 文件相关
  - copy
    - dest
    - src
    - group
    - owner
    - mode
    - backup
    - content
  - file
    - path
    - src
      - link
      - hard
    - state
      - directory
      - file
      - touch
      - link
      - hard
    - group
    - mode
    - owner

# 今日内容详解

### fetch

用来拉取 被控机上的文件,每个被控机都会创建一个文件夹,并且保留原来的目录格式

```shell
ansible web -m fetch -a 'dest=/tmp src=/var/log/cron'
```

## 软件包相关

### yum

- rpm 与yum的 区别

  - redhat package manage

- yum源配置方式

  ```shell
  [epel] # 组名
  name=Extra Packages for Enterprise Linux 7 - $basearch #名称
  baseurl=http://mirrors.aliyun.com/epel/7/$basearch #url,可以写http,https,ftp,file:
  failovermethod=priority
  enabled=1 #是否启用 1表示启用,0表示不启用
  gpgcheck=0 #是否校验gpgcheck,0表示不校验,1表示校验
  gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
  ```

- yum 安装包组

  ```shell
  yum grouplist 查询包组
  yum groupinstall -y 'Development Tools' 安装包组
  rpm -qa |grep python2-pip 查看软件包是否安装成功
  ```

  ```shell
  ansible web -m yum -a 'name=python2-pip' 安装python2-pip包
  ansible web -m yum -a 'name=@Development Tools' 安装python2-pip包
  ```

## pip

```shell
pip freeze > a.txt 给当前python环境的包打快照
pip install -r a.txt 安装文件里面所有的包
pip list 查看所有安装的包
```

```shell
ansible web -m pip -a 'name=flask' 安装pip包
```

### service

```shell
service nginx start|stop|restart # centos6
chkconfig add nginx 
chkconfig nginx on 设置开机自启动
chkconfig --list
systemctl start nginx # centos7
systemctl  enable nginx # 设置开机自启动
ss -tnlp
```

```shell
ansible web -m service -a 'name=nginx state=started' #启动服务
ansible web -m service -a 'name=nginx state=stopped' #停止服务
```

## 计划任务

### cron

```shell
分 时 日 月 周 job
1 0 * * *
* * * * * tar zcvf /tmp/etc.tar.gz /etc/ 这是一个错误的示范
2 */3 * * * 每个3小时
0 15-17 * * 2,3 每周2,周三,15-17点的0分做某件事
```

```shell
day:天
hour:小时
job:执行的任务
minute:分钟
month:月
name:名字
weekday:周
ansible web -m cron -a 'minute=10 job="touch /tmp/alex.txt" name=touchfile' #新建计划任务
ansible web -m cron -a 'minute=10 job="touch /tmp/alex.txt" name=touchfile disabled=yes' #关闭计划任务
ansible web -m cron -a 'name=touchfile state=absent' #删除计划任务

```

## 用户相关

```shell
用户:
超级用户 root 0
系统用户 不能登录 201-999 centos7 1-499 centos6
普通用户  可以登录系统 1000-60000 centos7 500-65535 centos6
组:
超级组 root 0
系统组 201-999 centos7 1-499 centos6
普通组 1000-60000 centos7 500-65535 centos6
useradd -d /opt/alex alex 指定用户的家目录
useradd -M -d /opt/alex3 alex3 不创建用户的家目录
userdel -r alex3 删除用户并删除用户的家目录
```

用户和组的关系

- 一对一 主组
- 一对多 附加组
- 多对多

```shell
ansible db -m user -a 'name=mysql home=/opt/mysql groups=root uid=2000' #创建用户,并指定用户的家目录 ,指定用户的附加组,指定用户的uid
ansible db -m user -a 'name=mysql state=absent' #删除用户但是不删除用户的家目录
ansible db -m user -a 'name=mysql state=absent remove=yes' #删除用户并删除用户的家目录
```

### group

```shell
ansible db -m group -a 'name=wusir' 创建一个普通组
ansible db -m group -a 'name=wusir state=absent' 删除组
```

### setup

```shell
ansible_all_ipv4_addresses 所有的ipv4地址
ansible_all_ipv6_addresses 所有的ipv6地址
ansible_architecture 系统的架构
ansible_date_time 系统时间
ansible_default_ipv4 系统的默认ipv4地址
ansible_distribution 系统名称
ansible_distribution_file_variety 系统的家族
ansible_distribution_major_version 系统的版本
ansible_domain 系统所在的域
ansible_fqdn 系统的主机名
ansible_hostname 系统的主机名,简写
ansible_os_family 系统的家族
ansible_processor_cores cpu的核数
ansible_processor_count cpu的颗数
ansible_processor_vcpus cpu的个数

```



web

- 创建一个用户alex   ansible web -m user -a 'name=alex'
- 创建一个用户组wusir ansible web -m group -a 'name=wusir'
- 复制/etc/fstab文件到/tmp目录下面  ansible web -m copy -a 'dest=/tmp/fstab src=/etc/fstab'
- 安装nginx  ansible web -m yum -a 'name=nginx'
- 安装redis   ansible web -m yum -a 'name=redis'
- 并新建crontab每天的晚上12点重启nginx  ansible web -m cron -a 'minute=0 hour=0 job=重启'

 ## playbook

### yaml

```shell
列表: -
字典: key:value
后缀名:yaml yml
```

### ansible-playbook的命令格式

```shell
ansible-playbook [options] playbook.yml [playbook2 ...]
-C --check 干跑 白跑
-f FORKS 用来做并发的
--list-hosts 列出主机列表
--syntax-check 语法检查
-e 传递参数
-t 指定tags
```

单台机器

```shell
- hosts: cache
  remote_user: root
  tasks:
  - name: createuser
    user: name=alex
  - name: creategroup
    group: name=wusir
  - name: installredis
    yum: name=redis
```

多台机器

```shell
- hosts: web
  remote_user: root
  tasks:
  - name: createuser
    user: name=wengang
  - name: creategroup
    group: name=gebixiaoguniang
    执行过程,所有机器都执行完第一个任务,在去执行第二个任务
```

### playbook的参数

```shell
- hosts: web
  remote_user: root
  tasks:
  -  name: create{{ user }}
     user: name={{ user }}
```

第一种传参方式: -e

第二种传参方式:hosts文件里面主机后面写

第三种传参方式:hosts文件里面写[groupname:vars]

第四种传参方式:playbook文件中vars来指定

```shell
- hosts: web
  remote_user: root
  vars:
  - user: alexsb5
  tasks:
  -  name: create{{ user }}
     user: name={{ user }}
```

第五种传参方式:通过register注册,使用的时候要使用参数的.stdout值

```shell
- hosts: web
  remote_user: root
  tasks:
  -  name: sum
     shell: echo 2+4|bc
     register: user 
  -  name: create{{ user }}
     user: name=alexsb{{ user.stdout }}
```



```shell
-e > playbooks的vars > hosts文件
```

### 条件判断

```shell
- hosts: cache
  remote_user: 文刚
  tasks:
  - name: 偷看姑娘
    dong: 偷看姑娘
    when: 站着
  - name: 偷看姑娘
    dong: 偷看姑娘
    when: 趴着
```

```shell
- hosts: web
  tasks:
  - name: file
    copy: content="凿壁偷光" dest=/tmp/wg.txt
    when: num=="2"
  - name: file
    copy: content="刷流氓" dest=/tmp/wg.txt
    when: num=="4"
```

```shell
- hosts: cache
  tasks:
  - name: createfile
    copy: content="小弦切切如私语" dest=/tmp/ppx.txt
    when: ansible_processor_vcpus==1
```

```shell
- hosts: cache
  tasks:
  - name: createfile
    copy: content="小弦切切如私语" dest=/tmp/ppx.txt
    when: ansible_python.version.major==1 #取字典内的值
```

### 标签

```shell
- hosts: cache
  remote_user: root
  tasks:
  - name: install
    yum: name=redis
  - name: copyfile
    copy: dest=/etc/redis.conf src=/root/redis.conf
  - name: startredis
    service: name=redis state=started
```

```shell
- hosts: cache
  remote_user: root
  tasks:
  - name: install
    yum: name=redis
    tags: install
  - name: copyfile
    copy: dest=/etc/redis.conf src=/root/yaml/redis.conf
    tags: copyfile
  - name: startredis
    service: name=redis state=started
    tags: start
```

### 模板

```shell
- hosts: cache
  remote_user: root
  tasks:
  - name: install
    yum: name=redis
    tags: install
  - name: copyfile
    template: dest=/etc/redis.conf src=redis.conf.j2 # 可以使用相对路径,在当前目录的templates目录里面
    tags: copyfile
  - name: startredis
    service: name=redis state=started
    tags: start
```

### 循环 with_item

```shell
- hosts: web
  remote_user: 文刚
  tasks:
  - name: 偷看姑娘A
    dong: 偷看姑娘A
  - name: 偷看姑娘B
    dong: 偷看姑娘B
  - name: 偷看姑娘C
    dong: 偷看姑娘C
```

进阶版

```shell
- hosts: web
  remote_user: 文刚
  tasks:
  - name: 偷看姑娘A
    dong: 偷看{{item}}
    with_items:
    - 姑娘A
    - 姑娘B
    - 姑娘C
```

```shell
- hosts: db
  tasks:
  - name: creatuser
    user: name={{ item }}
    with_items:
    - alex10
    - wusir10
    - taibai10
```

### 循环嵌套

```shell
- hosts: db
  tasks:
  - name: group
    group: name={{item}}
    with_items:
    -  alex20
    -  wusir20
    -  taibai20
  - name: creatuser
    user: name={{ item.name }} group={{item.group}}
    with_items:
    - {name: alex30,group: alex20}
    - {name: wusir30,group: wusir20}
    - {name: taibai30,group: taibai20}
```

### handlers

```shell
- hosts: cache
  remote_user: root
  tasks:
  - name: install
    yum: name=redis
    tags: install
  - name: copyfile
    template: dest=/etc/redis.conf src=redis.conf.j2
    tags: copyfile
    notify: restart redis
  - name: startredis
    service: name=redis state=started
    tags: start
  handlers:
  - name: restart redis
    service: name=redis state=restarted
```



# 今日内容总结:

- fetch

  - 每台机器都有一个文件夹,并且保持原来的目录的结构

- yum

  - name=@development tools 安装包组

- pip 

- service

- cron

  - disabled=yes
  - 分钟最好不要是*

- user

  - remove=yes

- group

- playbook

  - 基本
  - 传参
    - -e
    - hosts文件ip地址后面
    - hosts文件[gorup:vars]
    - playbook里面vars
    - register
    - -e > playbook > hosts
  - when
  - with_items
  - handlers
    - notify
  - template
  - 标签 -t

  



3

4

5