1.安装
2.部署ANSIBLE
2.1INVENTORY
2.2ANSIBLE配置文件
2.3AD HOC命令
3.PLAYBOOK
4.变量
5.ansible vault加密变量
6.ansible_facts
7.loop
8.条件判断
9.handler处理
10.错误处理
11.tags标签
12.管理文件
13.template模板
14.host-pattern
15.动态Inventory
16.role
17.配置并行
1.安装
1.1控制节点:linux
1.2 受管主机:windows
yum install ansible
yum install python36
2. 部署ANSIBLE
目录结构
2.1INVENTORY
mkdir web
vim inventory
格式:INI,YAML格式。
ansible all -i inventory --list-host #当前文件夹
# 系统目录 /etc/ansible/hosts
#查找是否有 servera这个主机
ansible all -i ./inventory --list-hosts servera
#在文件中查找 abc
grep abc /etc/hosts
#不属于任何组
ansible all -i ./inventory --list-hosts ungrouped
树形查看:ansible-inventory -i inventory --graph
[njwebs]
servera
serverb
[njdbs]
serverc
serverd
[nj:children]
njwebs
njdbs
2.2ANSIBLE配置文件
2.21配置文件及优先级
文件位置和优先级:由上到下,优先级越来越高。
./相对路径
查看当前使用的配置文件:
ansible --version|grep 'config file'
在文件 ansible.cfg中查找 ‘^\[’
egrep ‘^\[’ ansible.cfg
2.22常见配置
2.23 验证配置
ansible all -m command -a id
2.3AD HOC命令
目的:
1.快速执行单个任务
2.快速测试和更改
3.执行简单任务
返回值:
3.PLAYBOOK
vim ~/.vimrc 在家目录下 用vim时执行命令
bash ~/.bashrc 在家目录下 用bash时执行命令
vim /etc/vimrc 全局的vimrc
set ai ts=2
# ai 自动缩进 ts=2 tab键用2个空格实现
3.1一文件一个列表:
--- #开始
- name: create user # - 代表列表
hosts: servera
tasks:
- name: create user laoma
user:
name: tang
uid:
state: present
shuiguo:
- pingguo
- juzi
- taozi
... #结束 一般不写
3.2 一文件中多个列表
3个层次:是列表类型 -
1.play :name,hosts,tasks
2.tasks:name,模块
3.模块
冒号后有一个空格 字典类型(多个键值对)
key: value 字典类型
4.变量
4.1变量定义
4.2 变量作用域
4.3 引用变量时要用引号
1.变量声明
2.变量文件声明
注意:
:后面一定要加“”或者‘’
4.4.主机变量和主机组变量
1.主机变量:
---
- name: test vars
hosts: servers
remote_user: root
vars_files:
- vars/user1.yml
#vars:
# user: joe
# home: /home/joe
tasks:
- name: add user {{ user }}
user:
name: "{{ user }}"
home: "{{ home }}"
- name: debug user
debug:
msg: >
username is {{ user }}
home is {{ home }}
inventory
[servers]
servera user=usera home=/opt/usera
serverb user=userb home=/opt/userb
此时 vars_files需要注释掉。
2.主机组变量
优先级低于主机变量的。
inventory
[servers]
servera user=usera home=/opt/usera
serverb
[servers:vars]
user=tom
home=/opt/tom
3.如果有非常多的主机:
3.1主机目录:host_vars:
3.2主机组目录:group_vars:
#1.创建目录mkdir host_vars
#2.创建servera.yml. serverb.yml
vim host_vars/servera.yml
user: user1
home: /opt/user1
user: user2
home: /opt/user2
grep . host_vars/* # 当前目录/host_vars/
3.2主机组目录:group_vars:
vim group_vars/servers.yml
users: user-servers
home: /opt/user-servers
tree group_vars/ host_vars/
4.4数组变量
4.41数组列表树形结构
users_vars.yml
user: user1
home: /opt/user1
ansible_host: servera.lab.example.com
ansible_user: root
users:
bjones:
frist_name: Bob
last_name: Jones
home_dir: /users/bjones
acook:
frist_name: Anne
last_name: Cook
home_dir: /users/acook
users-play.yml
---
- name: test vars
hosts: servera
remote_user: root
tasks:
- name: add user {{ user }}
user:
name: "{{ users.bjones.first_name }}_{{ users.bjones.last_name }}"
home: "{{ users.bjones.home_dir }}"
state: present
- name: add user {{ user }}
debug:
msg: >
username is {{ user }}
home is {{ home }}
4.42变量是两个列表,引用时使用下标的方式:
users_vars.yml
user: user1
home: /opt/user1
ansible_host: all
ansible_user: root
users:
- first_name: bob
last_name: jones
home_dir: /users/bjones
- first_name: Anne
last_name: Cook
home_dir: /users/acook
users_play1.yml
---
- name: test
hosts: servera
remote_user: root
tasks:
- name: create
file:
path: /users
state: directory
- name: add user
user:
name: "{{ users[0].first_name }}_{{ users[0].last_name }}"
home: "{{ users[0].home_dir }}"
state: present
- name: debug
debug:
msg: >
username is {{ user }}
home is {{ home }}
users_play2.yml
---
- name: test
hosts: servera
remote_user: root
tasks:
- name: create
file:
path: /users
state: directory
- name: add user
user:
name: "{{ users[0]['first_name'] }}_{{ users[0]['last_name'] }}"
home: "{{ users[0]['home_dir'] }}"
state: present
- name: debug
debug:
msg: >
username is {{ user }}
home is {{ home }}
以上两种都可以。vim
1.块复制
编辑可视块提示字样 :ESC+ ctrl+V
复制:选取 +y
黏贴:p
回到编辑态
2.删除所有行内容
ESC:退出编辑模式
g g:光标移到文本的首行
d+G:
ESC:1,$d
3.替换 把users 替换成 user-type1
:%s/users/users-type1/g
4.43用于捕获任务输出
users_vars.yml
user: user1
home: /opt/user1
ansible_host: all
ansible_user: root
users_type2:
- first_name: bob
last_name: jones
home_dir: /users/bjones
- first_name: Anne
last_name: Cook
home_dir: /users/acook
users_type1:
- first_name: bob
last_name: jones
home_dir: /users/bjones
- first_name: Anne
last_name: Cook
home_dir: /users/acook
users_play.yml
---
- name: test vars
hosts: servera
remote_user: root
tasks:
- name: add user
user:
name: "{{ users_type1[0].frist_name }}_{{ users_type1[0].last_name }}"
home: "{{ users_type1[0].home_dir }}"
state: present
register: result #定义了一个变量用于存储返回值
- name: show result
debug:
var: result
4.5 4个MAGIC变量
hostvars[host].ansible_default_ipv4.address
hostvars[host].ansible_fqdn
hostvars[host].ansible_hostname
when inventory_hostname in groups.dev
5.ansible vault加密变量
ansible-vault --help
# 加密
ansible-valut encrypt host_vars/servera.yml
# 查看
ansible-valut view host_vars/servera.yml
# 编辑
ansible-valut edit host_vars/servera.yml
# 解密
ansible-valut decrypt host_vars/servera.yml
#创建
ansible-valut create securite.yml
6.ansible_facts
通过setup模块查看: ansible servera -m setup|less
ansible servera -m setup | less
ansible servera -m setup > fact.yml
ansible servera -m debug -a 'var=ansible_facts'
#看不到值的
show_facts.yml
---
- name: show var ansible_facts
hosts: servera
tasks:
- name: show var ansibe_facts
debug:
var: ansible_facts
deploy_web.yml
不收集事实 gather_facts: false
---
- name:
hosts: servera
gather_facts: false
remote_user: root
become: true
become_method: sudo
become_user: root
tasks:
- name:
yum:
name: httpd
state: present
- name:
引用 两种写法
ansible_default_ipv4.address
ansible_facts.default_ipv4.address
1.判断是否存在
ansible_lvm.vgs.research is defined
ansible_lvm.vgs.research is not defined
ansible_devices.vdb is defined
ansible_devices.vdb is not defined
2.取值
{{ hostvars[host].ansible_default_ipv4.address }}
{{ hostvars[host].ansible_fqdn }}
{{ hostvars[host].ansible_hostname }}
‘memory={{ ansible_memtotal_mb }}’
'vdasize={{ ansible_devices.vda.size | default("NONE")}}'
7.loop
#删除 host_vars里的文件
rm -fr host_vars/*
vim host_vars/servera/users_vars.yml
ssh root@servera "egrep 'jack|tom' /etc/passwd"
users_vars.yml
#写法1
user1: jack
user2: tom
#写法2
users:
- jack
- tom
#写法3
users:
bjones:
frist_name:
last_name:
home_dir:
acook:
frist_name:
last_name:
home_dir:
users_play_loop1.yml
---
- name: create users
hosts: servera
gather_facts: no
vars:
users:
- jack
- tom
tasks:
- name: add user jane
user:
name: "{{ item }}"
state: present
loop:
- jack
- tom
users_play_loop2.yml
---
- name: create users
hosts: servera
gather_facts: no
vars:
users:
- jack
- tom
tasks:
- name: add user jane
user:
name: "{{ item }}"
state: present #删除 absent
loop: "{{ users }}"
7.1简单的循环
声明变量和不声明变量2种。
7.2循环列表值 列表中带有字典
7.3with_list with_item
7.4with_random_choice
8.条件判断
8.1判断:== 》等
是否定义:is defined
---
- name: test when
hosts: servera
gather_facts: no
vars:
run_mytasks: true
tasks:
- name:
debug:
msg: "hello my task"
when: run_mytasks
8.2 判断执行结果
9.handler处理:
与一般的任务区别在于什么?
handlers:
1.多个任务都会执行同一个函数,最后一个任务时才执行
2.任务发生改变时才通知handlers
3.如果状态未发生改变是不执行的,比如相同的playbook,运行两次。
一步步执行
ansible-playbook handlers.yml --step
notify:
- hello
- restart apache
handlers:
- name: restart apache
service:
name:
state:
- name: hello
debug:
先执行 restart apache,再执行hello
执行顺序取决于 handlers 而非 notify
10.错误处理
1.返回值变量关键字:register
2.返回的值: successded,failed,changed
3.忽略执行错误:ignore_errors: true #yes
---
- name: test error
hosts: servera
gather_facts: no
vars:
doshell: "yes"
tasks:
- shell : cat /etc/host
register: result
ignore_errors: true
when: deoshell == "yes"
- name: success
debug:
msg: success
when: result is succeeded
- name: failed
debug:
msg: failed
when: result is failed
- name: changed
debug:
msg: changed
when: result is changed
1.一般任务,忽略错误
2.notify-handler模式的play,执行失败后仍然运行handlers
3.failed模块, 任务必定failed,停在这一步。
4.failed_when 指明什么条件下,判定任务执行失败。
5.ansible block和错误处理
5.1当两个语句都需要when 语句判断时,用了block。
---
- name: block example
hosts:
gather_facts: no
tasks:
- block:
- name:
debug:
msg: task1
- name:
debug:
msg: task2
when: ansible_distribution == "redhat"
5.2 三个层次
block 是主任务,执行失败时运行rescue,无论成功与否都执行always.
---
- name: test block
hosts: mytest
gather_facts: no
vars:
- run: no
tasks:
- block:
- name:
debug:
msg: task1 in block
- name:
debug:
msg: task2 in block
rescue:
- name:
debug:
msg: task1 in rescue
- name:
debug:
msg: task2 in rescue
always:
- name:
debug:
msg: task1 in always
- name:
debug:
msg: task2 in always
查看 ansible facts值:ansible servera -m setup|less
11.tags标签
---
- name:
hosts:
tasks:
- name: httpd
yum:
name: httpd
state: latest
tags: webserver
- name:
yum:
name: postfix
state: latest
tags: mailserver
- name: always debug
debug:
msg: debug
12.管理文件
查找本地的用户和组: /etc/shadow /etc/passwd
12.1 file 创建目录、文件、软硬链接
---
- name:
hosts:
tasks:
- name: create file
file:
path: ~/mytest/testfile
owner:
group:
mode: '0640'
setype: httpd_sys_content_t
state: touch # state 参数file ,directory,link,touch
- name: create directory
file:
path: ~/mytest/testdir
owner:
group:
mode: '0640'
setype: httpd_sys_content_t
state: directory # state 参数file ,directory,link,touch
- name: install package
yum:
name: httpd
state: present #state 参数 present absent
- name: install package
service:
name: "{{ item }}""
state: present
loop:
- httpd
- firewalld
- name: create user
user:
name: harry
state: present
- name: create groups
group:
name: sysm
state: present
file :touch:创建 ;absent:删掉;directory:目录。
12.2修改上下文 selinux context:sefcontext
12.3 lineinfile 修改文件内容
12.4 replace 多行替换
12.5 copy
13.template模板
13.1 基本功能
变量替换。被传输的文件内容是变量,每台机器各异。
1.模板调用: mytesttemplate.yml
2.模板文件:my.cnf
---
- name: test jinja2
hosts: servera
tasks:
- name:
template:
src: my.cnf
dest: /root/my.cnf
my.cnf
bind {{ ansible_default_ipv4.address }}
13.2 jinja2模板
模板中 光#不是注释。
语法:哪些内容被替换,哪些不被替换?
如果指示不用手动编辑:
1.ansible.cfg文件中添加
ansible_managed= Ansible managed
2.jinja2 模板中添加
# {{ ansible_managed }}
13.21 条件语句+替换的变量是ansible_facts的值
{% for host in groups['all'] %}
{{ hostvars[host]['ansible_facts']['default_ipv4']['address'] }} {{ hostvars[host]['ansible_facts']['fqdn'] }} {{ hostvars[host]['ansible_facts']['hostname'] }}
{% endfor %}
{% for host in groups.all %}
{{ hostvars[host].ansible_default_ipv4.address }} {{ hostvars[host].ansible_facts_fqdn }} {{ hostvars[host].ansible_hostname }}
{% endfor %}
13.22 替换的变量来自文件
变量文件:~/ansible/host_vars/servera.yml
变量文件名为主机名,不可任意命名。
ssh_port: 1022
root_allowed: yes
groups_allowed: root
passwords_allowed: yes
模板文件:myvars.cnf
Port {{ ssh_port }}
ListenAddress {{ ansible_defalut_ipv4.address }}
PermitRootLogin {{ root_allowed }}
Allow Groups {{ groups_allowed }}
PasswordAuthentication {{ passwords_allowed }}
13.23 for循环的是自定义变量
模板文件:fro.j2
{% for user in users %}
user:{{ user }}
{% endfor %}
变量文件:vim /host_vars/servera.yml
users:
- user01
- user02
- user03
13.24
13.25 变量过滤器
13.26 字符操作过滤器
14.host-pattern
# 1.查找主机 servera
ansible --list-hosts servera
# 2. 查找主机组 出2个
ansible --list-hosts datacenter1
# 并集
ansible --list-hosts datacenter1 ,new
ansible --list-hosts datacenter1 :new
#3. 查找父组 出4个 就是他们底下的 datacenter1 ,datacenter2
ansible --list-hosts datacenter
#4.模糊匹配 一定要加单引号
ansible --list-hosts all
ansible --list-hosts '*'
ansible --list-hosts 'server*'
ansible --list-hosts '172*'
#5.取两个主机组的交集
ansible --list-hosts ' datacenter1,&lab'
ansible --list-hosts ' datacenter1,&serverc'
#6.取数组第1个值, 0-1, -1最后
ansible --list-hosts 'new[0]'
ansible --list-hosts 'new[0-1]'
ansible --list-hosts 'new[-1]'
15.动态Inventory
wget http:// -O inventory/inventorya.py
mv inventorya.py inventory
#添加执行权限
chmod +x inventory/*
inventory/inventorya.py --list | json_reformat
脚本如何写?
16.role
16.1 role 结构
role 定义了:tasks,操作的主机,模板。
3个示例:
16.11 timesync
1.安装包
2.复制角色所有文件
3.查看帮助文件: 得到示例 README.md
4.编写调用的:playbook
sudo yum list|grep roles*
sudo yum install -y rhel-system-roles
cp -r /usr/share/ansible/roles/rhel-systemroles.timesync roles/timesync
ansible-galaxy list
vim roles/timesync/README.md
---
- name: Use RHEL system role
hosts: all
vars:
timesync_ntp_servers:
- hostname: 172.25.254.254
iburst: yes
roles:
- timesync
16.12 seliunx
1.安装包。
2.复制角色所有文件。
3.查看帮助文件: 得到示例
/usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml
4.编写调用的:playbook
sudo yum list|grep roles*
sudo yum install -y rhel-system-roles
cp -r /usr/share/ansible/roles/rhel-systemroles.selinux roles/selinux
ansible-galaxy list
cp /usr/share/doc/rhel-system-roles/selinux/example-selinux-playbook.yml ~/ansible/myselinux.yml
---
- name: Use RHEL system role
hosts: all
vars:
selinux_policy: targeted
selinux_state: enforcing
selinux_reboot_required: true
tasks:
- block:
- name: Apply SELinux role
include_role:
name: selinux
rescue:
- name: Check for failure for other reasons than required reboot
fail:
when: not selinux_reboot_required
- name:
reboot:
- name: Reapply SELinux role
include_role:
name: selinux
16.13 apache
1.主任务:tasks: main.yml
2.主任务中的变量:defaults:main.yml
3.主任务中的motd文件: vim files/motd
4.主任务中的
4.1 模板文件:templates/laoma.conf.j2
4.2 handlers文件:handlers/main.yml
5.
6.模板文件: templates/index.html.j2
7. 使用
1.主任务 tasks: main.yml
---
- name: install web
tasks:
- name: 1.install package defaults/main.yml
yum:
name: "{{ web_package }}"
state: present
- name: 2.start service
service:
name: "{{ web_service }} "
state: started
enabled: yes
- name: 3.prepare motd files/motd
copy:
src: motd
dest: /etc/motd
- name: 4. prepare conf templates/laoma.conf.j2 handlers/main.yml
template:
src: laoma.conf.j2
dest: /etc/httpd/conf.d/laoma.conf
notify:
- restart_web
- name: 5.prepare docRoot
file:
path: "/var/www/html/{{ ansible_hostname }}"
state: directory
- name: 6.prepare index.html
template:
src: index.html.j2
dest: "/var/www/html/{{ ansible_hostname }}/index.html"
2.主任务中的变量文件:defaults:main.yml
---
web_package: httpd
web_service: httpd
3.主任务中的motd文件 vim files/motd
# /etc/issue和/etc/motd
#区别在于 /etc/issue 是在 登录之前显示, /etc/motd 是在登录之后显示
hello guys
welcome to servera!
4.主任务中的
4.1模板文件: templates/laoma.conf.j2
4.2 handlers文件:handlers/main.yml
---
- name: restart_web
service:
name: httpd
state: restarted
5.
6.模板文件:templates/index.html.j2
hello guys
welcome to {{ ansible_fqdn }}!
meta/main.yml
7.使用:ansible-galaxy list
---
- name:
hosts: mytest
roles:
- apache
curl http://localhost
16.2 使用 rhel-system-role
deploy apache
vim mytestDeployApache.yml
16.21 :关键字
roles:
- apache
---
- name: deploy apache
hosts: serverc
roles:
- apache
16.22 : tasks:
include_role:
16.3 使用 Galaxy 角色
查看:
ansible-galaxy info haproxy --offline
ansible-galaxy role info -h
ansible-galaxy search haproxy
ansible-galaxy install docker
安装:
单个安装和多个安装:
ansible-galaxy install -r requires.yml
vim requires.yml
a) ansible init tang cd tang
b) cat tasks/main.yml
17.配置并行
17.1设置forks
1.修改主机清单:inventory:
[servers]
server[a:d]
# 1.查看默认配置
ansible-config dump|grep -i fork
#2.修改配置文件
vim ansible.cfg
ansible all -m ping
2.修改配置文件: ansible.cfg
[defaults]
inventory=inventory
remote_user=root
forks=2
3.编写 playbook:
---
- name:
hosts: all
gather_facts: no
tasks:
- name: task1
shell: sleep 3
4.设置并发台数:
4.1.修改配置文件 ansible.cfg 可以控制每次的台数
4.2.使用命令行控制:ansible-playbook playbook.yml -f 3 命令行高于配置文件。
17.2滚动更新
a)串行:一次完成整个playbook
滚动更新用的就是串行。
b)并行:多台先完成一个task
关键词
serial: 2
serial: 20%
---
- name: test
hosts: all
serial: 2
gather_facts: no
tasks:
- name: task 1
shell: sleep 3
滚动更新示例:
异步并行模式:
示例:
---
- name:
hosts:
tasks:
- name: connection
shell:
async: 5
poll: 2