- 1.ansible简介
- 2.ansible相关指令
- 3.ansible常用模块
- 4.ansible playbook
- ansible的内建变量是由setup模块提供的,里面记录许多的主机信息;ansible使用{{ }}来引用变量,注意前后有空格;
- 注意变量只能在ansible-playbook中使用,因为只有使用palybook时,才会获取远程主机信息,也就是Gathering Facts
- 变量是同一类元素,用列表,表示方法,key:value
- 1.复制redis主配置文件
- 2.修改监听地址,与密码为对应变量
- 3.配置playbook
- 需求:当系统是Centos7安装mariadb,Centos6安装mysql
- 1.使用ansible setup模块获取版本信息
- 2.编写playbook
- 1. 定义角色存放的路径
- 2. 角色的集合
- 每一个层级都有自己对应的配置文件,将playbook的功能划分为各个层级
- 1. tasks文件
- 2. vars文件
- 3. handlers文件
- 4.template模板
- 5. file被调用文件
- 6. nginx.yml直接调用角色
1.ansible简介
特性:
- 模块化:调用特定的模块,完成特定的任务;
- 基于python语言实现,由Paramiko,PyYAML和Jinja2三个关键模块;
- 部署简单:agentless
- 支持自定义模块;
- 支持playbook
配置文件:
- ansible指令
```shell ansible HOST_PATTERN OPTION OPTIONS: -m,—module-name:模块名称 -a,—args:向模块传递参数 -f,—forks:在几个主机上并行(default=5) -C,—check:don’t make any changes; —list-host:列出匹配主机
connection Options: -u,—user:以指定身份登录远程主机 -c,—connection:连接方式(default=smart)
example: ansible HOST_PATTERN -m MODULE_NAME -a MODULE_ARGS -f FORKS -C
2. ansible-doc指令
```shell
ansible-doc OPTION MODULE
OPTIONS:
-s:查看模块的简单说明
-l,--list:列出所有模块
-a,--all:查看所有文档
example:
ansible-doc -s ping #查看ping模块的说明
3.ansible常用模块
1.ping模块
#检测ansible连接的主机是否在线
[root@node1 ~]# ansible all -m ping
192.168.10.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.10.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
2.group模块
#该模块用于添加或者删除一个group
ARG:
gid #set group id
name= #set group name
state #set group state;the values is "present" or "absent"
system #if "yes",indicates that the group create is system group
example:
1.ansible all -m group -a "gid=3000 name=mygroup state=present system=no"
#创建一个gid为3000 名称为mygroup的组
2.ansible all -m group -a "gid=3000 name=mygroup state=absent system=no"
#删除一个gid为3000 名称为mygroup的组
注意:带等号为必填
3.user模块
#Manage user accounts,管理用户账户
ARG:
comment #描述信息
expires #过期时间
group #基本组
groups #附加组
home #家目录路径
password #密码
shell #用户的shell
state #present or absent 创建还是删除
system #系统用户
uid #用户id
move_home #两次创建一个用户,家目录不是同一路径,是否需要直接移动家目录
generate_ssh_key #创建用户时,是否同时生成一对秘钥
create_home #当创建用户或者家目录不存在时,是否为用户创建家目录
example:
ansible all -m user -a "name=aa uid=5555 state=present shell=/sbin/nologin create_home=no"
4.copy模块
#copy files to remote locations
ARG:
backup
content #不指定src,由content生成的内容即为复制内容
dest #目标路径
directory_mode #
src #本机路径,如果复制目录,有"/"则表示复制目录下所有文件,否则递归复制整个目录
remote_src #从远程主机复制到另一个远程主机
group
owner #copy之后的属主,属组,权限
mode
example:
1.ansible all -m copy -a "src=/etc/passwd dest=/tmp/passwd.ansible mode=644"
2.ansible all -m copy -a 'content="hello world\n" dest=/tmp/hello.txt mode=600'
#用content生成的内容复制到目标主机名称为hello.txt
3.ansible all -m copy -a 'src=/home/linxi dest=/tmp/'
#复制改目录到指定目录下
#copy 可以创建文件
5.fetch模块
#Fetch files from remote nodes 从远程主机获取文件
ARG:
dest #目标
src #源
fail_on_missing #由于任何原因无法读取远程文件,则任务将失败
example:
ansible all -m fetch -a 'dest=/tmp/backup.ansible? src=/etc/passwd'
#fetch复制文件时,会在本地创建目录,将多个主机上的文件都放在改目录下
6.command模块
#Execute commands on target 在目标主机上执行指令
ARG:
chdir #切换目录执行command
example:
ansible all -m command -a 'whoami'
#command模块不能解析shell语句
7.shell模块
#Execute shell commands on targets在目标主机上执行shell指令
ARG:
chdir #切换目录执行command
executable #使用其他的shell解析
example:
ansible all -m shell -a 'echo "123465"|passwd --stdin root'
8.file模块
#Manage files and file properties管理文件和文件属性
ARG:
state #文件属性directory,file,link
src #在目标主机上创建符号链接
path #创建文件或目录路径
mode
owner
group
example:
ansible all -m file -a "path=/root/ansible state=directory mode=644 owner=root"
#在目标主机上创建目录
ansible all -m file -a "src=/etc/fstab path=/root/fatab.link state=link"
#在目标主机创建链接
#不建议创建文件,
9.cron模块
#Manage cron.d and crontab entries管理cron.d和contab条目
ARG:
day #天
hour #小时
minute #分钟
job #执行指令
name #任务名
state #present or absent
user #执行任务的用户
weekday #星期
example:
ansible all -m cron -a 'name="sync time" minute=*/1 job="/usr/sbin/ntpdate 192.168.10.11 &> /dev/null" state=present'
10.yum模块
#Manages packages with the `yum' package manager 使用yum管理程序包
ARG:
name #软件包名称
state #install(present or latest),remove(absten or removed)
disable #禁用某个安装仓库
enable #启用某个安装仓库
disable_gpg_check #是否使用gpgcheck
example:
ansible all -m yum -a "name=nginx state=present"
11.service模块
#Manage services
ARG:
enable #开机自启
name #服务名称
pattern #服务不支持status,无法获取服务状态信息时,可以使用pattern过滤关键字
runlevel #启动级别
state #设置服务是启动还是停止,reloaded, restarted, started, stopped
example:
ansible all -m service -a "name=nginx state=started "
12.script模块
#Runs a local script on a remote node after transferring it 在远程主机上执行本地脚本
example:
ansible all -m script -a "/root/a.sh" #直接指定本地脚本
4.ansible playbook
1.playbook格式:
palybook是由yaml语言构成
yaml是由:键值对,列表,关联数组构成
键值对:key:value
name:jack
age:18
列表:一组类型相同的元素,由‘—’开头
-apple
-orange
关联数组:键值对与列表的嵌套
-host
name:node1
age:10
-host
name:node2
age:10
2.palybook的组成
核心元素 | 作用 |
---|---|
Hosts | 主机列表 |
Remoter_user,su sudo | 执行远程主机任务的用户 |
Tasks | 任务列表 |
Variables | 变量 |
Templates | 模板文本 |
Handlers,notify | 由特定条件出发的任务 |
Tag | 标记式运行 |
3.运行palybook方式
- 测试
```shell 1.ansible-playbook —syntax-host #检测语法错误
2.ansible-playbook —list-host #列出运行任务的主机
3.ansible-playbook —list-task #列出任务
2. 直接运行
```shell
1.ansible-playbook PATH #直接接路径运行
2.ansible-playbook -t TAG_NAME PATH #运行playbook中指定的TAG
4.palybook实战
1.ansible-playbook
[root@node1 playbooks]# vim httpd.yaml
#hosts指定运行主机,也可以使用ansible的hosts文件中定义的标签
- hosts: 192.168.10.12
#remote_user执行远程任务的主机
remote_user: root
#task任务列表
tasks:
#name任务名称
- name: install httpd
#MODULE:ARG调用的模块和模块使用的参数
yum: name=httpd state=installed
- name: configure httpd file
copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
- name: start httpd
service: name=httpd state=started
#语法检测
[root@node1 playbooks]# ansible-playbook httpd.yaml --syntax-check
playbook: httpd.yaml
#运行
[root@node1 playbooks]# ansible-playbook httpd.yaml
#Gathering Facts 获取远程主机信息
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.10.12]
TASK [install httpd] ******************************************************************************************************************
changed: [192.168.10.12]
TASK [configure httpd file] ***********************************************************************************************************
changed: [192.168.10.12]
TASK [start httpd] ********************************************************************************************************************
changed: [192.168.10.12]
PLAY RECAP ****************************************************************************************************************************
192.168.10.12 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
2.Handlers触发执行
[root@node1 playbooks]# vim httpd.yaml
- hosts: 192.168.10.12
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: configure httpd file
copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
#当任务状态为changed才会通知handlers
notify: restart httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
3.Tag选择执行
[root@node1 playbooks]# vim httpd.yaml
- hosts: 192.168.10.12
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=installed
- name: configure httpd file
copy: content="ansible test" dest=/var/www/html/index.html owner=apache group=apache
notify: restart httpd
#定义任务标签名
tags:configure_httpd
- name: start httpd
service: name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
#-t选项只执行标签任务
[root@node1 playbooks]# ansible-playbook httpd.yaml -t configure_httpd
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.10.12]
TASK [configure httpd file] **********************************************************************************************************
ok: [192.168.10.12]
#--skip-tags不执行标签中的内容
[root@node1 playbooks]# ansible-playbook --skip-tags configure_httpd httpd.yaml
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.10.12]
TASK [install httpd] *****************************************************************************************************************
ok: [192.168.10.12]
#没有执行configure httpd file
TASK [start httpd] *******************************************************************************************************************
ok: [192.168.10.12]
5.Variable的使用
- 内建变量,fects,直接调用
```yamlansible的内建变量是由setup模块提供的,里面记录许多的主机信息;ansible使用{{ }}来引用变量,注意前后有空格;
ansible 192.168.10.12 -m setup #获取192.168.10.12的内建变量
注意变量只能在ansible-playbook中使用,因为只有使用palybook时,才会获取远程主机信息,也就是Gathering Facts
[root@node1 playbooks]# vim facts.yaml
- hosts: 192.168.10.12
remote_user: root
tasks:
- name: look up internal variable
copy: content={{ ansible_default_ipv4 }} dest=/tmp/ansible.variable#注意括号与变量名中间的空格
- name: look up internal variable
[root@node1 playbooks]# ansible-playbook facts.yaml
[root@node1 playbooks]# ansible 192.168.10.12 -m shell -a ‘cat /tmp/ansible.variable’ {“macaddress”: “00:0c:29:d5:c5:7b”, “network”: “192.168.10.0”, “mtu”: 1500, “broadcast”: “192.168.10.255”, “alias”: “ens33”, “netmask”: “255.255.255.0”, “address”: “192.168.10.12”, “interface”: “ens33”, “type”: “ether”, “gateway”: “192.168.10.254”}
2. 通过命令行传递变量
```yaml
#ansible命令行中使用-e VARS,--extra-vars=VARS来指定,使用key:value格式指定
[root@node1 playbooks]# vim install_package.yaml
- hosts: 192.168.10.12
remote_user: root
tasks:
- name: install {{ package_name }}
yum: name={{ package_name }} state=installed
#传递nginx到package_name
[root@node1 playbooks]# ansible-playbook -e package_name=nginx install_package.yaml
TASK [Gathering Facts] **************************************************************************************************************
ok: [192.168.10.12]
TASK [install nginx] #将package_name替换为nginx
**************************************************************************************************************
ok: [192.168.10.12]
- 在playbook中自定义变量
```yaml [root@node1 playbook]# vim pb_var.yaml
- hosts: 192.168.10.12
remote_user: root
vars: #定义变量
变量是同一类元素,用列表,表示方法,key:value
- pb: palybook variable tasks:
- name: palybook variable copy: content={{ pb }} dest=/tmp/pb.var
[root@node1 playbook]# ansible 192.168.10.12 -m shell -a ‘cat /tmp/pb.var’ #查看变量名称是否正确 192.168.10.12 | CHANGED | rc=0 >> palybook variable
4. Host Inventory,通过主机清单定义变量<br />(a) Inventory参数,用于定义ansible连接远程主机时使用的参数 <br />(b)主机清单自定义变量
| Inventory参数 | 作用 |
| --- | --- |
| ansible_ssh_host | 定义远程连接的主机 |
| ansible_ssh_port | 远程连接的主机的端口 |
| ansible_ssh_user | 远程连接登录的用户 |
| ansible_ssh_pass | 远程连接登录的密码 |
| ansible_sudo_pass | 远程连接提权密码 |
```shell
[root@node1 playbook]# ansible all -m user -a 'name=test1 state=present'
[root@node1 playbook]# ansible all -m shell -a "echo 123456 | passwd --stdin test1"
[root@node1 playbook]# vim /etc/ansible/hosts
192.168.10.12 ansible_ssh_user=test1 ansible_ssh_pass=123456
192.168.10.13 ansible_ssh_user=test1 ansible_ssh_pass=123456
[root@node1 playbook]# ansible all -m shell -a 'whoami'
192.168.10.13 | CHANGED | rc=0 >>
test1
192.168.10.12 | CHANGED | rc=0 >>
test1
vim /etc/ansible/hosts
[web_server]
192.168.10.12 ipaddr=192.168.10.12 #ipaddr为主机清单自定义变量
192.168.10.13 ipaddr=192.168.10.13
[web_server]
domain=abc.com #自定义组变量
#将变量存在目标主机
[root@node1 playbook]# ansible all -m copy -a 'content={{ ipaddr }} dest=/tmp/host.var'
#查看变量内容
[root@node1 playbook]# ansible all -m shell -a 'cat /tmp/host.var'
192.168.10.13 | CHANGED | rc=0 >>
192.168.10.13
192.168.10.12 | CHANGED | rc=0 >>
192.168.10.12
6.模板 Template
template模块:基于模板方式生成一个文件复制到远程主机
ARG:
src #模板文件
dest #目标主机目录
owner
group #文件属主属组权限
mode
文本文件,嵌套脚本(使用模板编程语言)
变量:(与python一直)
字符串:使用单引号和双引号
数字:整数,浮点数
列表:["arg","arg2"]
元组:("arg1","arg2")
字典:{"key1":"values2","key2":"values2"}
算数运算符:+ - * /
实战,基于模板将redis监听端口为网卡地址,密码为主机名
```yaml1.复制redis主配置文件
cp /etc/redis.conf /root/playbook/redis.conf.j2
2.修改监听地址,与密码为对应变量
vim redis.conf.j2 #配置模板文件 bind {{ ansible_default_ipv4.address }} requirepass ansible_fqdn
3.配置playbook
vim redis.yaml
- hosts: 192.168.10.12 remote_user: root tasks:
- name: install redis yum: name=redis state=installed
- name: config redis template: src=/root/playbook/redis.conf.j2 dest=/etc/redis.conf #src为模板文件直接复制到远程主机 notify: restart_redis
- name: start service service: name=redis state=started handlers:
- name: restart_redis
service: name=redis state=restarted
```
7.playbook循环和判断
- 条件测试,when语句,在tasks中使用
```shell需求:当系统是Centos7安装mariadb,Centos6安装mysql
1.使用ansible setup模块获取版本信息
“ansible_distribution_major_version”: “7”
2.编写playbook
- hosts: all
remote_user: root
tasks:
- name: install mariadb
yum: name=mariadb state=installed
when: ansible_distribution_major_version == "7" #测试当前系统版本信息
- name: install mysql
yum: name=mysql state=installed
when: ansible_distribution_major_version == "6"
2. 需要重复执行的任务,循环;对循环的引用固定变量名为{{ item }},暂停with_items给定要循环的元素列表
```yaml
#需求,使用循环,安装lamp环境
vim intsall_LNMP.yaml
- hosts: 192.168.10.12
remote_user: root
tasks:
- name: install package
yum: name={{ item }} state=installed
with_items:
- nginx
- mysql
- php
- php-fpm
- php-mysql
8.roles角色
- 执行同一种任务的所有元素的集合,构成角色;
```shell1. 定义角色存放的路径
[root@node1 ~]# grep roles /etc/ansible/ansible.cfg roles_path = /etc/ansible/roles
2. 角色的集合
[root@node1 ~]# tree /etc/ansible/roles/ -L 1 /etc/ansible/roles/ ├── httpd #完成httpd任务的集合 ├── mysql ├── nginx └── redis
2. 每个角色都有特定的目录结构
```shell
[root@node1 ansible]# tree roles/nginx/ -d
roles/nginx/
├── default #设定默认变量时使用此目录中的main.yml文件
├── files #存放由copy或script模块等调用的文件
├── handlers #此目录的任务由notify调用,文件名为main.yml,其它文件需要通过include包含
├── meta #定义当前角色的特殊设定及其依赖关系
├── tasks #至少要有一个tasks目录,执行任务的目录下的文件名都是mian.yml
├── templates #template模块查找所需要模板文件的目录
└── vars #此目录用来存储playbook变量,文件名为main.yml,其它文件需要通过include包含
- 部署一个nginx
```yaml每一个层级都有自己对应的配置文件,将playbook的功能划分为各个层级
[root@node1 ansible]# tree roles/nginx/ roles/nginx/ ├── default ├── files │ └── index.html ├── handlers │ └── main.yml ├── meta ├── tasks │ └── main.yml ├── templates │ └── vhost1.conf.j2 └── vars └── main.yml
1. tasks文件
- name: install nginx
yum: name=nginx state=installed
- name: config file
template: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf
notify: restart nginx
tags: config_nginx
- name: set site web root
file: path={{ nginx_root }} state=directory
- name: set sete index
copy: src=index.html dest={{ nginx_root }}/index.html #copy中的src默认是调用file目录中文件
- name: start nginx
service: name=nginx state=started
2. vars文件
nginx_root: /nginx/date
3. handlers文件
- name: restart nginx
service: name=nginx state=restarted
4.template模板
server{
listen 80;
server_name {{ ansible_fqdn }};
location / {
root {{ nginx_root }}; #vars中定义的变量
index index.html;
}
}
5. file被调用文件
<h1>vhost1</h1>
6. nginx.yml直接调用角色
- hosts: node2.abc.com
remote_user: root
roles:
- nginx
```