Ansible

ansible是一种自动化运维工具,基于paramiko开发的,并且基于模块化工作,Ansible是一种集成IT系统的配置管理、应用部署、执行特定任务的开源平台,它是基于python语言,由Paramiko和PyYAML两个关键模块构建。集合了众多运维工具的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能.ansible是基于模块工作的,本身没有批量部署的能力.真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架.ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的.

ansible程序目录结构

  • 配置文件: /etc/ansible/
  • 执行文件目录: /usr/bin/
  • lib依赖库: /usr/lib/python2.7/site-packages/ansible/
  • help文件: /usr/lib/python2.7/site-packages/ansible

安装

Ansible可以运行在任何机器上,但是对管理机有一定要求。管理机应安装Python 2(2.7)或Python 3(3.5或更高版本),另外,管理机不支持Windows控制节点。我们可以使用Linux发行版包管理器、源码安装或者Python包管理器(PIP)来安装Ansible。

redhat系

sudo yum install ansible 或者dnf install ansible

ansible 批量安装 fluentbit ansible批量创建目录_运维


ubuntu

sudo apt update

sudo apt install software-properties-common

sudo apt-add-repository --yes --update ppa:ansible/ansible

sudo apt install ansible

通过Pip安装

pip install --user ansible

或者全局性安装

sudo pip install ansible

源码安装

git clone github.com/ansible/ansible.git

cd ./ansible

source ./hacking/env-setup

安装成功后,可以使用下面命令检查Ansible的安装版本:

ansible –version

ansible 2.9.1

config file = /etc/ansible/ansible.cfg

configured module search path = [u'/home/xx/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']

ansible python module location = /usr/lib/python2.7/site-packages/ansible

executable location = /usr/bin/ansible

python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

帐号规划

假设我们有四台客户机(node1,node2,node3和node4)和管理机(manage)。为了方便,我们创建一个ansible用户帐户,将该ansible用户添加到wheel组,然后配置SSH身份验证。在配置新用户帐户时,请在所有节点上创建该帐户(注意可以使用ansible批量创建):

sudo useradd ansible

然后将ansible用户添加到wheel组:

sudo usermod -aG wheel ansible

为用户设置密码:

sudo passwd ansible

接下来,使用visudo配置/etc/sudoers文件,赋予ansible用户使用sudo执行特权命令:

%wheel ALL=(ALL) NOPASSWD: ALL

配置证书登陆

在所有客户机和管理上创建新的ansible用户之后,我们在管理机(ansible用户)生成SSH密钥,然后将SSH公钥复制到所有客户机。

sudo su - ansible

ssh-keygen

ansible 批量安装 fluentbit ansible批量创建目录_运维_02


现在,将SSH公钥复制到所有客户机,这使管理机ansible用户无需输入密码即可登录客户机:

ssh-copy-id ansible@node1

ansible 批量安装 fluentbit ansible批量创建目录_运维_03


第一次使用,完成以后,就可以直接用证书登陆了。

Ansible配置

默认的配置文件位于/etc/ansible/ansible.cfg下。可以使用此配置文件来修改绝Ansible大多数设置,一般无需额外多配置,默认配置应能满足大多数使用情况。关于Ansible配置文件,其执行程序会按照一定顺序搜索配置:

Ansible按照以下顺序搜索配置文件,优先配置优先使用,而忽略其余配置文件:

$ANSIBLE_CONFIG环境变量。

任务当前目录下的:ansible.cfg(如果在当前目录中)。

当前用户下的ansible.cfg:~/.ansible.cfg

默认配置文件:/etc/ansible/ansible.cfg。

默认清单配置文件位于/etc/ansible/hosts中,但是通过ansible.cfg配置文件中修改此位置。也可以通过-i自定义hosts清单。

为了安全起见,虫虫建议你,不要直接在/etc/ansible/host配置清单,尤其是有用户认账等信息时候。对于长期不执行ansible可以将host文件加密锁定,防止信息泄露,引起安全事故。

ansible任务执行模式

Ansible任务执行模式分为以下两种:

  • ad-hoc模式(点对点模块)

使用单个模块,支持批量执行单条命令,相当与在bash中执行一句shell命令

  • playbook模式(剧本模式)

ansible主要的管理方式,通过多个task的集合完成一类功能,可以理解为多个ad-hoc的配置文件

基于ad-hoc模式运行

ansible通过ssh实现配置管理、应用部署、任务执行等功能,因此,需要事先配置ansible端能基于密钥认证的方式联系各被管理节点。

ansible命令使用语法:

ansible <host-pattern> [-f forks] [-m module_name] [-a args]
    -m module:默认为command

例如:

1、定义好inventory后可以调用ping模块来检测网络是否可达

# ansible all -m ping
192.168.57.22 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
192.168.57.11 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

2、使用command模块远程执行命令:

# 如果/etc/passwd文件存在就执行grep命令
# ansible all -m command -a 'removes=/etc/passwd grep root /etc/passwd' 
192.168.57.22 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

192.168.57.11 | SUCCESS | rc=0 >>
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin

可以通过ansible-doc -l列出所有可用的module,常用的module有:

