一、基本部署
安装Ansible
# yum -y install epel-release # yum list all *ansible* # yum info ansible # yum -y install ansible
Ansible配置文件
/etc/ansible/ansible.cfg /etc/ansible/hosts /usr/bin/ansible-doc /usr/bin/ansible-playbook |
主配置文件 Inventory 帮助文件 指定运行任务文件 |
定义Inventory
# cd /etc/ansible/ # cp hosts{,.bak} # > hosts
# cat hosts [webserver] 127.0.0.1 192.168.10.149
[dbserver] 192.168.10.113 |
使用秘钥方式连接
# ssh-keygen -t rsa # ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.10.149 # ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.10.113 # ssh-copy-id -i /root/.ssh/id_rsa.pub root@127.0.0.1 |
使用帮助
# ansible-doc -l # ansible-doc -s MODULE_NAME |
列出ansible所有的模块 查看指定模块具体适用 |
Ansible命令应用基础
语法:ansible <host-pattern> [-f forks] [-m module_name] [-a args]
<host-pattern> 这次命令对哪些主机生效的 inventory group name ip all -f forks 一次处理多少个主机 -m module_name 要使用的模块 -a args 模块特有的参数
# ansible 192.168.10.113 -m command -a 'date' # ansible webserver -m command -a 'date' # ansible all -m command -a 'date' |
command 命令模块(默认模块)用于在远程主机执行命令;不能使用变量,管道等 # ansible all -a 'date' cron 计划任务 |
|
month 指定月份 minute 指定分钟 job 指定任务 day 表示那一天 hour 指定小时 weekday 表示周几 state 表示是添加还是删除 |
|
present:安装 absent:移除 |
|
# ansible webserver -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"' #不写默认都是*,每个任务都必须有一个名字 # ansible webserver -a 'crontab -l' # ansible webserver -m cron -a 'minute="*/10" job="/bin/echo hello" name="test |
|
cron job" state=absent' #移除任务 user 用户账号管理 |
|
name uid state group groups home |
用户名 uid 状态 属于哪个组 附加组 家目录 |
createhome 是否创建家目录 comment 注释信息 system 是否是系统用户 |
|
# ansible all -m user -a 'name="user1"' # ansible all -m user -a 'name="user1" state=absent' group 组管理 |
|
gid name state system |
gid 组名 状态 是否是系统组 |
# ansible webserver -m group -a 'name=mysql gid=306 system=yes' |
# ansible webserver -m user -a 'name=mysql uid=306 system=yes group=mysql' copy 复制文件(复制本地文件到远程主机的指定位置) src 定义本地源文件路径 dest 定义远程目录文件路径(绝对路径) owner 属主 group 属组 mode 权限 content 取代src=,表示直接用此处的信息生成为文件内容 # yum -y install libselinux-python # ansible all -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=640' # ansible all -m copy -a 'content="hello ansible Hi ansible" dest=/tmp/test.ansible' file 设置文件的属性 path|dest|name 对那个文件做设定
创建文件的符号链接: src: 指定源文件 path: 指明符号链接文件路径 # ansible all -m file -a 'owner=mysql group=mysql mode=644 path=/tmp/fstab.ansible' # ansible all -m file -a 'path=/tmp/fstab.link src=/tmp/fstab.ansible state=link' ping 测试指定主机是否能连接 # ansible all -m ping service 管理服务运行状态 enabled 是否开机自动启动 name 指定服务名 state 指定服务状态 |
||
started stoped restarted |
启动服务 停止服务 重启服务 |
|
arguments 服务的参数 # ansible webserver -m service -a 'enabled=true name=httpd state=started' shell 在远程主机上运行命令 尤其是用到管道变量等功能的复杂命令 # ansible all -m shell -a 'echo devopsman | passwd --stdin user1' script 将本地脚本复制到远程主机并运行之 # ansible all -m script -a '/tmp/test.sh' yum 安装程序包 |
||
name state |
程序包名称(不指定版本就安装最新的版本latest) present,latest表示安装,absent表示卸载 |
|
# ansible webserver -m yum -a 'name=httpd' # ansible all -m yum -a 'name=ntpdate' #默认就是安装 # ansible all -m yum -a 'name=ntpdate state=absent' setup 收集远程主机的facts 每个被管理节点在接受并运行管理命令之前,会将自己主机相关信息,如操作系统版本,IP地址等报告给远 程的ansible主机 # ansible all -m setup |
组成结构:
inventory modules |
#以下操作应用的主机 #调用哪些模块做什么样的操作 |
||||||||||
ad hoc commands #在这些主机上运行哪些命令 playbooks |
|||||||||||
|
4.1 YAML介绍
YAML是一个可读性高的用来表达资料序列的格式。 YAML参考了其它多种语言,包括: XML、C语言、 Python、 Perl以及电子邮件格式RFC2822等。 ClarkEvans在2001年首次发表了这种语言,另外Ingy dot Net与Oren Ben- Kiki也是这语言的共同设计者。
YAML Ain't Markup Language,即YAML不是XML,不过,在开发这种语言时, YAML的意思其实 是: "Yet Another Markup Language"(仍是一种标记语言),其特性:
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
更多的内容及规范参见[1]
4.2 YAML语法
YAML的语法和其他高阶语言类似,并且可以简单表达清单、散列表、标量等数据结构,其结构 (structure)通过空格来展示,序列(sequence)里的项用"-"来表示, Map里面的键值对用":"分割,下面是 一个示例。
name: john smith age: 41 gender: male spouse: name:jane smith age:37 gender: female children: - name:jimmy smith age:17 gender: male - name:jenny smith age: 13 gender: female |
YAML文件扩展名通常为.yaml,如example.yaml
4.2.1 list
列表的所有元素均使用"-"打头,例如:
# A list of testy fruits - Apple - Orange - Strawberry - Mango |
4.2.2 dictionary
字典通过key与value进行标识,例如:
--- # An employee record name: Example Developer job: Developer skill: Elite |
也可以将key:value放置于{}中进行表示,例如:
--- #An exmloyee record {name: Example Developer, job: Developer, skill: Elite} |
5.1 变量
5.1.1 变量命名
变量名仅能由字母、数字和下划线组成,且只能以字母开头。
5.1.2 facts
facts是由正在通信的远程目标主机发回的信息,这些信息被保存在ansible变量中。要获取指定的远程主 机所支持的所有facts,可使用如下命令进行:
#ansible hostname -m setup
5.1.3 register
把任务的输出定义为变量,然后用于其他任务,实例如下:
tasks: - shell: /usr/bin/foo register: foo_result ignore_errors: True |
5.1.4 通过命令行传递变量
在运行playbook的时候也可以传递一些变量供playbook使用,示例如下:
#ansible-playbook test.yml --extra-vars "hosts=www user=devopsman"
5.1.5 通过roles传递变量
当给一个主机应用角色的时候可以传递变量,然后在角色内使用这些变量,示例如下:
- hosts: webserver roles: - common - {role: foo_app_instance, dir: '/web/htdocs/a.com', port: 8080} |
5.2 Inventory
ansible的主要功用在于批量主机操作,为了便捷的使用其中的部分主机,可以在inventory file中将其分 组命名,默认的inventory file为/etc/ansible/hosts
inventory file可以有多个,且也可以通过Dynamic Inventory来动态生成。
5.2.1 inventory文件格式
inventory文件遵循INI文件风格,中括号中的字符为组名。可以将同一个主机同时归并到多个不同的组 中;此外,当如若目标主机使用非默认的SSH端口,还可以在主机名称之后使用冒号加端口号来表明。
ntp.devopsman.cn
[webserver] www1.devopsman.cn:2222 www2.devopsman.cn
[dbserver] db1.devopsman.cn db2.devopsman.cn db3.devopsman.cn
如果主机名遵循相似的命名模式,还可使用列表的方式标识个主机,例如: [webserver] www[01:50].example.com
[databases] db-[a:f].example.com |
5.2.2 主机变量
可以在inventory中定义主机时为其添加主机变量以便于在playbook中使用,例如:
[webserver] www1.devopsman.cn www2.devopsman.cn |
http_port=80 maxRequestsPerChild=808 http_port=8080 maxRequestsPerChild=909 |
5.2.3 组变量
组变量是指赋予给指定组内所有主机上的在playbook中可用的变量。例如:
[webserver] www1.devopsman.cn www2.devopsman.cn
[webserver:vars] ntp_server=ntp.devopsman.cn nfs_server=nfs.devopsman.cn |
5.2.4 组嵌套
inventory中,组还可以包含其它的组,并且也可以向组中的主机指定变量。不过,这些变量只能在 ansible-playbook中使用,而ansible不支持。例如:
[apache] httpd1.devopsman.cn httpd2.devopsman.cn
[nginx] ngx1.devopsman.cn ngx2.devopsman.cn |
|
[webserver:children] apache nginx |
#固定格式 |
[webserver:vars] ntp_server=ntp.devopsman.cn |
5.2.5 inventory参数
ansible基于ssh连接inventory中指定的远程主机时,还可以通过参数指定其交互方式,这些参数如下所 示:
ansible_ssh_host ansible_ssh_port ansible_ssh_user ansible_ssh_pass ansible_sudo_pass ansible_connection ansible_ssh_private_key_file ansible_shell_type ansible_python_interpreter |
5.3 条件测试
如果需要根据变量、 facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试。
5.3.1 when语句
在task后添加when字句即可使用条件测试; when语句支持jinja2表达式语句,例如:
tasks: - name: 'shutdown debian flavored system" command: /sbin/shutdown -h now when: ansible_os_family == "Debian" |
when语句中还可以使用jinja2的大多"filter",例如果忽略此前某语句的错误并基于其结果(failed或
success)运行后面指定的语句,可使用类似如下形式;
tasks: - command:/bin/false register: result ignore_errors: True - command: /bin/something when: result|failed - command: /bin/something_else when: result|success - command: /bin/still/something_else when: result|skipped |
此外, when语句中还可以使用facts或playbook中定义的变量
# cat cond.yml - hosts: all remote_user: root vars: - username: user10 tasks: - name: create {{ username }} user user: name={{ username }} when: ansible_fqdn == "node1.exercise.com" |