3 Ansible安装和入门

3.1 Ansible安装

ansible的安装方法有多种

官方方档:https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html

下载:https://releases.ansible.com/ansible/

pip下载:https://pypi.org/project/ansible/

3.1.1 EPEL源的rpm包安装:

[root@ansible ~]# yum install ansible -y

3.1.2 编译安装

yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
wget https://releases.ansible.com/ansible/ansible-2.7.7.tar.gz
tar xvf ansible-2.7.7.tar.gz
cd ansible-2.7.7
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible

3.1.3 Git安装

git clone git://github.com/ansible/ansible.git --recursive
cd ./ansible
source ./hacking/env-setup

3.1.4 pip安装

pip是安装python包的管理器,类似于yum

# 安装前注意python版本和pip版本匹配情况,pip21.0版本后不支持python2.7
# 安装pip
[root@centos7 ~]# curl https://bootstrap.pypa.io/pip/2.7/get-pip.py -o get-pip.py
[root@centos7 ~]# python get-pip.py
[root@centos7 ~]# pip -V
pip 20.3.4 from /usr/lib/python2.7/site-packages/pip (python 2.7)
# 安装基础环境
[root@centos7 ~]# yum install gcc glibc-devel zlib-devel rpm-build openssl-devel -y
[root@centos7 ~]# yum install -y python-devel
# 安装ansible
[root@centos7 ~]# pip install ansible
[root@centos7 ~]# ansible --version
[DEPRECATION WARNING]: Ansible will require Python 3.8 or newer on the controller 
starting with Ansible 2.12. Current version: 2.7.5 (default, Nov 16 2020, 22:23:17) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]. This feature will be removed from ansible-core
 in version 2.12. Deprecation warnings can be disabled by setting 
deprecation_warnings=False in ansible.cfg.
/usr/lib/python2.7/site-packages/ansible/parsing/vault/__init__.py:44: CryptographyDeprecationWarning: Python 2 is no longer supported by the Python core team. Support for it is now deprecated in cryptography, and will be removed in the next release.
  from cryptography.exceptions import InvalidSignature
ansible [core 2.11.1] 
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
  jinja version = 2.11.3
  libyaml = True

# pip安装是没有config file文件的 我们可以将官网的默认文件上传到服务器
[root@centos7 ~]# mkdir /etc/ansible
[root@centos7 ~]# touch /etc/ansible/ansible.cfg

3.1.5 确认安装

[root@ansible ~]# ansible --version
ansible 2.9.21
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

3.2 Ansible相关文件

3.2.1 配置文件

  • /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
  • /etc/ansible/hosts 主机清单
  • /etc/ansible/roles 存放角色的目录

3.2.2 ansible主配置文件

Ansible的配置文件/etc/ansible/ansible.cfg,其中大部分的配置内容无需进行修改

[defaults]
#inventory      = /etc/ansible/hosts        # 主机列表配置文件
#library        = /usr/share/my_modules/    # 库文件存放目录
#remote_tmp     = ~/.ansible/tmp    # 临时py命令文件存放再远程主机的目录
#local_tmp      = ~/.ansible/tmp    # 本机的临时命令执行目录
#forks          = 5     # 默认并发数
#sudo_user      = root  # 默认sudo用户
#ask_sudo_pass = True   # 每次执行ansible命令是否需要询问ssh密码
#ask_pass      = True
#remote_port    = 22
#host_key_checking = False          # 检查对应服务器的host_key,建议取消注释
#log_path = /var/log/ansible.log    #日志文件,建议启用
#module_name = command  # 默认模块,可以修改为shell模块

3.2.3 inventory主机清单

ansible的主要功用在于批量主机操作,为了便捷地使用其中的部分主机,可以在inventory file中将其分组命名
默认的inventory file为/etc/ansible/hosts
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成

官方文档:https://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html

主机清单文件格式

inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组中

此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来标明

如果主机名称遵循相似的命名模式,还可以使用列表的方式标识各主机

mail.waluna.top

[webservers]
www.waluna.top
www.waluna.top:8888

[dbservers]
db1.waluna.top
db2.waluna.top
db3.waluna.top

[websrvs]
www[1:100].waluna.top

[databases]
db-[a:f].waluna.top

[appsrvs]
10.0.0.[1:100]

例:

[test]
10.0.0.8 ansible_connection=local   # 指定本地连接,无需ssh配置

