安装好ansible后,检查安装是否成功:
ansible --version
配置文件
Ansible通过以下顺序应用配置文件:
- ANSIBLE_CONFIG (environment variable if set)
- ansible.cfg (in the current directory)
- ~/.ansible.cfg (in the home directory)
- /etc/ansible/ansible.cfg
另外,可以通过ansible-config参看配置值以及配置具体来自于哪个文件。
比如禁用ssh的host checking,可以在当前目录创建ansible.cfg文件,内容如下:
[defaults]
host_key_checking = False
inventory文件
inventory文件是一个INI格式文件,里面包含了ansible可能会连接的所有机器,但是ansible可以选择性的针对某些机器执行指令。
默认情况下,ansible的会将/etc/ansible/hosts文件作为inventory文件,通常情况下我们都会通过ansible -i inventory ...
来指定自己定义的inventory文件。
inventory文件格式如下:
[load_balancer]
nginx ansible_host=192.168.4.2 ansible_port=22 ansible_user=vagrant
[server]
server-node1 ansible_host=192.168.4.3 ansible_port=22 ansible_user=vagrant
server-node2 ansible_host=192.168.4.4 ansible_port=22 ansible_user=vagrant
其中load_balanceer
和server
表示分组,nginx
和server-node1
表示某台主机,ansible可以针对组执行指令,也可以针对某台主机执行指令,all
表示所有主机。
inventory文件中常见的参数有:
- ansible_host:host域名或者IP地址
- ansible_port:ssh到远程机器的端口
- ansible_user: ssh到远程机器的默认用户名,会被playbook中的remote_user替代
- ansible_ssh_private_key_file:ssh到远程机器时所使用的密钥
- ansible_become:是否已另一个用户执行ansible,默认的用户为root
在inventory中定义基于host的变量:
host1 http_port=80 maxRequestsPerChild=808
定义基于group的变量:
[atlanta:vars]
ntp_server=ntp.atlanta.example.com
一种好的实践是不要再inventory文件中存储变量,而是存于host_vars和group_vars文件夹下,ansible会自动应用文件夹中的变量。存储变量的文件名遵循以下格式:
host_vars/host-name
group_vars/group-name
其中host-name和group-name为inventory文件中主机的名字或者group的名字,文件名可以以yml/yaml为后缀,比如:
host_vars/host1
group_vars/atlanta.yaml
host_vars和group_vars可以与inventory或者playbook文件存于相同的文件夹下,如果同时inventory和playbook所在文件夹同时有host_vars/group_vars,那么playbook的会覆盖inventory的。
变量可以存在于多个地方,但是在ansible运行时,所有地方的变量将针对于某个host机器进行合并。
在合并时,基于group和host的变量通过以下顺序进行覆盖,后面的覆盖前面的:
- all group (because it is the ‘parent’ of all other groups)
- parent group
- child group
- host
ansible命令
ansible
命令用于在远程机器上执行单个任务。
要执行ansible命令,需要做3件事情:
- 创建inventory文件
- 创建ssh key,并上传public key到远程机器上
- 调用ansible命令,指定inventory中需要执行模块的机器
检查所有机器是否能ping通:
ansible all -m ping
用ansible在远程机器上执行whoami
命令:
ansible -i inventory.ini node1 -m command -a "whoami" -u aUser --private-key key/ansible_id_rsa -k -b --become-user user0 --become-method sudo -K
-
-i inventory.ini
表示使用当前路径下的inventory.ini作为inventory文件 -
node1
表示在node1这台机器上执行ansible指令,这里node1需要在inventory.ini中存在 -
-m command
表示在node1机器上执行command模块,默认即为command模块 -
-a "whoami"
模块参数,与-m
配合使用 -
-u aUser
表示ansible通过aUser
用户登录远程机器,默认使用本机当前用户 -
--private-key key/ansible_id_rsa
表示在用aUser登录是使用指定的密钥文件 -
-k
表示在用aUser登录时提示输入aUser的密码,通常的做法是-k
和--private-key
任选其一,但是如果同时使用了两者,那么-k
生效。 -
-b
表示登录之后变成另外一个用户执行ansible指令 -
--become-user user0
表示在-b
的情况下要变成哪个用户,默认为root用户 -
--become-method sudo
表示通过什么方式变为那个用户,默认为sudo,也可以指定su等 -
-K
表示需要变成用户时需要提示输入密码,对于become-method=sudo来说,如果user0已经有免密执行sudo的权限,那么便没有必要配置-K
,否则反而会让你输入密码。
基于以上anbile命令行参数,通常情况下,在运行ansible时我们不希望有人工参与(比如输入密码等),因此我们可以创建如下默认环境:
- 本地目录下有个inventory.ini文件
- 本地有个key/id_rsa
- 通过key完成ansible到远程机器的登录
- 登录用户具有免密执行sudo命令的权限
有了这些,我们便可以简化ansible命令:
ansible -i inventory.ini node1 -a "whoami" -u aUser --private-key key/ansible_id_rsa -b
以上命令在远程即上以root用户执行whoami命令。
ansible-playbook命令
执行playbook的格式为:
ansible-playbook [options] playbook.yml [playbook2 ...]
ansible-playbook
常用命令行参数:
- -b:启用become
- -become_user:指定运行指令的用户,默认为root
- -u:指定ssh登录用户
- --private-key:指定登录用户的密钥文件
- -i:指定inentory文件
- --vault-password-file:指定vault的密码文件
- --list-hosts:输出命中的host列表
变量处理
可以在多个地方声明ansible所使用的变量,优先级从高到低:
- 运行ansible-playbook命令时的命令行参数
- playbook文件
- inventory文件
在playbook中设置变量:
---
- hosts: all
remote_user: root
vars:
favcolor: blue
vars_files:
- /vars/external_vars.yml
tasks:
- name: this is just a placeholder
command: /bin/echo foo
更详细变量优先级请参考这里。
role
创建一个role:
ansible-galaxy init my-role
这里写的很详细。
vault
ansible vault主要用于加密一些yaml格式的变量文件,比如host_vars和group_vars文件夹下的文件等,而不会加密Role中的文件或者模板。
创建加密文件:
ansible-vault create foo.yml
此时,ansible会提示设置密码。
编辑加密文件:
ansible-vault edit foo.yml
加密普通文件:
ansible-vault encrypt foo.yml
解密文件:
ansible-vault decrypt foo.yml
查看加密文件内容:
ansible-vault view foo.yml
最佳实践
ansible工程推荐目录结构:
production # inventory file for production servers
staging # inventory file for staging environment
group_vars/
group1 # here we assign variables to particular groups
group2 # ""
host_vars/
hostname1 # if systems need specific variables, put them here
hostname2 # ""
library/ # if any custom modules, put them here (optional)
module_utils/ # if any custom module_utils to support modules, put them here (optional)
filter_plugins/ # if any custom filter plugins, put them here (optional)
site.yml # master playbook
webservers.yml # playbook for webserver tier
dbservers.yml # playbook for dbserver tier
roles/
common/ # this hierarchy represents a "role"
tasks/ #
main.yml # <-- tasks file can include smaller files if warranted
handlers/ #
main.yml # <-- handlers file
templates/ # <-- files for use with the template resource
ntp.conf.j2 # <------- templates end in .j2
files/ #
bar.txt # <-- files for use with the copy resource
foo.sh # <-- script files for use with the script resource
vars/ #
main.yml # <-- variables associated with this role
defaults/ #
main.yml # <-- default lower priority variables for this role
meta/ #
main.yml # <-- role dependencies
library/ # roles can also include custom modules
module_utils/ # roles can also include custom module_utils
lookup_plugins/ # or other types of plugins, like lookup in this case
webtier/ # same kind of structure as "common" was above, done for the webtier role
monitoring/ # ""
fooapp/
更多最佳实践,请参考这里。