TOC

Ansible简介

    ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能;
    ansible是基于paramiko开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的,ansible目前已经已经被红帽官方收购,是自动化运维工具中大家认可度最高的,并且上手容易,学习简单;

Ansible程序命令

    Ansible程序提供了很多命令,它们分别实现不同的功能,如下示例;
ansible:临时命令执行工具,常用于临时命令的执行;
ansible-doc:ansible功能模块查看工具;
ansible-galaxy:上传/下载优秀代码或Roles模块的官网平台;
ansible-playbook:定制自动化的任务集编排工具;
ansible-pull:ansible远程执行命令工具(使用较少,海量机器时使用);
ansible-vault:文件加密工具;
ansible-console:ansible基于linux consoble界面可与用户交互的命令执行工具 ;

ansible-doc命令参数

    ansible-doc命令主要的作用就是用来获取ansible程序内支持的模块的帮助信息,该命令主要有两个命令可供我们使用,如下
    语法格式:ansible <options> [module_name]
-l:查看当前ansible程序支持的所有模块;
-s:查看指定模块的帮助信息;

ansible命令参数

    ansible命令是实现自动化操作的一个基础命令,使用ansible命令可以完成一些小众化的基础操作,它也提供了很多命令行参数,用来指定ansible的各种运行环境,如下;
    语法格式:ansible <host-pattern> options
-m:要执行的模块,默认为command模块;
-a:指定模块的参数;
-u:ssh连接的用户名,默认用root,在ansible.cfg中可以配置;
-b,--become:变成那个用户身份,不提示密码;
-k:提示输入ssh登录密码,当使用密码验证的时候用;
-s:以sudo的方式运行;
-U:sudo到哪个用户,默认为root;
-K:提示输入sudo密码,当不是NOPASSWD模式时使用;
-C:只是测试一下会改变什么内容,不会真正去执行;
-c:连接类型(default=smart),local表示仅连接本地主机;
-f:fork多少进程并发处理,默认为5个;
-i:指定hosts文件路径,默认default=/etc/ansible/hosts;
-I:指定pattern,对已匹配的主机中再过滤一次;
--list-hosts:只打印有哪些主机会执行这个命令,不会实际执行;
-M:要执行的模块路径,默认为/usr/share/ansible;
-o:压缩输出,摘要输出;
--private-key:私钥路径;
-T:ssh连接超时时间,默认是10秒;
-t:日志输出到该目录,日志文件名以主机命名;
-v:显示详细日志;

主机清单配置

    如果想要使用Ansible来管控其他主机,首先,我们必须将被控机的连接IP或者主机名加入到Ansible的主机清单配置文件中,该主机清单,在配置文件中使用inventory来指定,默认的主机清单配置文件在/etc/ansible/hosts下;
    在主机清单配置文件中来定义被控主机,有很多种语法,我们可以将主机的IP或者主机名直接写入主机清单配置文件中,这样就是声明该主机为ansible的被控主机,如下示例;
[cce@doorta ~]# echo 172.16.1.1 > /etc/ansible/hosts
[cce@doorta ~]# ansible 172.16.1.1 --list-hosts
  hosts (1):
    172.16.1.1

匹配所有主机

    那么如果我们希望直接对当前ansible所管理的所有被控主机实行管理操作,那么我们主要有两种方式,我们可以使用all或者"*"来匹配所有的主机,如下示例;
[cce@doorta ~]# echo 172.16.1.2 >> /etc/ansible/hosts
[cce@doorta ~]# ansible all --list-hosts
  hosts (2):
    172.16.1.1
    172.16.1.2
[cce@doorta ~]# ansible "*" --list-hosts
  hosts (2):
    172.16.1.1
    172.16.1.2

主机参数

    在定义主机时,我们可以定义一些参数,来告知Ansible该如何去连接目标主机和指定目标主机的一些基础配置,具体的参数如下;
ansible_ssh_host:将要连接的远程主机名,与你想要设定的主机的别名不同的话,可通过此变量设置;
ansible_ssh_port:指定该主机或者组下面的所有主机连接时的SSH端口号,默认为22;
ansible_ssh_user:指定该主机或者组下面的所有主机连接时的SSH用户名;
ansible_ssh_pass:指定该主机或者组下面的所有主机连接时的SSH用户名;
ansible_sudo_pass:指定该主机或者组下面的所有主机连接之后调用sudo命令的密码;
ansible_sudo_exe:指定该主机或者组下面的所有主机连接之后调用sudo命令的路径;
ansible_ssh_private_key_file:指定该主机或者组下面的所有主机连接时的使用的密钥文件路径;
ansible_shell_type:指定该主机或者组下面的所有主机连接之后所使用的shell,如sh、csh、fish;
ansible_python_interpreter:指定该主机或者组下面的所有主机的Python路径,当系统中有多个Python, 可使用;
    这些参数,直接定义在我们的主机IP或者主机名的后面即可,多个参数使用空格分割,如下示例;
[cce@doorta ~]# cat /etc/ansible/hosts
172.16.1.1 ansible_ssh_port=23 ansible_ssh_user=ansible