# ansible_connection=ssh 需要StrictHostKeyChecking no
10.0.0.7 ansible_connection=ssh ansible_port=8888 ansible_user=luna ansible_password=waluna
10.0.0.6 ansible_connection=ssh ansible_user=root ansible_password=waluna

3.3 Ansible相关工具

  • /usr/bin/ansible 主程序,临时命令执行工具
  • /usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man
  • /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本
  • /usr/bin/ansible-pull 远程执行命令的工具
  • /usr/bin/ansible-vault 文件加密工具
  • /usr/bin/ansible-console 基于Console界面与用户交互的执行工具
  • /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台

利用ansible实现管理的主要方式:

  • Ad-Hoc 即利用ansible命令,主要用于临时命令使用场景
  • Ansible-playbook 主要用于长期规划好的,大型项目的场景,需要有前期的规划过程

3.3.1 ansible-doc

此工具用来显示模块帮助,相当于man

格式

ansible-doc [options] [module...]
-l, --list      # 列出可用模块
-s, --snippet   # 显示指定模块的playbook片段

例:

# 列出所有模块
ansible-doc -l
# 查看指定模块帮助用法
ansible-doc ping
# 查看指定模块帮助用法(简洁)
ansible-doc -s ping

例:

[root@ansible ~]# date
Mon May 31 16:32:17 CST 2021
[root@ansible ~]# ansible --version
ansible 2.9.21
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
[root@ansible ~]# ansible-doc -l|wc -l
3387

3.3.2 ansible

此工具通过ssh协议,实现对远程主机的配置管理、应用部署、任务执行等功能

建议:使用此工具前,先配置ansible主控端能基于密钥认证的方式联系各个被管理节点

利用sshpass批量实现基于key验证脚本1

# 可以修改配置文件,也可以在脚本中添加 StrictHostKeyChecking=no参数
[root@ansible ~]# sed -i.bak 's/#   StrictHostKeyChecking ask/StrictHostKeyChecking no/' /etc/ssh/ssh_config
[root@ansible ~]# cat hosts.list
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
[root@ansible ~]# cat push_ssh_key.sh
#!/bin/bash
rpm -q sshpass &> /dev/null || yum install sshpass -y &> /dev/null
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa -P ''
export SSHPASS=waluna
while read IP;do
    sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $IP
done < hosts.list

实现基于key验证的脚本2

[root@ansible ~]# cat ssh_key.sh
#!/bin/bash
IPLIST="
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
"

rpm -q sshpass &> /dev/null || yum install sshpass -y &> /dev/null
[ -f /root/.ssh/id_rsa ] || ssh-keygen -f /root/.ssh/id_rsa -P ''
export SSHPASS=waluna
for IP in $IPLIST;do
    sshpass -e ssh-copy-id -o StrictHostKeyChecking=no $IP
done

格式:

ansible <host-pattern> [-m module_name] [-a args]

选项说明:

--version       # 显示版本
-m module       # 指定模块,默认为command
-v              # 详细过程 -vv -vvv更详细
--list-hosts    # 显示主机列表,可简写--list
-c, --check     # 检查,并不执行
-T, --timeout=TIMEOUT   # 执行命令的超时时间,默认10s
-k, --ask-pass  # 提示输入ssh连接密码,默认Key验证
-u, --user=REMOTE_USER  # 执行远程执行的用户
-b, --become    # 代替旧版的sudo切换
--become-user=USERNAME  # 指定sudo的runas用户,默认为root
-K, --ask-become-pass   # 提示输入sudo时的口令

ansible的Host-pattern

用于匹配被控制的主机的列表

All:表示所有Inventory中的所有主机

ansible all -m ping

*:通配符

ansible "*" -m ping
ansible 10.0.0.* -m ping
ansible "websrvs" -m ping
ansible "10.0.0.6 10.0.0.7" -m ping

或关系

ansible "websrvs:appsrvs" -m ping
ansible "10.0.0.7:10.0.0.8" -m ping

逻辑与

#在websrvs组并且在dbsrvs组中的主机
ansible "websrvs:&dbsrvs" -m ping

逻辑非

# 在websrvs组,但不在dbsrvs组中的主机
# 注意:此处为单引号
ansible 'websrvs:!dbsrvs' -m ping

综合逻辑

ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' -m ping

正则表达式

ansible "websrvs:dbsrvs" -m ping
ansible "~(web|db).*\.waluna\.top" -m ping

例:

[root@ansible ~]# ansible "~(web|db)srvs" -m ping

[root@ansible ~]# ansible all --list-hosts
  hosts (4):
    10.0.0.6
    10.0.0.7
    10.0.0.8
    10.0.0.9
