ansible自动化运维

86113651 2019-06-28

Ansible自动化运维

ansible简介

Ansible是一个IT自动化工具。它可以配置系统、部署软件、以及编排更高级的IT任务,例如持续部署或零宕机滚动升级。

Ansible的目标是简单易用。它还很注重安全和可靠性,具有最小化的移动部件,使用OpenSSH传输(使用其他传输和拉取模式做替代品),并且语言是围绕人们可审计设计的,即便这些人对程序不太熟悉。

我们相信简单性和所有环境规模有关,所以我们为各种类型的繁忙用户进行设计: 包括开发人员、发布工程师、IT管理员、以及中间的所有人。Ansible适用于管理所有环境,从具有少量实例的小型设置到具有数千实例的企业环境。

Ansible用一种较少代理的方式管理机器。从来没有如何升级远程守护进程的问题,或因为守护进程不能卸载而不能管理系统的问题。因为OpenSSH是最受同行评议的开源组件之一,极大的降低了安全性的暴露。Ansible是无中心的,它依赖于你现有操作系统凭证来控制远程机器的。 如果需要,ansible可以很容易使用Kerberos(是一种计算机网络授权协议,用来在非安全网络中,对个人通信以安全的手段进行身份认证。)、LDAP、以及其他中心化授权管理系统来进行连接。

ansible安装

这里只介绍一种安装方式, 使用pip install ansible。其他更多安装方法可以参照链接: https://docs.ansible.com/ansi...

ansible配置

我们采用pip install的方式进行安装,因此默认是没有创建相关配置文件的。下面介绍如何配置ansible。

我使用的是macbook, 因此主要介绍macbook下面的配置。

  • 在用户home目录下面创建.ansible目录。
  • 在上面的.ansible目录下面创建hosts和ansible.cfg文件。
  • 并将上述文件进行软链到/etc/ansible。
# 1. 创建目录
mkdir ~/.ansible
mkdir /etc/ansible

# 2. 创建hosts文件
touch ~/.ansible/hosts

# 3. 创建ansible配置文件ansible.cfg
touch ~/.ansible/ansible.cfg

# 4. 建立软链
ln -s ~/.ansible/hosts /etc/ansible/hosts
ls -s ~/.ansible/ansible.cfg /etc/ansible/ansible.cfg

上面是创建目录、配置文件的命令操作,注意目录和文件权限问题。

以下是ansible配置文件内容:

[defaults]
inventory      = /etc/ansible/hosts
library        = /usr/share/my_modules/
remote_tmp     = $HOME/.ansible/tmp
pattern        = *
forks          = 5
poll_interval  = 15
sudo_user      = root                     #执行sudo的默认用户
ask_sudo_pass = False                     #在执行sudo之前是否询问sudo密码
ask_pass      = False                     #执行命令时是否询问密码
deprecation_warnings = False
host_key_checking = False
transport      = smart
remote_port    = 22
module_lang    = C
gathering = implicit

# 关闭第一次使用ansible连接客户端是输入命令提示
host_key_checking = False

remote_user = root
# 指定私钥文件路径
private_key_file = ~/.ssh/id_rsa

#添加ansible日志
log_path = /var/log/ansible/ansible.log

配置选项及含义解释

ansible的所有参数都可以在ansible-playbook中或使用命令行标志来覆盖。ansible会读取配置文件的顺序如下(按查找的优先顺序列举出来的):

  • ANSIBLE_CONFIG。
  • 当前目录的ansible.cfg文件。
  • Home目录的.ansible.cfg文件。
  • /etc/ansible/ansible.cfg文件。

对于我这里的来说,首先找到/etc/ansible/ansible.cfg文件,因为我建立了软链。

下面介绍基本参数及含义:

  • inventory: 财产目录,一般指向你ansible使用的hosts文件的绝对路径。我这里可以设置为/etc/ansible/hosts, 因为我建立了软链。
  • library: 指向共享模块所在目录。
  • module_utils: 工具模块目录地址。
  • remote_tmp: 远程tmp目录地址。
  • local_tmp: 本地ansible tmp目录地址。
  • plugin_filters_cfg: 插件过滤配置文件。可指定一个yml文件。
  • forks: -。
  • poll_interval: 拉取时间间隔。
  • sudo_user: 本地sudo过去的用户名,一般都是root。
  • ask_sudo_pass: 是否询问sudo密码。
  • ask_pass: 是否询问密码。
  • transport: 传输方式, 默认smart。
  • remote_port: 远程机器ssh的端口号。
  • module_lang: 模块语言,默认C。
  • module_set_locale: -。
  • gathering: 使用它的话,默认会收集事实,包括远程机器的信息。

    • smart: 默认会收集信息,但是如果已经收集了的话就不会再收集了。
    • implicit: 默认会收集信息,可以使用gather_facts为False来关闭。
    • explicit: 默认不收集信息,必须设置gather_facts为Ture来开启。
  • roles_path: 查找角色的目录,可以包含多个,使用分号分隔开来。
  • remote_user: 设置ssh远程机器的默认用户。
  • log_path: 记录ansible的日志文件地址。
  • private_key_file: 指定本地私匙文件的位置。即使用ssh-keygen命令产生的私匙文件的位置。因为要ssh到远程机器需要使用私匙来配合ssh-copy-id到远程机器的公匙才能免密登录上去。

