目录
一. inventory 主机清单
1.1 inventory 中的变量含义
1.2 主机变量使用
1.3 组变量使用
1.4 组嵌套使用
二. playbook 剧本
1. playbook 的相关知识
1.1 playbook 的简介
1.2 playbook 的各部分组成
1.3 特点与优势
2. 基础的playbook剧本编写实例
2.1 playbook 编写 apache 的 yum 安装部署剧本
2.2 playbook 编写 nginx 的 yum 安装并且能修改其监听端口的剧本
3. playbook 的定义、引用变量
3.1 基础变量的定义与引用
3.1.1 创建文件
3.1.2 引用 fact 信息中的变量
3.1.3 综合使用
3.1.4 指定远程主机sudo切换用户
4. when 条件判断
5. 迭代
5.1 with_item 单循环输出
5.2 with_list 每组列表一起循环的输出
5.3 with_together 同一列表位置数据组合输出的循环
5.4 with_nested 列表数据循环匹配的循环
6. Templates 模块
7. Tags
7.1 单标签的使用
7.2 多标签的使用
7.3 通用标签 always 的运用
8. roles
9. 操作:搭建 LAMP
一. inventory 主机清单
Inventory 支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内。
1.1 inventory 中的变量含义
Inventory 变量名 | 含义 |
ansible_host | ansible连接节点时的IP地址 |
ansible_port | 连接对方的端口号,ssh连接时默认为22 |
ansible_user | 连接对方主机时使用的主机名。不指定时,将使用执行ansible或ansible-playbook命令的用户 |
ansible_password | 连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效 |
ansible_ssh_private_key_file | 指定密钥认证ssh连接时的私钥文件 |
ansible_ssh_common_args | 提供给ssh、sftp、scp命令的额外参数 |
ansible_become | 允许进行权限提升 |
ansible_become_method | 指定提升权限的方式,例如可使用sudo/su/runas等方式 |
ansible_become_user | 提升为哪个用户的权限,默认提升为root |
ansible_become_password | 提升为指定用户权限时的密码 |
1.2 主机变量使用
写法1:
[webservers]
192.168.44.60 ansible_port=22 ansible_user=root ansible_password=123
192.168.44.40 ansible_port=22 ansible_user=root ansible_password=123
#webservers组中被控制端192.168.44.60的端口号为22登录时用户是root密码为123
写法2:
[webservers]
192.168.44.1[1:2] ansible_port=22 ansible_user=root ansible_password=123
#如果是名称类似的主机,可以使用列表的方式标识各个主机
写法3:
[webservers]
192.168.44.60:22
192.168.44.40:1314
#默认ssh管理时的端口为22,若不是22则直接在被管理ip后加冒号和对应端口号
登录测试:
1.3 组变量使用
[webservers:vars]
ansible_user=root
ansible_password=123
#表示webservers 组内所有主机定义变量控制时使用root账户密码为123
ansible_port=1314[all:vars]
ansible_port=22
#表示为所有组的所有主机定义变量使用ssh远程管理时都是22端口
测试:
1.4 组嵌套使用
#webservers组
[webservers]
192.168.44.60
192.168.44.40#dbservers组
[dbservers]
192.168.44.50#组内嵌为onlys
[onlys:children]
webservers
dbservers
#表示onlys组的成员即children包括 webservers和dbservers
二. playbook 剧本
1. playbook 的相关知识
1.1 playbook 的简介
playbook 是 一个不同于使用 Ansible 命令行执行方式的模式,其功能更强大灵活。简单来说,playbook 是一个非常简单的配置管理和多主机部署系统,不同于任何已经存在的模式,可作为一个适合部署复杂应用程序的基础。Playbook 可以定制配置,可以按照指定的操作步骤有序执行,支持同步和异步方式。我们完成一个任务,例如安装部署一个httpd服务,我们需要多个模块(一个模块也可以称之为 task)提供功能来完成。而 playbook 就是组织多个 task 的容器,他的实质就是一个文件,有着特定的组织格式,它采用的语法格式是 YAML(Yet Another Markup Language)。
1.2 playbook 的各部分组成
- Tasks:任务,即通过 task 调用 ansible 的模板将多个操作组织在一个 playbook 中运行
- Variables:变量
- Templates:模板
- Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
- Roles:角色
模板样式:
1.3 特点与优势
-
声明式:用户只需描述期望的系统状态,而非具体的操作步骤,Ansible 负责确定如何达到这一状态。
-
幂等性:Playbook 设计为可重复执行,即使在系统已处于预期状态时,再次运行也不会产生副作用。
-
可读性强:YAML 格式和简洁的结构使得Playbook易于编写和维护。
-
模块丰富:Ansible 提供了大量的模块,覆盖了从系统配置到云资源管理的广泛需求。
-
跨平台:支持多种操作系统和环境,适配不同的自动化需求。
2. 基础的playbook剧本编写实例
playbook 中运用的模块就是 ansible 中的模块,就像 docker-compose 一样将 docker 操作容器的指令归纳为一个 yaml 文件,开启运行 yaml 中的指令模块就能按照预设计的方向去完成。
2.1 playbook 编写 apache 的 yum 安装部署剧本
模板格式:
--- #yaml文件以---开头,以表明这是一个yaml文件,可省略
- name: first play #定义一个play的名称,可省略gather_facts: false #设置不进行facts信息收集,这可以加快执行速度,可省略hosts: webservers #指定要执行任务的被管理主机组,如多个主机组用冒号分隔remote_user: root #指定被管理主机上执行任务的用户tasks: #定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行- name: test connection #自定义任务名称ping: #使用 module: [options] 格式来定义一个任务- name: disable selinuxcommand: '/sbin/setenforce 0' #command模块和shell模块无需使用key=value格式ignore_errors: True #如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务- name: disable firewalldservice: name=firewalld state=stopped #使用 module: options 格式来定义任务,option使用key=value格式- name: install httpdyum: name=httpd state=latest- name: install configuration file for httpdcopy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf #这里需要一个事先准备好的/opt/httpd.conf文件notify: "restart httpd" #如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作- name: start httpd serviceservice: enabled=true name=httpd state=startedhandlers: #handlers中定义的就是任务,此处handlers中的任务使用的是service模块- name: restart httpd #notify和handlers中任务的名称必须一致service: name=httpd state=restarted
##Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
剧本编写实现的需求:对 Ansible 管理的所有的 webservers 组的成员,yum 安装最新版本的apache 服务软件,并进行相应环境的调整,确保 webservers 的 apache 服务能够正常运行并设置开机自启
---
- name: install httpdgather_facts: falsehosts: webserversremote_user: roottasks:- name: connection ceshiping:- name: disable firewalldservice: name=firewalld state=stopped- name: install apacheyum: name=httpd state=latest- name: install config filecopy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.confnotify: "restart httpd"- name: start httpd serviceservice: enabled=true name=httpd state=startedhandlers:- name: restart httpdservice: name=httpd state=restarted
//运行playbook
ansible-playbook ceshi1.yaml//补充参数:
-k(–ask-pass):用来交互输入ssh密码
-K(-ask-become-pass):用来交互输入sudo密码
-u:指定用户
ansible-playbook ceshi1.yaml --syntax-check #检查yaml文件的语法是否正确
ansible-playbook ceshi1.yaml --list-task #检查tasks任务
ansible-playbook ceshi1.yaml --list-hosts #检查生效的主机
ansible-playbook ceshi1.yaml --start-at-task='install httpd' #指定从某个task开始运行
测试看看
2.2 playbook 编写 nginx 的 yum 安装并且能修改其监听端口的剧本
需求:通过 yum 安装 nginx 服务,并且能够控制被管理的主机的服务的开启,按照预设的配置在运行时的端口。
在编写剧本前,需要准备相应的两个文件,一个为nginx的yum源。一个为相对应的主配置文件,在主配置文件中修改其端口,在将该配置移至被管理主机中,作为运行启动时的默认配置
剧本编写:
mkdir /etc/ansible/nginxvim nginx.yaml
---
- name: nginx scriptgather_facts: falsehosts: webserversremote_user: roottasks:- name: test connectionping:- name: stop firewalldservice: name=firewalld state=stopped enabled=no- name: stop selinuxcommand: '/usr/sbin/setenforce 0'ignore_errors: true- name: prepare nginx repocopy: src=/etc/ansible/nginx/nginx.repo dest=/etc/yum.repos.d/nginx.repo- name: install nginxyum: name=nginx state=latest- name: change portcopy: src=/opt/default.conf dest=/etc/nginx/conf.d/default.confnotify: "restart nginx"- name: start nginxservice: name=nginx state=started enabled=yeshandlers:- name: restart nginxservice: name=nginx state=restarted
然后运行剧本
再去查看
3. playbook 的定义、引用变量
3.1 基础变量的定义与引用
3.1.1 创建文件
在yaml文件中,我们可以在初始配置的模块中用var去定义变量的存在,变量的格式为 key:value ,以此来确定该变量在剧本中的存在
vim test1.yaml
---
- name: this is a play for testing variableshosts: dbserversremote_user: rootvars:filename: abc.txttasks:- name: touch a test filefile: path=/opt/{{filename}} state=touchansible-playbook test1.yaml
3.1.2 引用 fact 信息中的变量
首先我们知道 使用 ansible 组 -m setup 可以收集该组中所有的节点信息 ,
所以 setup 中 fact 信息,有时候会剧本编写中需要,而 fact 的信息也是可以通过变量的方式进行调用
剧本编写:
---
- name: this is a playbook for quote variatehosts: dbserversremote_user: roottasks:- name: reading setup fact variatedebug: msg={{ansible_date_time.weekday}}
3.1.3 综合使用
查看:
ansible-playbook test3.yaml -e "username=nginx1"
#在定义行定义变量
3.1.4 指定远程主机sudo切换用户
先在那台机器上创建 zhangsan
报错:
要给zhangsan权限
联通了
编写剧本
执行剧本
查看测试结果
4. when 条件判断
在 Ansible 中,提供的唯一一个通用的条件判断是 when 指令,当 when 指令的值为 true 时,则该任务执行,否则不执行该任务。
编写剧本
在一组名为dbservers
的主机上执行重启操作
执行剧本
成功了 目标主机立即关机重启了
修改剧本,更换地址
执行剧本 由于地址与目标组不一样,跳过了
除此之外 when条件还可以通过 !=(不等于条件来进行判断)
5. 迭代
5.1 with_item 单循环输出
Ansible 提供了很多种循环结构,一般都命名为 with_items,作用等同于 loop 循环。
编写剧本
---
- name: dd1hosts: webserverstasks:- name: create dirfile: path={{item}} state=directorywith_items:- /opt/x1- /opt/x2- /home/x3
运行剧本
去查看
编写剧本
---
- name: dd2hosts: webserversgather_facts: falsetasks:- name: create dirfile:path: "{{item}}"state: directorywith_items:- /tmp/test1- /tmp/test2- name: add usersuser: name={{item.name}} state=present groups={{item.groups}}with_items:- name: test1groups: wheel- name: test2groups: root
运行剧本
5.2 with_list 每组列表一起循环的输出
---
- name: item testhosts: dbserversremote_user: rootgather_facts: notasks:- debug:msg: "{{item}}"with_list:- [a, b, c, d]- [1 ,2, 3, 4]
5.3 with_together 同一列表位置数据组合输出的循环
---
- name: item testhosts: dbserversremote_user: rootgather_facts: notasks:- debug:msg: "{{item}}"with_together:- [a, b, c, d]- [1 ,2, 3, 4]
---
- name: item testhosts: dbserversremote_user: rootgather_facts: notasks:- debug:msg: "{{item}}"with_together:- [a, b, c, d]- [1 ,2, 3, 4]- [A, B, C]
5.4 with_nested 列表数据循环匹配的循环
(根据列表个数定义有多少层的循环)
---
- name: item testhosts: dbserversremote_user: rootgather_facts: notasks:- debug:msg: "{{item}}"with_nested:- [a, b, c, d]- [1 ,2, 3, 4]
四种迭代循环方式的总结:
with_items: {{item}}会把所有的列表展开进行遍历输出,with_flattened也可以替代with_items
with_list: {{item}}会把每个列表当作一个整体输出。如果每个列表中只有一个值,则效果与with items一致。loop也可以替代ith
with_together: {{item}}引用时会把每个列表相同位置的值对齐合并后输出
with nested:{ {item}}引用时会把每个列表的值两两组合循环输出
6. Templates 模块
Jinja 是基于 Python 的模板引擎。Template 类是 Jinja 的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递 Python 的变量给模板去替换模板中的标记。
本次我们以改变 apache 的配置文件为例,来展现 Templates 模块的运用
先准备一个以 .j2 为后缀的 template 模板文件,设置引用的变量
#如果没有相关的httpd的配置文件,可以先yum按住一个httpd的服务,取其主配置文件
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2vim /opt/httpd.conf.j2
Listen {{http_port}} #42行,修改
ServerName {{server_name}} #95行,修改
DocumentRoot "{{root_dir}}" #119行,修改
这边路径可以不改 改的话就这么改 懒得改了
修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量
vim /etc/ansible/hosts
[webservers]
192.168.44.60 http_port=8080 server_name=www.test1.com:8080 [dbservers]
192.168.44.50 http_port=8081 server_name=www.test2.com:8081
如果没有做DNS解析域名,还需要对主机名进行映射 :
vim /etc/hosts192.168.44.60 www.test1.com
192.168.44.50 www.test2.com
编写 playbook
mkdir /etc/ansible/templates
vim apache.yaml
---
- hosts: allremote_user: rootvars:- package: httpd- service: httpdtasks:- name: install httpd packageyum: name={{package}} state=latest- name: install configure filetemplate: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.confnotify:- restart httpd- name: create root dirfile: path=/etc/httpd/htdocs state=directory- name: start httpd serverservice: name={{service}} enabled=true state=startedhandlers:- name: restart httpdservice: name={{service}} state=restartedansiable-playbook apache.yaml
运行剧本
查看客户机的配置是否更改,并测试能否正常访问
7. Tags
可以在一个 playbook 中为某个或某些任务定义“标签”,在执行此 playbook 时通过 ansible-playbook 命令使用 --tags 选项能实现仅运行指定的 tasks。
playbook 还提供了一个特殊的 tags 为 always。作用就是当使用 always 作为 tags 的 task 时,无论执行哪一个 tags 时,定义有 always 的 tags 都会执行。
7.1 单标签的使用
vim test1.yaml
---
- name: this is a play for testing variableshosts: webserversremote_user: roottasks:- name: position 1debug:msg: 'ls /opt'tags:- only- name: position 2debug:msg: 'ls /mnt'ansible-playbook test1.yaml --tags="only"
7.2 多标签的使用
---
- name: this is a play for testing variableshosts: webserversremote_user: roottasks:- name: position 1debug:msg: '测试标签1'tags:- one- name: position 2debug:msg: '测试标签2'tags:- two- name: position 3debug:msg: '测试标签3'tags:- one
7.3 通用标签 always 的运用
---
- name: this is a play for testing variableshosts: dbserversremote_user: roottasks:- name: position 1debug:msg: '测试标签1'tags:- one #可自定义- name: position 2debug:msg: '测试通用标签always'tags:- always #表示始终要运行的代码- name: position 3debug:msg: '测试标签3'tags:- one
顺序是从上往下执行
8. roles
简述 ansible 角色:
数据中心有各种不同类型的主机。如web服务器、数据库服务器,基于开发环境的服务器。随着时间的推移,具有处理所有这些情况的任务和人员的Ansible playbook将变得庞大而复杂。
- 角色允许将复杂的剧本组织成独立的、更小的剧本和文件,
- 角色提供了一种从外部文件加载任务、处理程序和变量的方法,
- 角色也可关联和引用静态的文件和模板。
- 角色可以编写成满足普通用途需求,并且能被重复利用。
- 定义角色的文件具有特定的名称,并以严格的目录结构进行组织。
- Roles 又称为角色,playbook 被称为剧本。Roles 角色是自1.2版本之后引入的新特性,用于层次性、结构化的组织剧本
- roles 能够根据层次型结构自动装载变量文件、任务集、以及触发的动作等,要使用 roles 只需要在剧本中使用 include 命令引入即可
- 简单的来说,roles 就是分别将变量、文件、任务、模板以及处理器放置于不同的单独的目录,并且可以便捷的通过 include 引入
- 角色一般用于基于主机构建的服务的场景中,但是也可以是用于构建守护进程等场景中,主要是使用在代码复用度较高的场景下
roles 内各目录含义解释:
- files
- 用来存放由 copy 模块或 script 模块调用的文件。
- templates
- 用来存放 jinjia2 模板,template 模块会自动在此目录中寻找 jinjia2 模板文件。
- tasks
- 此目录应当包含一个 main.yml 文件,用于定义此角色的任务列表,此文件可以使用 include 包含其它的位于此目录的 task 文件。
- handlers
- 此目录应当包含一个 main.yml 文件,用于定义此角色中触发条件时执行的动作。
- vars
- 此目录应当包含一个 main.yml 文件,用于定义此角色用到的变量。
- defaults
- 此目录应当包含一个 main.yml 文件,用于为当前角色设定默认变量。
- meta
- 此目录应当包含一个 main.yml 文件,用于定义此角色的特殊设定及其依赖关系。
roles 的步骤:
在一个 playbook 中使用 roles 的步骤:
(1)创建以 roles 命名的目录
mkdir /etc/ansible/roles/ -p #yum装完默认就有(2)创建全局变量目录(可选)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意(3)在 roles 目录中分别创建以各角色名称命令的目录,如 httpd、mysql
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql(4)在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta}(5)在每个角色的 handlers、tasks、meta、defaults、vars 目录下创建 main.yml 文件,千万不能自定义文件名
touch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml(6)修改 site.yml 文件,针对不同主机去调用不同的角色
vim /etc/ansible/site.yml
---
- hosts: webserversremote_user: rootroles:- httpd
- hosts: dbserversremote_user: rootroles:- mysql(7)运行 ansible-playbook
cd /etc/ansible
ansible-playbook site.yml
9. 操作:搭建 LAMP
mkdir /etc/ansible/roles/httpd/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks,handlers,vars,defaults,meta} -p
mkdir /etc/ansible/roles/php/{files,templates,tasks,handlers,vars,defaults,meta} -ptouch /etc/ansible/roles/httpd/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta,handlers}/main.yml
touch /etc/ansible/roles/php/{defaults,vars,tasks,meta,handlers}/main.yml------编写httpd模块------
写一个简单的tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apacheyum: name={{pkg}} state=latest
- name: start apacheservice: enabled=true name={{svc}} state=started//定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd-------编写mysql模块-------
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysqlyum: name={{pkg}} state=latest
- name: start mysqlservice: enabled=true name={{svc}} state=startedvim /etc/ansible/roles/mysql/vars/main.yml
pkg:- mariadb- mariadb-server
svc: mariadb-------编写php模块-----
vim /etc/ansible/roles/php/tasks/main.yml
- name: install phpyum: name={{pkg}} state=latest
- name: start php-fpmservice: enabled=true name={{svc}} state=startedvim /etc/ansible/roles/php/vars/main.yml
pkg:- php- php-fpm
svc: php-fpm-----编写roles示例-----
vim /etc/ansible/site.yml
---
- hosts: webserversremote_user: rootroles:- httpd- mysql- phpcd /etc/ansible
ansible-playbook site.yml
编写 httpd 模块
写一个简单的tasks/main.yml
vim /etc/ansible/roles/httpd/tasks/main.yml
- name: install apacheyum: name={{pkg}} state=latest
- name: start apacheservice: enabled=true name={{svc}} state=started//定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
编写 mysql 模块
vim /etc/ansible/roles/mysql/tasks/main.yml
- name: install mysqlyum: name={{pkg}} state=latest
- name: start mysqlservice: enabled=true name={{svc}} state=startedvim /etc/ansible/roles/mysql/vars/main.yml
pkg:- mariadb- mariadb-server
svc: mariadb
编写php模块
vim /etc/ansible/roles/php/tasks/main.yml
- name: install phpyum: name={{pkg}} state=latest
- name: start php-fpmservice: enabled=true name={{svc}} state=startedvim /etc/ansible/roles/php/vars/main.yml
pkg:- php- php-fpm
svc: php-fpm
编写roles示例
vim /etc/ansible/site.yml
---
- hosts: webserversremote_user: rootroles:- httpd- mysql- php
cd /etc/ansible
ansible-playbook site.yml