[root@ansible ~]# ansible websrvs --list-hosts
  hosts (2):
    10.0.0.6
    10.0.0.7
[root@ansible ~]# ansible appsrvs --list-hosts         
  hosts (2):
    10.0.0.7
    10.0.0.8
[root@ansible ~]# ansible websrvs:appsrvs --list-hosts
  hosts (3):
    10.0.0.6
    10.0.0.7
    10.0.0.8
[root@ansible ~]# ansible dbsrvs --list-hosts
  hosts (3):
    10.0.0.7
    10.0.0.8
    10.0.0.9
[root@ansible ~]# ansible "appsrvs:&dbsrvs" --list-hosts
  hosts (2):
    10.0.0.7
    10.0.0.8
[root@ansible ~]# ansible "websrvs:!appsrvs" --list-hosts
-bash: !appsrvs: event not found
[root@ansible ~]# ansible 'websrvs:!appsrvs' --list-hosts
  hosts (1):
    10.0.0.6

ansible命令执行过程

  1. 加载自己的配置文件,默认/etc/ansible/ansible.cfg
  2. 加载自己对应的模块文件,如:command
  3. 通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件
  4. 给文件+x执行
  5. 执行并返回结果
  6. 删除临时py文件,退出

ansible的执行状态:

[root@ansible ~]# grep -A 13 '\[colors\]' /etc/ansible/ansible.cfg
[colors]
#highlight = white
#verbose = blue
#warn = bright purple
#error = red
#debug = dark gray
#deprecate = purple
#skip = cyan
#unreachable = red
#ok = green
#changed = yellow
#diff_add = green
#diff_remove = red
#diff_lines = cyan
  • 绿色:执行成功并且不需要做改变的操作
  • 黄色:执行成功并且对目标主机做变更
  • 红色:执行失败

ansible使用范例

# 以luna用户执行ping存活检测
ansible all -m ping -u luna -k
# 以luna sudo至root执行ping存活检测
ansible all -m ping -u luna -k -b
# 以luna sudo至test用户执行ping存活检测
ansible all -m ping -u luna -k -b --become-user=test
# luna sudo至root用户执行ls
ansible all -m command -u luna -a 'ls /root' -b --become-user=root -k -K

3.3.3 ansible-playbook

此工具用于执行编写好的playbook任务

ansible-playbook hello.yml
cat hello.yml
#hello world yml file
- hosts: websrvs
  remote_user: root
  gather_facts: no

  tasks:
    - name: hello world
      command: /usr/bin/wall hello world

3.3.4 ansible-vault

此工具可以用于加密yml文件

格式:

ansible-vault [create|decrypt|edit|encrypt|rekey|view]

例:

ansible-vault encrypt hello.yml # 加密
ansible-vault decrypt hello.yml # 解密
ansible-vault view hello.yml    # 查看
ansible-vault edit hello.yml    # 编辑加密文件
ansible-vault rekey hello.yml   # 修改口令
ansible-vault create new.yml    # 创建新文件

3.3.5 ansible-console

此工具可交互执行命令,支持tab,ansible 2.0+新增

提示符格式:

执行用户@当前操作的主机组(当前组的主机数量)[f:并发数]$

常用子命令:

  • 设置并发数:forks n,例如:forks 10
  • 切换组:cd主机组,例如:cd web
  • 列出当前组主机列表:list
  • 列出所有的内置命令:?或help
[root@ansible ~]# ansible-console 
Welcome to the ansible console.
Type help or ? to list commands.

root@all (4)[f:5]$ ping
10.0.0.6 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.7 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.8 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.9 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
root@all (4)[f:5]$ list
10.0.0.6
10.0.0.7
10.0.0.8
10.0.0.9
root@all (4)[f:5]$ cd websrvs
root@websrvs (2)[f:5]$ list
10.0.0.6
10.0.0.7
root@websrvs (2)[f:5]$ forks 10
root@websrvs (2)[f:10]$ cd appsrvs
root@appsrvs (2)[f:10]$ yum name=httpd state=present 
root@appsrvs (2)[f:10]$ service name=httpd state=started

3.3.6 ansible-galaxy

此工具会连接https://galaxy.ansible.com/下载相应的roles

# 列出所有已安装的galaxy
ansible-galaxy list
# 安装galaxy
ansible-galaxy install geerlingguy.mysql
ansible-galaxy install geerlingguy.redis
# 删除galaxy
ansible-galaxy remove geerlingguy.redis