还有其他更多配置参数可以参照后面的配置文件样本来查看。

SSH秘匙认证

要实现自动化运维,需要远程机器对本地机器进行认证。通过ssh-keygen产生公私匙,并通过ssh-copy-id命令向远程机器复制对本地机器的信任。

ssh-copy-id会将本地公匙复制到远程机器的~/.ssh/authorized_keys文件中。 这样本地机器ssh的时候可以使用本地私匙进行远程机器访问。

ssh-keygen -t rsa
ssh-copy-id root@远程机器IP

添加被管理的远程机器列表

在~/.ansible/hosts文件中添加如下内容:

# vim /etc/ansible/hosts

[Client]
angent_host_ip_1
angent_host_ip_2

hosts主机文件详解

注意这里的hosts非机器上的/etc/hosts。
  1. 远程主机可以通过ip, 域名以及别名的方式指定。仅指定域名或ip, 默认使用端口号22。 如果使用别名,可以将别名写前面,后面分别指定端口号和host。例如:
# 定义域名
www.example.com

# 定义IP
192.168.222.22

# 定义别名
Monitor ansible_ssh_port=12345 ansible_ssh_host=192.123.123.11
  1. 另外主机还可以使用正则表达式来指定,一次性指定多个。例如:
www[01:99].example.com

db-[a-z].example.com
  1. 可以对主机进行分组, 例如:
[webservers]
191.111.111.11
111.121.121.11

[dbservers]
112.232.12.12
121.121.121.11

测试ansible

使用下面命令进行ansible测试:

$ ansible Client -m ping

132.11.36.122 | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}

显示如上类似内容表示配置ansible成功了。

常见错误及解决方案

Failed to connect to the host via ssh

出现这中错误的原因,一般是ssh到远程机器失败。 原因大致上可以有如下几种:

  • 没有生成公私匙,或者没有将本地机器的公匙复制到远程机器上。可以使用ssh-keygen和ssh-copy-id来解决。
  • 没有配置ssh登录远程机器的用户名或者设置本地私匙文件的位置: 可以通过设置remote_user和private_key_file来指定。当然如果你的远程机器都是统一使用root来ssh, 可以直接配置到ansible.cfg文件中。如果远程机器所使用的用户不同,可以直接在hosts文件中分别针对不同的远程主机进行设置。

分别针对不同主机进行设置

下面分别为具体远程机器设置ssh的用户名、密码以及端口号。

# ~/.ansible/hosts
192.168.128.83  ansible_port=22  ansible_user=root  ansible_ssh_pass=root

具体在inventory中可以使用的参数列表如下:

  • ansible_connection: 到远程主机的连接类型。这个只可以是ansible连接插件的名字。SSH协议类型有smart, ssh,或paramiko。默认为smart。还支持非SSH的类型。
  • ansible_host: 远程主机地址。
  • ansible_port: 远程主机端口号。
  • ansible_user: 远程主机用户名。
  • ansible_ssh_pass: 远程主机的密码。
  • ansible_ssh_private_key_file: 本机私匙文件。

更多参数介绍参照链接: https://docs.ansible.com/ansi...

ansible常用模块

ansible支持很多模块,支持的模块分类大致如下:

  • 云模块: 例如amazon, atomic, azure, Centurylink, Cloudscale, Cloudstack, Digital_Ocean, Dimensiondata, Docker, Google, Heroku, Linode, Lxc, Lxd, Memset, Misc, Oneandone, Opennebula, Openstack, Ovh, Ovirt等等很多云服务商的支持模块。
  • 集群模块: 例如对K8S, Openshift集群支持的模块。
  • 命令模块: 例如在远程机器执行命令(command), expect, psexec, raw, script, shell, telnet等。
  • 加密相关的模块: openssl_certificate, openssl_csr等等。
  • 数据库模块: 例如对influxdb, mongodb, mssql, mysql等数据支持的模块。
  • 文件模块: 例如acl, archive, copy, fetch等支持的模块。