ping # 主机连通性测试
command # 在远程主机上执行命令,不支持管道
shell # 在远程主机上调用shell解析器,支持管道命令个
copy # 用于将文件复制到远程主机,支持设定内容和修改权限.
file # 创建文件,创建连接文件,删除文件等
fetch # 从远程复制文件到本地
cron # 管理cron计划任务
yum # 用于模块的安装
service # 管理服务
user # 管理用户账号
group # 用户组管理
script # 将本地的脚本在远端服务器运行
setup # 该模块主要用于收集信息,是通过调用facts组件来实现的,以变量形式存储主机上的信息

ansible -s <module-name>可以查看指定module的用法,或者参看官方文档

# ansible-doc -s service
- name: Manage services
  service:
      arguments:             # Additional arguments provided on the command line
      enabled:               # Whether the service should start on boot. *At least one of state and enabled are required.*
      name:                  # (required) Name of the service.
      pattern:               # If the service does not respond to the status command, name a substring to look for as would be
                               found in the output of the `ps' command as a stand-in for a
                               status result.  If the string is found, the service will be
                               assumed to be running.
      runlevel:              # For OpenRC init scripts (ex: Gentoo) only.  The runlevel that this service belongs to.
      sleep:                 # If the service is being `restarted' then sleep this many seconds between the stop and start
                               command. This helps to workaround badly behaving init scripts
                               that exit immediately after signaling a process to stop.
      state:                 # `started'/`stopped' are idempotent actions that will not run commands unless necessary.
                               `restarted' will always bounce the service.  `reloaded' will
                               always reload. *At least one of state and enabled are required.*
                               Note that reloaded will start the service if it is not already
                               started, even if your chosen init system wouldn't normally.
      use:                   # The service module actually uses system specific modules, normally through auto detection, this
                               setting can force a specific module. Normally it uses the value
                               of the 'ansible_service_mgr' fact and falls back to the old
                               'service' module when none matching is found.

基于playbook执行

playbook是由一个或多个“play”组成的列表。play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们联同起来按事先编排的机制同唱一台大戏。

下面是一个简单示例:

- hosts: master
  user: root
  vars:
    - motd_warning: 'WARNING: Use by master ONLY'
  tasks:
    - name: setup a MOTD
      copy: dest=/etc/motd content="{{ motd_warning }}"
      notify: say something
  handlers:
    - name: say something
      command: echo "copy OK"

playbooks的组成部分

  • Target section: 定义要运行playbook的远程主机组

hosts: hosts用于指定要执行指定任务的主机,其可以是一个或多个由冒号分隔主机组
user: 指定远程主机上的执行任务的用户,还可以指定sudo用户等

  • Variable section: 定义playbook运行时使用的变量
  • Task section: 定义要在远程主机上运行的任务列表

name: 每个任务都有name,建议描述任务执行步骤,未通过name会用执行结果作为name
‘module:options’: 调用的module和传入的参数args

  • Handler section: 定义task完成后需要调用的任务

notify: 在Task Section在每个play的最后触发,调用在hendler中定义的操作

handler: 也是task的列表

执行过程:

[root@localhost ansible]# ansible-playbook set_motd.yaml 

PLAY [master] ******************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.57.11]

TASK [setup a MOTD] ************************************************************************************************************
changed: [192.168.57.11]

RUNNING HANDLER [say something] ************************************************************************************************
changed: [192.168.57.11]

PLAY RECAP *********************************************************************************************************************
192.168.57.11              : ok=3    changed=2    unreachable=0    failed=0   

# cat /etc/motd 
WARNING: Use by master ONLY

playbook安装配置apache实战

1、编写playbook:install_httpd.yaml

---
- hosts: slave
  vars:
    http_port: 8080
  user: root
  tasks:
  - name: ensure apache is at the latest version
    yum: name=httpd state=latest
  - name: write the apache config file
    template:
      src: template/httpd.j2
      dest: /etc/httpd/conf/httpd.conf
    notify:
    - restart apache
  - name: ensure apache is running
    service: name=httpd state=started
  handlers:
    - name: restart apache
      service:
        name: httpd
        state: restarted

2、生成apache配置文件jinja2模板,将服务端口配置为变量Listen {{ http_port }}
3、执行playbook并检查远端服务端口

[root@localhost ansible]# ansible-playbook install_httpd.yaml 

PLAY [slave] *******************************************************************************************************************

TASK [Gathering Facts] *********************************************************************************************************
ok: [192.168.57.22]

TASK [ensure apache is at the latest version] **********************************************************************************
changed: [192.168.57.22]

TASK [write the apache config file] ********************************************************************************************
changed: [192.168.57.22]

TASK [ensure apache is running] ************************************************************************************************
changed: [192.168.57.22]

RUNNING HANDLER [restart apache] ***********************************************************************************************
changed: [192.168.57.22]

PLAY RECAP *********************************************************************************************************************
192.168.57.22              : ok=5    changed=4    unreachable=0    failed=0   

[root@localhost ansible]# ansible slave -m shell -a 'ss -lntp | grep 8080'
192.168.57.22 | SUCCESS | rc=0 >>
LISTEN     0      128         :::8080                    :::*                   users:(("httpd",pid=29187,fd=4),("httpd",pid=29185,fd=4),("httpd",pid=29184,fd=4),("httpd",pid=29183,fd=4),("httpd",pid=29182,fd=4),("httpd",pid=29181,fd=4))