第三十八天:Ansible playbook--Role角色
角色是ansible自1.2版本引入的新特性,用于层次性、结构化地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即
可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进
程等场景中
运维复杂的场景:建议使用 roles,代码复用度高
roles:多个角色的集合目录, 可以将多个的role,分别放至roles目录下的独立子目录中,如下示例
roles/ mysql/ nginx/ tomcat/ redis/
默认roles存放路径
/root/.ansible/roles /usr/share/ansible/roles /etc/ansible/roles
官方文档:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_reuse_roles.html
一、Ansible Roles目录编排
roles目录结构如下所示
每个角色,以特定的层级目录结构进行组织
roles目录结构:
playbook1.yml playbook2.yml roles/ project1/ tasks/ files/ vars/ templates/ handlers/ default/ meta/ project2/ tasks/ files/ vars/ templates/ handlers/ default/ meta/
Roles各目录作用
roles/project/ :项目名称,有以下子目录
files/ :存放由copy或script模块等调用的文件
templates/:template模块查找所需要模板文件的目录
tasks/:定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其它的文件需要在此文件中通过include进行包含
handlers/:至少应该包含一个名为main.yml的文件;此目录下的其它的文件需要在此文件中通过include进行包含
vars/:定义变量,至少应该包含一个名为main.yml的文件;此目录下的其它的变量文件需要在此文件中通过include进行包含,也可以通过项目目录中的group_vars/all定义变量,从而实现角色通用
代码和项目数据的分离
meta/:定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main.yml的文件,其它文件需在此文件中通过include进行包含
default/:设定默认变量时使用此目录中的main.yyml文件,比vars的优先级低
二、创建 role
步骤
1 创建role的目录结构.在以roles命名的目录下分别创建以各角色名称命名的目录,如mysql等,在每个角 色命名的目录中分别创建相关的目录和文件,比如tasks、files、handlers、templates和vars等目录; 用不到的目录可以创建为空目录,也可以不创建 2 编写和准备指定role的功能文件,包括: tasks,templates,vars等相关文件 3 编写playbook文件调用上面定义的role,应用到指定的主机
针对大型项目使用Roles进行编排
范例: 利用 ansible-galaxy 创建角色目录的结构
#创建初始化目录结构 [root@ansible roles]#ansible-galaxy role init test_role - Role test_role was created successfully [root@ansible roles]#tree test_role/ test_role/ ├── defaults │ └── main.yml ├── files ├── handlers │ └── main.yml ├── meta │ └── main.yml ├── README.md ├── tasks │ └── main.yml ├── templates ├── tests │ ├── inventory │ └── test.yml └── vars └── main.yml 8 directories, 8 files
三、Playbook 调用角色
调用角色方法1:
--- - hosts: websrvs remote_user: root roles: - mysql - memcached - nginx
调用角色方法2:
键role用于指定角色名称,后续的k/v用于传递变量给角色
--- - hosts: all remote_user: root roles: - role: mysql username: mysql - { role: nginx, username: nginx }
调用角色方法3:
还可基于条件测试实现角色调用
--- - hosts: all remote_user: root roles: - { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' }
四、Roles 中 Tags 使用
[root@ansible ~]#vi app-role.yml --- #可以有多个play - hosts: lbserver roles: - role: haproxy - role: keepalived - hosts: appsrvs remote_user: root roles: - { role: nginx ,tags: [ 'nginx', 'web' ] ,when: ansible_distribution_major_version == "6" } - { role: httpd ,tags: [ 'httpd', 'web' ] } - { role: mysql ,tags: [ 'mysql', 'db' ] } - role: mariadb tags: - mariadb - db tags: app #play的tag [root@ansible ~]#ansible-playbook --tags="nginx,mysql" app-role.yml
五、实战案例
1、实现 Httpd 角色
#创建角色相关的目录 [root@ansible ~]#mkdir -pv /data/ansible/roles/httpd/{tasks,handlers,files} #创建角色相关的文件 [root@ansible ~]#cd /data/ansible/roles/httpd/ #main.yml 是task的入口文件 [root@ansible ~]#vim tasks/main.yml - include: group.yml - include: user.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible ~]#vim tasks/group.yml - name: create apache group group: name=apache system=yes gid=80 [root@ansible ~]#vim tasks/user.yml - name: create apache user user: name=apache system=yes shell=/sbin/nologin home=/var/www/ uid=80 group=apache [root@ansible ~]#vim tasks/install.yml - name: install httpd package yum: name=httpd #注意: 文件是放在files目录下,但src的路径无需写files目录名 [root@ansible ~]#vim tasks/config.yml - name: config file copy: src=httpd.conf dest=/etc/httpd/conf/ backup=yes notify: restart [root@ansible ~]# tasks/index.yml - name: index.html copy: src=index.html dest=/var/www/html/ [root@ansible ~]#vim tasks/service.yml - name: start service service: name=httpd state=started enabled=yes [root@ansible ~]#vim handlers/main.yml - name: restart service: name=httpd state=restarted #在files目录下准备两个文件 [root@ansible ~]#ls files/ httpd.conf index.html #在playbook中调用角色 [root@ansible ~]#vim /data/ansible/role_httpd.yml --- # httpd role - hosts: websrvs remote_user: root roles: - httpd #运行playbook [root@ansible ~]#ansible-playbook /data/ansible/role_httpd.yml
2、实现 Nginx 角色
[root@ansible ~]#mkdir -pv /data/ansible/roles/nginx/{tasks,handlers,templates,vars} #创建task文件 [root@ansible ~]#cd /data/ansible/roles/nginx/ [root@ansible nginx]#vim tasks/main.yml - include: install.yml - include: config.yml - include: index.yml - include: service.yml [root@ansible nginx]#vim tasks/install.yml - name: install yum: name=nginx [root@ansible nginx]#vim tasks/config.yml - name: config file for centos7 template: src=nginx7.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="7" notify: restart - name: config file for centos8 template: src=nginx8.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution_major_version=="8" notify: restart #跨角色调用文件 [root@ansible nginx]#vim tasks/index.yml - name: index.html copy: src=roles/httpd/files/index.html dest=/usr/share/nginx/html/ [root@ansible nginx]#vim tasks/service.yml - name: start service service: name=nginx state=started enabled=yes #创建handler文件 [root@ansible nginx]#cat handlers/main.yml - name: restart service: name=nginx state=restarted #创建两个template文件 [root@ansible nginx]#cat templates/nginx7.conf.j2 ...省略... user {{user}}; worker_processes {{ansible_processor_vcpus+3}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; ...省略... [root@ansible nginx]#cat templates/nginx8.conf.j2 ...省略... user {{user}}; worker_processes {{ansible_processor_vcpus**3}}; #修改此行 error_log /var/log/nginx/error.log; pid /run/nginx.pid; ...省略... #创建变量文件 [root@ansible nginx]#vim vars/main.yml user: daemon #在playbook中调用角色 [root@ansible ~]#vim /data/ansible/role_nginx.yml --- #nginx role - hosts: websrvs roles: - role: nginx #运行playbook [root@ansible ~]#ansible-playbook /data/ansible/role_nginx.yml
3、实现 Memcached 角色
[root@ansible ~]#mkdir -pv /data/ansible/roles/memcached/{tasks,templates} [root@ansible ~]#cd /data/ansible/roles/memcached [root@ansible memcached]#vim tasks/main.yml - include: install.yml - include: config.yml - include: service.yml [root@ansible memcached]#vim tasks/install.yml - name: install yum: name=memcached [root@ansible memcached]#vim tasks/config.yml - name: config file template: src=memcached.j2 dest=/etc/sysconfig/memcached [root@ansible memcached]#vim tasks/service.yml - name: service service: name=memcached state=started enabled=yes [root@ansible memcached]#vim templates/memcached.j2 PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="{{ansible_memtotal_mb//4}}" OPTIONS="" [root@ansible ~]#vim /data/ansible/role_memcached.yml --- - hosts: appsrvs roles: - role: memcached [root@ansible ~]#ansible-play /data/ansible/role_memcached.yml
4、调用变量
[root@ansible ~]#vim /data/ansible/roles/test_role/tasks/main.yml - name: Include OS-specific variables include_vars: {{ ansible_os_family}}.yml .... [root@ansible ~]#ls /data/ansible/roles/test_role/vars/ Archlinux.yml Debian.yml FreeBSD.yml OpenBSD.ymL RedHat.yml
5、实现多角色的选择
[root@ansible ~]#vim /data/ansible/role_httpd_nginx.yml --- - hosts: websrvs roles: - {role: httpd,tags: [httpd,web], when: ansible_distribution_major_version=="7" } - {role: nginx,tags: [nginx,web], when: ansible_distribution_major_version=="8" } [root@ansible ~]#ansible-playbook -t nginx /data/ansible/role_httpd_nginx.yml
6、依赖其它角色
[root@ansible roles]#vim wordpress/meta/main.yml dependencies: - role: nginx - role: php-fpm - role: mysql
7、实现 NFS 服务
[root@ansible ~]#cat /data/ansible/roles/nfs-server/tasks/main.yml - name: Configre NFS Server template: src: exports.j2 dest: /etc/exports owner: root group: root mode: '0644' notify: Restart NFS Server - name: Create NFS dir file: path: "{{ item }}" state: directory owner: "{{ all_user }}" group: "{{ all_group }}" mode: '0755' recurse: yes loop: - "{{ nfs_share_blog }}" - "{{ nfs_share_zrlog }}" - name: Start NFS Server systemd: name: nfs state: started [root@ansible ~]#cat /data/ansible/roles/nfs-server/handlers/main.yml - name: Restart NFS Server systemd: name: nfs state: restarted [root@ansible ~]#cat /data/ansible/roles/nfs-server/templates/exports.j2 {{ nfs_share_blog }} {{ nfs_allow_ip }}(rw,all_squash,anonuid={{ all_uid }},anongid={{ all_gid }}) {{ nfs_share_zrlog }} {{ nfs_allow_ip }}(rw,all_squash,anonuid={{ all_uid }},anongid={{ all_gid }}) [root@ansible ~]#cat /data/ansible/roles/group_vars/all nfs_share_blog: /data/blog nfs_share_zrlog: /data/zrlog nfs_allow_ip: 10.0.0.0/24
8、实现 Redis 服务
[root@ansible ~]#cat /data/ansible/roles/redis/tasks/main.yml - name: Installed Redis Server yum: name: redis state: present - name: Configure Redis Server template: src: redis.conf.j2 dest: /etc/redis.conf owner: redis group: root mode: '0640' notify: Restart Redis Server - name: Start Redis Server systemd: name: redis state: started enabled: yes [root@ansible ~]#cat /data/ansible/roles/redis/templates/redis.conf.j2 bind 127.0.0.1 {{ ansible_eth0.ipv4.address }} [root@ansible ~]#cat /data/ansible/roles/redis/handlers/main.yml - name: Restart Redis Server systemd: name: redis state: restarted
9、实现 Nginx 服务
[root@ansible ~]#cat /data/ansible/roles/nginx/tasks/main.yml - name: Install Nginx Server yum: name: nginx enablerepo: nginx state: present - name: Configure Nginx nginx.conf template: src: nginx.conf.j2 dest: "{{ nginx_conf_path }}" notify: Restart Nginx Server - name: Start Nginx Server systemd: name: nginx state: started enabled: yes [root@ansible ~]#cat /data/ansible/roles/nginx/handlers/main.yml - name: Restart Nginx Server systemd: name: nginx state: restarted [root@ansible ~]#cat /data/ansible/roles/nginx/templates/nginx.conf.j2 user {{ all_user }}; worker_processes {{ ansible_processor_vcpus }} ; events { workder_connections {{ ansible_processor_vcpus *10240 }}; } http { include {{ nginx_include_path }}; } [root@ansible ~]#cat /data/ansible/roles/group_vars/all # nginx nginx_conf_path: /etc/nginx/nginx.conf nginx_include_dir: /etc/nginx/conf.d nginx_include_path: /etc/nginx/conf.d/*.conf
六、Ansible Tower 介绍
公司中实现运维自动化的架构中主要用到ansible,但是ansible脚本在部署服务器指令行中显得不太直观
Ansible Tower (最早以前叫’AWX’)是能够帮助IT团队更容易使用Ansible的解决方案。
Ansible Tower是一个图形化基于WEB的任务调度,复杂服务部署,IT自动化的一个管理平台,属于发布配置管理系统,支持Api及界面操作,基于Django编写
Tower允许对用户进行权限控制,即使某用户不能传送某SSH凭证,你也可以通过Tower来对该用户共享该凭证。我们可以通过图形化界面来管理 Inventory,也可以对各种各样的云资源做同步。Tower可以记录所有job的日志,也可以与LDAP集成,并且拥有强大的可浏览的REST API。Tower也提供了命令
行工具,可以与Jenkins轻松集成。Provisioning回调对自动伸缩拓扑图提供了强大的支持。
可以在 Ansible Tower 页面 <http://ansible.com/tower> _了解Tower更多的功能,并且了解如何下载使用。Tower的免费版本最多支持10个节点,并且Ansible公司会提供强大的支持。可以支持用Ansible playbook来安装Tower
七、Ansible 推荐学习资料
http://galaxy.ansible.com https://galaxy.ansible.com/explore#/ http://github.com/ http://ansible.com.cn/ https://github.com/ansible/ansible https://github.com/ansible/ansible-examples