主机组清单配置

    那么当我们的主机非常多的时候,我们可以通过定义主机组的形式来组织我们的被控主机,这样更加便于管理,对于主机组的定义就是使用"[group_name]"的语法来定义,然后将属于该组的主机直接放在组下即可,那么在对改组下面的主机进行管控时,直接指明组名即可,如下示例;

如下示例;

[cce@doorta ~]# cat > /etc/ansible/hosts << EOF
[linux]
172.16.1.1
172.16.1.2
EOF
[cce@doorta ~]# ansible linux --list-hosts
  hosts (2):
    172.16.1.1
    172.16.1.2

与或非关系

    在真正的实际环境中,作为运维来讲,管控的服务器会非常的多,那么一般来讲,我们都会对这些主机进行逐一分组,那么如果我们希望同时对多个没有任何关系对组进行统一调度该怎么做呢,或者如果我们希望从一个大组里面排除一个小组应该怎么做呢,这里就需要用到一些与或非对关系;
    与关系表示,多个组之间都同时存在的主机,而或的关系,表示两个组之间的主机组合并去重得到的主机,而非的关系,表示,在前面的组里面,但是不再后面组里面的主机,如下示例
[cce@doorta ~]# cat /etc/ansible/hosts 
[linux]
172.16.1.1
172.16.1.2

[db]
172.16.1.1

[app]
172.16.1.2
# 与关系
[cce@doorta ~]# ansible "linux:&app" --list-hosts
  hosts (1):
    172.16.1.2
# 或关系
[cce@doorta ~]# ansible 'linux:&app' --list-hosts
  hosts (1):
    172.16.1.2
# 非关系
[cce@doorta ~]# ansible 'linux:!app' --list-hosts
  hosts (1):
    172.16.1.1

子组

    在实际的生产环境中,一般会将一个大项目所用的主机都放在一个组下面, 然后在这个组下面在去划分子组,比如数据库服务器一个组,中间件服务器一个组,应用服务器一个组,那么对于Ansible来讲,它也是支持子组划分的;
    Ansible的子组划分需要用到一个关键字,即children,当我们定义组名的时候,在组名后面加上一个以冒号分割的children关键字时,就表示,该组是一个大组,在该组下面并非普通的主机,而是主机组,如下示例;
[cce@doorta ~]# cat /etc/ansible/hosts 
[shop:children]  # 定义子组
db
app

[db]
172.16.1.1

[app]
172.16.1.2
[cce@doorta ~]# ansible shop --list-hosts
  hosts (2):
    172.16.1.1
    172.16.1.2
# 可以通过大组的名称直接拿到所有子组下面的所有主机

主机组参数

    在定义主机组时,可以向定义主机参数一样,直接给整个主机组定义参数,来告知Ansible该如何去连接目标该组下面的所有主机,具体的参数和主机参数一致;
    对于主机组参数的定义有点特殊,如果我们希望给一个组定义参数需要用到一个关键字,即vars,我们需要单独对一个组进行参数定义,就需要一个单独的参数组,这个参数组的定义有点特殊,需要在指定的组名后面加上一个以冒号分割的vars关键字时,就表示,给指定的组来定义参数,一个参数一行,如下示例;
[cce@doorta ~]# cat /etc/ansible/hosts
[linux]
172.16.1.1
172.16.1.2

[linux:vars]  # 给linux组统一定义参数
ansible_ssh_user=root
ansible_ssh_pass=caichangen
ansible_ssh_port=22

密钥连接

    控制端主机连接被控端主机的方式除了通过密码认证的方式之外,还可以通过密钥的方式认证,在正式的应用环境中,大多数企业都会选择通过密钥的方式来连接被控主机,因为通过密钥认证更加的安全,更加便捷;
    那么想要指定密钥文件进行连接,首先,我们需要创建一对密钥对儿,然后将公钥分发给远端主机,将私钥ansible控制端主机,并在ansible.cfg配置文件中使用private_key_file参数来指定私钥的具体位置,如下示例;
# 创建存储密钥对的路径
[cce@doorta ~]# mkdir /etc/ansible/secret
# 创建密钥对
[cce@doorta ~]# ssh-keygen -m PEM -t rsa -b 4096 -C "mail0426@163.com" -f /etc/ansible/secret/key
[cce@doorta ~]# ls /etc/ansible/secret 
key     key.pub
# 在ansible中指定私钥路径,并配置远程用户
[cce@doorta ~]# egrep "(private_key_file|remote_user)" /etc/ansible/ansible.cfg
remote_user = root
private_key_file = /etc/ansible/secret/key
# 分发公钥文件到远端主机
[cce@doorta ~]# ansible all -m copy -a 'src=/etc/ansible/secret/key.pub dest=/root/.ssh/authorized_keys mode=600' -u root -k
# 测试免密连接
[cce@doorta ~]# ansible all -m shell -a 'hostname' -o
172.16.1.1 | CHANGED | rc=0 | (stdout) node1.cce.com
172.16.1.2 | CHANGED | rc=0 | (stdout) node2.cce.com

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注