另外还有大量的其他类型的模块,比如消息队列模块、监控模块、网络工具模块、网络模块、通知模块、远程管理模块、源码控制模块、存储模块等等。

更多模块参见: https://docs.ansible.com/ansi...

ansible命令介绍

ansible命令执行的模式如: ansible <host-pattern> [options], 通过指定主机模式和选项参数来执行。

执行远程机器上的命令

例如:

ansible webservers -m command -a "free -m"

232.132.16.22 | SUCCESS | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:            992         101          69           0         821         725
Swap:             0           0           0

上面命令对远程主机组webservers执行free -m命令。

执行远程机器上的shell脚本。

再例如下面的命令执行远程机器上的一个shell脚本:

ansible webservers -m shell -a "/data/servers/bin/restart.sh"

实现主控端到远程机器拷贝文件,类似于scp命令。

以下命令将本地/home/qiao/app下面的东西都拷贝到远程主机组webservers的/tmp目录下面,拷贝过去的文件所属用户和组都为root, 文件权限为0755。

ansible webservers -m copy -a "src=/home/qiao/app/* dest=/tmp owner=root group=root mode=0755

获取远程文件状态信息

我们可以使用stat模块,获取远程文件的atime, ctime, mtime, md5, uid, gid等信息。

ansible test -m stat -a "path=/etc/syctl.conf"

使用远程主机下载文件到本地

ansible还可以使用远程主机进行翻墙下载文件,并传到本地, 而且还支持sha256sum文件校验。这个功能是不是很有用呢? 哈哈哈。

shell > ansible fanqiang -m get_url -a "url=http://www.baidu.com dest=/tmp/index.html mode=0440 force=yes"

远程主机crontab配置

通过ansible可以对远程主机进行crontab配置。

ansible webservers -m cron -a "name='check dirs' hour='5,2' job='ls -lah > /dev/null'"

#效果如下:
#* 5,2 * * * ls -alh > /dev/null

对远程主机分区挂载

ansible Client -m mount -a "name=/mnt/data src=/dev/sd0 fstype=ext4 opts=ro state=present"

远程主机系统服务管理

使用ansible还可以对远程主机系统服务进行管理,例如nginx的重启、停止、启动等操作。

ansible Client -m service -a "name=nginx state=stoped"
ansible Client -m service -a "name=nginx state=restarted"
ansible Client -m service -a "name=nginx state=reloaded"

有点碉堡的感觉。

远程主机用户管理

shell > ansible Client -m user -a "name=wang comment='user wang'"

shell > ansible Client -m user -a "name=wang state=absent remove=yes"    # 添加删除用户

ansible的剧本playbook

playbook是ansible的配置、部署以及编排语言。它们能描述一套你希望远程系统强制执行的策略,或者在IT过程中通用的一组步骤。

详细介绍见参考链接。

第一个事例: 对webservers主机组安装httpd、php并启动httpd

# vim batch-httpd.yml
- hosts: webservers
  remote_user: root
  vars: httpd_port=80
  
  tasks:
  - name: install httpd
    yum: name=http state=present
  - name: install php
    yum: name=php state=present
  - name: start httpd
    service: name=httpd state=started enabled=true
  • hosts: 定义单个主机或组。
  • vars: 定义变量。
  • remote_user: 定义执行命令的远程用户。
  • tasks: 定义执行哪些命令。

第二个实例: 为远程主机添加用户,安装httpd, php,添加多个用户

vim /root/second.yml

- hosts: web1
  remote_user: root
  vars:
    username: bob
    password: 123
    
  tasks:
  - name: add user
    user: name={{ username }} state=present
    when: ansible_os_family == "Debian"
  - name: set password
    shell: echo {{ password }} |passwd --stdin {{ username }}
  - name: install httpd php
    yum: name={{ item }} state=present
    with_items:
      - httpd
      - php
  - name: add two users
    user: name={{ item }} state=present groups={{ item.groups }}
    with_items:
    - { name: 'user1', groups: 'group1'}
    - { name: 'user2', groups: 'group2'}
  • 在playbook中调用变量的方式为{{ variable }}
  • when语句用来条件测试
  • ansible_os_family 是facts中内置的属性信息 ansible_os_family的信息可以使用ansible all -m setup | grep ansible_os_family 查看
  • 在task中调用内置的item变量;在某task后面使用with_items语句来定义元素列表

还有更多实例参见参考链接。

本文仅为个人学习记录使用,如有侵权,敬请告知,我会做调整。

术语

  • 编排: orchestrate.
  • 零宕机: zero downtime.

参考链接

相关推荐