ansible自动化运维
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。- 远程主机可以通过ip, 域名以及别名的方式指定。仅指定域名或ip, 默认使用端口号22。 如果使用别名,可以将别名写前面,后面分别指定端口号和host。例如:
# 定义域名 www.example.com # 定义IP 192.168.222.22 # 定义别名 Monitor ansible_ssh_port=12345 ansible_ssh_host=192.123.123.11
- 另外主机还可以使用正则表达式来指定,一次性指定多个。例如:
www[01:99].example.com db-[a-z].example.com
- 可以对主机进行分组, 例如:
[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.