目录
1、概念介绍
roles 角色
playbook 核心元素
ansible-playbook 命令
playbook 简单案例
2、Ansible 变量
自定义变量
facts 变量
Palybook 部署 LAMP
ansible 端安装 LAMP
playbook 系统环境脚本
构建 httpd 任务
构建 mariadb 任务
构建 php 任务
编写整个任务入口文件
1、概念介绍
Ansible Playbooks 提供了一个可重复、可重用、简单的配置管理和多机部署系统,非常适合部署复杂的应用程序。当你需要反复执行或要执行多个 task 时,可以将这些 task 编写入 playbook,然后用 playbook 推送给在 inventory 中定义好的一组服务器执行。
playbook 以 YAML 格式表示。一个 playbook 由一个或多个 play 组成,一个 play 中
包含一个或多个 task,一个 task 对应一个 module。 playbook 按从上到下的顺序运行。在每个 play 中,tasks 也按从上到下的顺序运行。
roles 角色
当我们刚开始学习运用 playbook 时,因为操作很多,所以很可能会把 playbook 写成一个很大的文件,慢慢你会发现,playbook 的内容较为混乱,难以管理。Roles 相当于我们剧本当中的角色,把不同的任务分配给不同的角色,可以使大型项目易管理,当需要做不同的事情时,只需要调用不同角色即可。
把不同功能的 playbook 分开,一个标准的角色含有下列子目录:
角色子目录 | 说明 |
defaults | 其中的 main.yml 包含角色变量的默认值,在所有变量中优先级最低 |
files | 包含角色任务引用的静态文件 |
handlers | 主要定义处理程序 |
meta | 角色相关信息,如作者、许可证等 |
tasks | 定义任务 |
templates | 任务引用的 jinja2 模板 |
tests | 可以包含清单和 test.yml 的 playbook,用于测试 |
vars | 定义角色的变量 |
playbook 核心元素
① target:定义 PlayBook 的远程主机组
target 常用参数 | 说明 |
hosts | 运行指定任务的目标主机,可以是一个主机组、主机、多个主机,中间以冒号分隔,也可以用 all 参数表示所有主机。 |
remote_user | 指定远程主机上的执行任务的用户。 |
gather_facks | 获取远程主机 facts 基础信息。注:gather_facts: True 表示在远程主机运行 setup 模块,获取远程主机的 facts,facts 就是变量,内建变量 。每个主机的各种信息,cpu 颗数、内存大小等,会存在 facts 中的某个变量中,调用后返回很多对应主机的信息。 |
② variables:定义 PlayBook 使用的变量
variables 常用参数 | 说明 |
vars | 在 yaml 文件中定义变量赋值。定义格式,变量名:变量值 |
vars_files | 指定变量文件,在文件中定义变量 |
③ tasks:定义远程主机上执行的任务列表
tasks 常用参数 | 说明 |
name | 任务显示名称也是屏幕显示信息 |
module_name | module_args: 需要使用的模块名字: 模块参数 |
关于 task 说明:
- Play 的主体部分是 task 列表,task 列表中的各任务按次序逐个在 hosts 中指定的主机上执行
- 在运行 playbook 时(从上到下执行),如果一个 host 执行 task 失败,整个 tasks都会回滚,请修正 playbook 中的错误,然后重新执行即可。
- 每一个 task 必须有一个名称 name,这样在运行 playbook 时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个 task 的。
- 定义一个 task,常见的格式:” module_name: module_args” 例如:yum: name=httpd state=absent update_cache=yes
- ansible 的自带模块中,command 模块和 shell 模块无需使用 key=value 格式
④ handlers:处理器,当某条件满足时,触发执行的操作。例如修改配置文件之后,启动跟 handlers 任务重启相关联的服务 。
handler 常用参数 | 说明 |
notify | notify”这个 action 可用于在每个 play 的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,取而代之,仅在所有的变化发生完成后一次性地执行指定操作。 在 notify 中列出的操作称为 handler,也即 notify 中调用 handler 中定义的操作。 |
handler | 也是 task 的列表。在 notify 中列出的操作称为 handler,也即 notify 中 调用 handler 中定义的操作。 Handlers 是由通知者进行 notify, 如果没有被 notify,handlers 不会执行。 不管有多少个通知者进行了 notify,等到 play 中的所有 task 执行完成之后,handlers 也只会被执行一次。 |
⑤ roles :角色,用于层次性、结构化地组织 playbook。roles 能够根据层次型结构自动装载变量文件、tasks 以及 handlers 等。
ansible-playbook 命令
语法:ansible [选项] yaml文件
- -C, --check 只检测可能会发生的改变,但不真执行操作
- -D, --diff 更改(小)文件和模板时,显示这些文件中的差异
- --list-hosts 输出匹配主机的列表;不执行任何其他操作
- --list-tasks 列出将要执行的所有任务
- --syntax-check 对 playbook 执行语法检查,但不要执行
- -t TAGS_NAME 表示跳过标签前的步骤,直接从标签位置开始
ansible-playbook --syntax-check install.yaml
playbook 简单案例
github 上提供了大量的实例供大家参考: https://github.com/ansible/ansible-examples
vim install.yaml
---
- name: yum install packagehosts: web_serversremote_user: rootvars:name1: treetasks:- name: install lrzszcommand: yum install -y lrzsz- name: install treecommand: yum install -y {{name1}}
第一行:使用三个横杠作为开始,在 YAML 语法中,---表示文档开始。
第二行:使用- 开头(横杠后面有空格),YAML 使用"-"表示一个块序列的节点,name play 的名称
第三行:hosts 关键字对应的值为 web-servers,表示我们要在 web-servers 主机组上进行操作
第四行:使用 remote_user 关键字可以指定在进行远程操作时使用哪个用户进行操作,'remote_user: root'表示以远程主机的 root 用户进行操作, 与 hosts 关键字对齐,表示它们是平级的
第五行:vars 设置变量,格式为 key:values
第七行:tasks 任务列表,整个任务列表一共有两个任务组成,每个任务都以"- "开头,每个任务都有自己的名字,任务名使用 name 关键字进行指定,name 下是 我们执行任务的模块。变量调用使{{var}}
# 执行 playbook
ansible-playbook install.yaml
注意:Gathering Facts 任务会收集当前 play 对应的目标主机的相关信息,收集完这些基础信息后,才会执行我们指定的任务。
2、Ansible 变量
自定义变量
① 在剧本中定义变量
---
- hosts: webvars:file: /etc/hostnamedir: /roottasks:- name: print vardebug:msg: "{{ dir }}变量file的内容是{{ file }}"
注意:如果msg起始位置有变量需要使用引号。
② 在文件中定义变量
# vars-file.yml
file: /etc/hostname
dir: /root
---
- hosts: webvars_files: ./vars-file.ymltasks:- name: print vardebug:msg: "{{ dir }}变量file的内容是{{ file }}"
③ 根据主机清单分组自动识别变量
通过主机清单里面的分组进行变量的共享,eg:web服务器 port 80,data服务器 port 873
group_vars/lb/vars.yml # 存放lb组的变量web/vars.yml # 存放web组的变量data/vars.yml # 存xxx组的变量all/vars.yml # 存放所有主机共用的变量mkdir -p /etc/ansible/lamp/group_vars
cd /etc/ansible/lamp/group_vars
mkdir {lb, web, data, all}vim data_vars.yml
port: 873vim web_vars.yml
port: 80
---
- hosts: webtasks:- name: print vardebug:msg: "当前服务的端口号:{{ port }}"- hosts: datatasks:- name: print vardebug:msg: "当前服务的端口号:{{ port }}"
facts 变量
fact变量是在运行剧本的时候ansible收集的每台机器的信息
# 查看ansible facts 变量
ansible web_servers -m setup
# 编写剧本
---
- hosts:tasks: print facts vars- name: print facts varsdebug:msg: "facts变量{{ ansible_default_ipv4.addresses }}"
常用 facts 变量
- ansible_hostname 主机名
- ansible_memtotal_mb 内存大小(总计),单位mb
- ansible_processor_vcpus cpu数量
在 /etc/motd 写入主机名,ip地址,内存大小,cpu个数
#批量分发 motd 文件,文件内容根据不容机器变化
①②③④⑤
Palybook 部署 LAMP
ansible 端安装 LAMP
首先,我们可以在 ansible 服务器上安装 LAMP 环境,然后,再将配置文件通过 ansible 拷贝到远程主机上,如果有配置文件不用在管理机安装 LAMP。
① 安装软件
# ---------------------------------安装 httpd---------------------------------
yum install -y httpd
systemctl start httpd#------------------------------------ 安装 MySQL ----------------------------
yum install -y mariadb-server mariadb
# 创建数据库保存目录
mkdir -p /data/mysql/data
# 修改权限
chown -R mysql:mysql /data/mysql/
# 修改数据保存目录
vim /etc/my.cnf
datadir=/data/mysql/data# 启动服务
systemctl start mariadb# --------------------------安装 PHP 和 php-mysql 模块 --------------------------------
yum install -y php php-mysql
# 提供 php 的测试页
vim /var/www/html/index.php
<?php phpinfo();
?>
# 重启httpd 服务
systemctl restart httpd
确保已经出现上面的测试页,而且,要看到 MySQL 已经被整合进来了,才能进行下一步操作
② 配置主机 和 ssh登录
# 定义主机名
vim /etc/ansible/hosts
[web-servers]
192.168.137.105
192.168.137.106# 设置 ssh 免密连接
ssh-keygen
ssh-copy-id root@192.168.137.105
ssh-copy-id root@192.168.137.106
playbook 系统环境脚本
# 创建相关文件
mkdir -pv /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,templates,vars,meta,default,handlers}# 拷贝文件:将搭建成功的 LAMP 环境的 httpd 和 MySQL 的配置文件拷贝到对应目录下
cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
cp /etc/my.cnf lamp/roles/mysql/files/#初始化系统环境的脚本:写 prepare(上面创建好的)角色的 playbooks
vim lamp/roles/prepare/tasks/main.yml
- name: delete yum config shell: rm -rf /etc/yum.repos.d/* #删除原有的 yum 配置文件
- name: provide yumrepo file get_url: url: http://mirrors.aliyun.com/repo/Centos-6.repo dest: /etc/yum.repos.d/CentOS-Base.repo when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "6")
- name: provide yumrepo file get_url: url: http://mirrors.aliyun.com/repo/Centos-7.repo dest: /etc/yum.repos.d/CentOS-Base.repo when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == "7")
- name: clean the yum repo shell: yum clean all #清除原有的 yum 缓存信息
- name: clean the iptables shell: iptables -F #清除原有防火墙规则,不然后可能上不了网
- name: close firewalld service: name=firewalld state=stopped enabled=no
- name: close selinux template: src: config.j2 dest: /etc/selinux/config
- name: current close selinux command: setenforce 0 ignore_errors: true
[root@node_04 ansible] cp /etc/selinux/config lamp/roles/prepare/templates/config.j2
template 模块跟 copy 模块类似,指定模版文件,该文件必须存在于 prepare 角色目录下的 templates 目录中,起名需要加上.j2 结尾,将 templates 下的文件复制到对应主机的对应目录下,src 指定源文件,dest 指定目标目录及复制到目录后改成什么名字。
该模块和 copy 模块作用基本一样,都是把某个文件复制到远端主机上,但是区别在于 template 模块可以获取变量的值,而 copy 则是原封不动的把文件内容复制过去。
构建 httpd 任务
① 配置 httpd 的 tasks
cd /etc/ansible/lamp/roles
cp /var/www/html/index.php httpd/files/
vim httpd/tasks/main.yml
---
- name: web server install yum: name=httpd state=present - name: provide test page # 提供测试页copy: src=index.php dest=/var/www/html- name: delete apache config # 删除原有的 apache 配置文件,如果不删除,下面的 copy 任务是不会执行的,# 因为当源文件 httpd.conf 和目标文件一样时,copy 命令是不执行的。# 如果 copy 命令不执行,那么 notify 将不调用 handler。shell: rm -rf /etc/httpd/conf/httpd.conf - name: provide configuration file # 提供 httpd 的配置文件copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf # 当前面的 copy 复制成功后,通过 notify 通知名字为 restart httpd 的 handlers 运行。notify: restart httpd
② 构建 httpd 的 handlers
vim httpd/handlers/main.yml
- name: restart httpd service: name=httpd enabled=yes state=restarted
构建 mariadb 任务
创建 MySQL 服务的任务,需要安装 MySQL 服务,改变属主信息,启动 MySQL
vim /etc/ansible/lamp/roles/mysql/tasks/main.yml
---# 安装 mysql 服务
- name: install the mysql yum: name: ['mariadb-server', 'mariadb','MySQL-python'] state: present # 创建数据挂载点目录
- name: mkdir data directory shell: mkdir -p /data/mysql/data# 提供 mysql 的配置文件
- name: provide configration file copy: src=my.cnf dest=/etc/my.cnf # 更改属主和属组
- name: chage the owner shell: chown -R mysql:mysql /data/mysql# 启动 mysql 服务
- name: start mariadb service: name=mariadb enabled=yes state=started- name: set root passwd shell: /usr/bin/mysqladmin -uroot password '123456' | /bin/true- name: create a database mysql_db: login_host: localhost login_user: root login_password: "123456" login_port: 3306 name: test encoding: utf8 state: present - name: create user mysql_user: login_host: localhost login_user: root login_password: "123456" login_port: 3306 name: test host: "192.168.137.%" password: "123456" priv: "test.*:ALL" state: present
构建 php 任务
vim php/tasks/main.yml
---
- name: install php yum: name=php state=present #安装 php
- name: install php-mysql yum: name=php-mysql state=present #安装 php 与 mysql 交互的插件
------------------------------------------------------------------------
# 一次安装多个软件格式:
- name: install php yum: name: ['php','php-mysql' , 'php-gd'] state: installed
编写整个任务入口文件
vim /etc/ansible/lamp/roles/site.yml
---
- name: prepare build remote_user: root hosts: web_servers # 要执行的 roles,确保 roles 目录下有同名的文件夹roles: - prepare# 给任务打标签,方便单独测试tags: prepare - name: LAMP build remote_user: root hosts: web_servers roles: - mysql tags: mysql - name: LAMP build remote_user: root hosts: web_servers roles: - php tags: php - name: LAMP build remote_user: root hosts: web_servers roles: - httpd tags: httpd
# 根据 tags 标签测试服务
ansible-playbook -C /etc/ansible/lamp/roles/site.yml -t httpd# 开始部署
ansible-playbook -i /etc/ansible/hosts /etc/ansible/lamp/roles/site.yml