Ansible
ansible的使用前提是确保ssh的秘钥登录
ansible <host-pattern> [options] host-pattern:指定运行组 -v:显示更详细信息 -i PATH:手工指定运行组,默认/etc/ansible/hosts -f NUM:并发线程数,默认5 -m MODE:指定模块 -a 'ARGS':模块参数 -k:认证密码 -K:sudo密码 -u USERNAME:指定运行用户 --list:列出符合条件的主机列表 --limit=:指定主机组中的主机,可以通过:做分隔符,用“”引起来 使用密码登陆:开启配置文件/etc/ansible/ansible.cfg中host_key_checking = False
例:ansible all -m shell -a 'date'
在/etc/ansible/hosts文件中可以定义管控的服务器组
[root@localhost ansible]# cat /etc/ansible/hosts #标准定义 [a] 172.17.148.111:2222 #可以加端口 172.17.148.113:2222 172.17.148.[120:130] #根据范围定义 #主机名定义 [b] www.a.com www.b.com www.[a:z].com #根据范围定义 #未进行秘钥分发的主机可以使用用户名密码 [c] 172.17.148.115 ansible_ssh_user=root ansible_ssh_pass=1 #针对a组的变量,:vars固定写法 [a:vars] ansible_ssh_user=root ansible_ssh_pass=1 #组嵌套,:children固定写法 [aaaa:children] a #这是其他组 b
查看模块帮助:
ansible-doc -l:列出可以使用的模块
ansible-doc -s MODULE_NAME:查看模块帮助
常用模块
0.debug:输出日志模块,常用于调试
msg:输出想要输出的内容
var:json格式输出
verbosity:输出级别,vvv就是3
1.command:命令模块,默认模块,用于在远程主机执行命令。
当shell命令中包含参数的时候需要改用ansible all -m shell -a 'XXXXX'
使用shell模块时一定要加上 ignore_errors: True 忽略错误,防止后面的playbook无法继续执行
[root@localhost ansible]# ansible all -m shell -a date 172.17.148.111 | SUCCESS | rc=0 >> 2018年 08月 08日 星期三 15:27:45 CST 172.17.148.113 | SUCCESS | rc=0 >> 2018年 08月 08日 星期三 15:27:45 CST
2.cron:用于在远程主机上添加定时任务或删除定时任务
job:要执行的任务
name:给这个任务起个名
state:present为添加任务,absent为删除任务
day,hour,minut,month,weekday:指定时间
#新建个每天晚上18点就关机的任务,命名为“everyday poweroff” [root@localhost ansible]# ansible all -m cron -a 'hour="18" job="/usr/sbin/poweroff" name="everyday poweroff" state="present" ' #查看刚刚新建定时任务是否成功 [root@localhost ansible]# ansible all -a "crontab -l" #删除刚刚新建的任务 [root@localhost ansible]# ansible all -m cron -a 'name="everyday poweroff" state="absent"'
3.user:创建用户一类的信息
name:指定用户名
home:设置家目录
shell:设置shell
uid:指定uid
group:指定用户组
groups:指定用户附加组
system:指定为系统用户,yes或no
state:present创建,absent删除
append:当为yes时,groups中的组为追加,no->覆盖
remove:结合state=absent时,remove=yes就是userdel -r
[root@localhost ansible]# ansible all -m user -a 'name=test uid=377 system=yes password="111" state=present'
4.group:创建组一类的信息
name:指定组名
gid:指定gid
system:指定为系统组,yes或no
state:present创建,absent删除
[root@localhost ansible]# ansible all -m group -a 'name=test gid=377 system=yes state=present'
5.copy:复制文件
src:指定本地源文件
dest:指定远程目标文件,绝对路径
content:取代src,表示直接用此处指定的信息生成为目标文件内容
owner:指定属主
mode:指定权限
5.1fetch:拉取文件
src:指定远端文件
dest:指定本地存放路径
6.file:设置文件属性
path:指定文件路径,创建链接
src:指明源文件
state:link创建符号链接,hard创建硬链接,directory创建文件夹
7.ping:连通性测试
[root@localhost ansible]# ansible all -m ping 172.17.148.113 | SUCCESS => { "changed": false, "ping": "pong" } 172.17.148.111 | SUCCESS => { "changed": false, "ping": "pong" }
8.service:管理服务
enabled:true开机自启动,false取消开机启动
name:服务名称
state:状态,started,stopped,restarted,reloaded
9.script:将本地脚本复制到远程主机并运行,-a直接指定脚本就可以,要使用相对路径
10.yum:安装程序包
name:指定包名,可以带上版本号
state:present安装,absent卸载,latest安装最新版
11.setup:收集远程主机的facts,每个被管理节点在接收并运行管理命令之前,会将自己主机相关信息,如操作系统版本、ip地址等报告给远程的ansbile主机。例如nginx启动之前要创建的工作进程个数是根据cpu的信息创建的。这个模块出来的值只能用在playbook,因为直接playbook会先执行setup模块收集信息。
ansible all -m setup --tree /tmp/facts:以各主机名为文件名保存在/tmp/facts目录下
ansible all -m setup -a 'filter="ansible_processor"' 只查看cpu相关信息
12.template:和copy模块差不多,不过template模块会把文件中的{{ 参数 }}转换为对应的值,copy不会
13.archive:压缩归档,默认是tar.gz
path:指定要压缩文件的位置
dest:指定压缩完成后文件名称
exclude_path:指定排除目录
14.unarchive:解压文件
copy:在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
creates:指定一个文件名,当该文件存在时,则解压指令不执行
dest:远程主机上的一个路径,即文件解压的路径,该路径必须存在
group:解压后的目录或文件的属组
list_files:如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
mode:解压后文件的权限
src:源文件位置,如果copy为yes,则需要指定压缩文件的源路径
owner:解压后文件或目录的属主
15.register: 储存变量
16.meta: flush_handlers 在剧本中,定义的handlers会在所有task执行完成之后才被执行,使用meta选项,可以确定在合适的时间执行handlers
playbook剧本
ansible-playbook playbook
-i PATH:指定用户文件,默认/etc/ansible/hosts
-v:详细输出
-e "key=value":定义变量
-f NUM:线程数,默认5
--check:检测模式,不真正执行
--skip-tags TAG_NAME:不执行这个tag的任务,可以写多个
--tags TAG_NAME:只执行这个tag的任务
--start-at-task TAG_NAME:从这个tag任务开始执行
组成结构:
Inventory:要执行的主机组
Modules:调用的模块
Commands:运行的命令
Playbooks:由以下组成
Tasks:任务,调用模块完成的操作
Variables:变量
Templates:模板
Handlers:处理器,由某事件
Roles:角色
例1:
- hosts: webservers vars: - user_name: xxx remote_user: root tasks: - name: 条件判断 user: name={{ user_name }} when: ansible_xxx == "xxxxx" - name: 提示notify service: name=httpd state=started notify: - 任务名称1 - 任务名称2 - name:模板 template: src=源文件路径 dest=目标路径 tags: - 当前任务tag名称 - name:item测试 yum:name={{ item }} state=present with_items: - 软件名1 - 软件名2 handlers: - name: 任务名称1 service: name=httpd state=restarted - name: 任务名称2 service: name=httpd state=restarted
1.hosts:将要执行任务的主机,多个可以用冒号分割
2.vars:一些参数,后面可以通过{{ 参数 }}调用,
- 参数1:值
- 参数2:值
3.remote_user:由哪个用户执行
4.tasks:执行的任务
- name:任务的名称
模块名称: 参数(这里和命令行的参数一样)
notify:当前任务执行后要通知哪个任务要执行
- 通知任务名称1
- 通知任务名称2
when: 参数 == "值",当满足条件时才执行。这里的参数可以通过ansible all -m setup参考;多个条件when: (参数=="值") or (参数==“值”)
- name: 任物的名称
template: 模板的源文件中必定包含带有{{ 参数 }}的地方,参数内容会被替换成vars中对应的值,同样可以在/etc/ansible/hosts文件中对应主机后面填写参数
tags:
- 当前任务的标签
5.handlers:通过tasks中的notify调用后才执行的任务,级别和tasks一样
- name:通知任务名称1
模块名称: 参数
- name:通知任务名称2
模块名称: 参数
6.with_items:分组变量,固定格式
在一个task中调用,例如创建多个用户
tasks: - name: 创建用户 user: name={{ item }} with_items: - user1 - user2
同时可以迭代操作
tasks: - name: 创建用户,并放到对应的组中 user: name={{ item.name }} group={{ item.group }} with_items: - {{ name: 'user1' , group: 'group1' }} - {{ name: 'user2' , group: 'group2' }}
7.playbook中变量使用{{ key }},仅能由字母数字下划线组成,且只能以字母开头,变量来源如下
1.通过命令行,ansible-playbook -e key=value指定,优先级最高
2.在/etc/ansible/hosts里面指定
3.在playbook中指定
4.setup模块输出带有ansible_开头的值,例如ansible_ens160.ipv4.address
5.在独立的变量YAML文件中定义
6.在role中定义
gather_facts:默认会执行setup模块,如果不启用,setup模块的内容都不可使用
例2:批量安装zabbix客户端的yaml文件
--- - hosts: server remote_user: root vars: - server_ip: 192.168.159.128 tasks: - name: 复制软件包到被安装主机 copy: src=/root/ansible/packges/zabbix-agent.rpm dest=/root/zabbix-agent.rpm - name: 安装软件 yum: name=/root/zabbix-agent.rpm - name: 替换配置文件 template: src=/root/ansible/zabbix_agentd.conf dest=/etc/zabbix/zabbix_agentd.conf notify: - restart server - name: 启动服务 service: name=zabbix-agent state=started handlers: - name: restart server service: name=zabbix-agent state=restarted #zabbix-agent中的Hostname一项配置需要替换,每台主机都不一样,可以在ansible的主机清单中指定其配置 #zabbix-agent配置文件 [root@localhost ansible]# cat zabbix_agentd.conf PidFile=/var/run/zabbix/zabbix_agentd.pid LogFile=/var/log/zabbix/zabbix_agentd.log LogFileSize=0 Server=127.0.0.1,{{ server_ip }} ServerActive=127.0.0.1,{{ server_ip }} Hostname={{ zabbix_hostname }} Include=/etc/zabbix/zabbix_agentd.d/*.conf #ansible主机清单 [server] 192.168.159.129 zabbix_hostname=nginx 192.168.159.130 zabbix_hostname=httpd
roles:
- roles角色文件夹存放目录:配置文件中指定
[root@bogon ~]# grep roles_path /etc/ansible/ansible.cfg #roles_path = /etc/ansible/roles
- roles文件夹下创建对应role,每个role都需要有如下的文件夹
/etc/ansible/roles/ ├── nginx │ ├── default │ │ └── main.yml │ ├── files │ ├── handlers │ │ └── main.yml │ ├── meta │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ ├── templates │ └── vars │ └── main.yml └── tomcat ├── default │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── tasks │ └── main.yml ├── templates └── vars └── main.yml #files:存放由copy或script模块调用的文件 #templates:存放由template模块调用的文件 #tasks:文件夹内创建main.yml文件,定义各种tasks,其他文件需要再此文件中通过include包含 #handlers:文件夹内创建main.yml文件,定义各种handlers,其他文件需要再此文件中通过include包含 #vars:文件夹内创建main.yml文件,定义变量,其他文件需要再此文件中通过include包含 #meta:文件夹内创建main.yml文件,定义依赖关系,其他文件需要再此文件中通过include包含 #default:文件夹内创建main.yml文件,定义默认变量
- 在roles文件夹外定义playbook,文件名为site.yml
---------------
今天公司在aws海外区域部署了一套服务,aws默认有个centos用户,可以sudo使用root命令,服务器上又建立了一个developer用户,用来跑程序,每个jar包都做成systemd服务.每次Jenkins上版需要使用两个用户,developr用来备份传送jar包,centos用户用来sudo重启服务.
1.首先需要在业务服务器上做centos和developer用户在ansible服务器的免密登录(没有想到别的办法)
2.在ansible服务器的hosts文件里面只写服务器地址,不要写用户和密码
[test-aws-hdd-01] 1.2.3.4 ansible_ssh_port=22222
3.ansible的playbook需要这样写就可以同时使用两个用户了
--- # 使用developer用户拷贝jar包 - name: copy jar to server for developer! hosts: test-aws-hdd-01 remote_user: developer gather_facts: no tasks: # 备份老的jar包 - name: archive JAR archive: path: /data/gateway/tst-cloud-server-gateway-1.0.jar dest: /data/gateway/tst-cloud-server-gateway-1.0.jar.gz # 传送新的jar包 - name: copy sechedule-JAR to server copy: src: /data/jenkins/workspace/2.0-altest-yicloud-gateway/tst-cloud-server-gateway/target/tst-cloud-server-gateway-1.0.jar dest: /data/gateway/tst-cloud-server-gateway-1.0.jar #owner: developer #group: developer # 使用centos用户登录,sudo重启服务 - name: restart gateway service service: name=gateway state=restarted enabled=true remote_user: centos become: yes become_user: root become_method: sudo
ansible lookup插件:当我需要从文件中读取配置时使用,下面案例是向nacos中以接口的形式添加配置文件
post请求中如果想要把&当字符串使用,需要换成%26,要不会被转换成key=value
[root@localhost ~]# vim ansible-tst/roles/gateway/tasks/main.yaml - name: nacos接口导入网关配置文件 uri: url: http://127.0.0.1:8848/nacos/v1/cs/configs method: POST body: dataId=gateway&group=test&content="{{ lookup('template','tst-iot-server-gateway-product.yaml') }}" #lookup后面有file或template很多插件,file和template对应两个相应的模块,后面跟的文件不需要传到对应服务器就在本机就行 [root@localhost ~]# ll ansible-tst/roles/gateway/templates/ 总用量 8 -rw-r--r-- 1 root root 6380 6月 3 16:33 tst-iot-server-gateway-product.yaml