88530091 2020-05-08
Ansible Roles 详解与实战案例
说明:
1、 运维人员使用的登录账号;
2、 所有的业务都放在 /app/ 下「yun用户的家目录」,避免业务数据乱放;
3、 该用户也被 ansible 使用,因为几乎所有的生产环境都是禁止 root 远程登录的(因此该 yun 用户也进行了 sudo 提权)。
# 使用一个专门的用户,避免直接使用root用户 # 添加用户、指定家目录并指定用户密码 # sudo提权 # 让其它普通用户可以进入该目录查看信息 useradd -u 1050 -d /app yun && echo ‘123456‘ | /usr/bin/passwd --stdin yun echo "yun ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers chmod 755 /app/
之后文章都是如下主机配置清单
[ ansible_info]$ pwd /app/ansible_info [ ansible_info]$ cat hosts_key # 方式1、主机 + 端口 + 密钥 [manageservers] 172.16.1.180:22 [proxyservers] 172.16.1.18[1:2]:22 # 方式2:别名 + 主机 + 端口 + 密码 [webservers] web01 ansible_ssh_host=172.16.1.183 ansible_ssh_port=22 web02 ansible_ssh_host=172.16.1.184 ansible_ssh_port=22 web03 ansible_ssh_host=172.16.1.185 ansible_ssh_port=22
前面已经学习了 变量、tasks 和 handlers,那怎样组织 playbook 才是最好的方式呢?
简单的回答就是:使用 roles。roles 基于一个已知的文件结构,去自动的加载某些 vars_files,tasks 以及 handlers。以便 playbook 更好的调用。相比 playbook,roles 的结构更加的清晰有层次。
假如:无论我们安装什么软件都会安装时间同步服务,那么每个 playbook 都要编写时间同步服务的 task。此时我们可以将时间同步服务 task 写好,等到用的时候再调用即可。
注意事项:在编写 roles 的时候,最好能够将一个 task 拆分为一个文件,方便后续复用「彻底打散」。
在 roles 目录下,可以使用如下命令创建目录
ansible-galaxy init nfs roles # 其中 nfs 为目录名称
这样创建的目录是全目录,但是我们可能只需要部分目录,因此实际应用中大多数都由我们自己创建目录,而不是用命令创建目录。
示例目录构造如下:
[ tmp]$ tree ./ ./ ├── sit.yml ├── webservers.yml └── roles └── nfs # 角色名称 ├── defaults # 角色默认变量(最低优先级) │ └── main.yml ├── files # 文件存放 ├── handlers # 触发任务 │ └── main.yml ├── meta # 依赖关系 │ └── main.yml ├── README.md # 使用说明 ├── tasks # 具体任务 │ └── main.yml ├── templates # 模板文件 └── vars # 角色其他变量 └── main.yml 10 directories, 10 files
目录说明:
1、首先要有 roles 目录,然后在 roles 目录下创建相应的目录。
2、roles 下的目录名最好见文知意,如 common 目录表示基础目录,是必要的;nfs 目录表示安装 nfs 服务;memcached 目录表示安装 memcached 服务;等等。
3、可以根据自身需要创建 roles 下的二级目录,不需要的目录可以不创建,没需要全目录创建。
4、roles 目录下的二级目录中,有些目录必须包含一个 main.yml 文件,以便 ansible 使用。
roles 允许在使用 role 时自动引入其他 role。roles 的依赖关系存储在 role 目录中的 meta/main.yml 文件中。
例如:安装 WordPress 是需要先确保 Nginx 和 PHP 都能正常运行,此时都可以在 WordPress 的 role 中定义依赖 Nginx 和 php-fpm 的 role。
[ playbook]$ cat /app/roles/wordpress/meta/main.yml --- dependencies: - { role: nginx } - { role: php-fpm }
此时 WordPress 的 role 会先执行 Nginx 的 role,然后执行 php-fpm 的 role,最后再执行 WordPress 本身的 role。
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [manager ansible_roles]$ ll total 4 drwxrwxr-x 2 yun yun 17 Sep 15 19:41 group_vars -rw-rw-r-- 1 yun yun 108 Sep 15 19:37 nfs_server.yml drwxrwxr-x 4 yun yun 35 Sep 15 18:00 roles [manager ansible_roles]$ tree # 目录结构 . ├── group_vars │ └── all ├── nfs_server.yml └── roles ├── nfs # 服务端 │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ ├── config.yml │ │ ├── install.yml │ │ ├── main.yml │ │ ├── mkdir.yml │ │ ├── start_NFS.yml │ │ └── start_rpcbind.yml │ └── templates │ └── exports.j2 └── nfs_client # 客户端 └── tasks └── main.yml 9 directories, 11 files
目录结构
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [ ansible_roles]$ tree roles/nfs roles/nfs ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── install.yml │ ├── main.yml │ ├── mkdir.yml │ ├── start_NFS.yml │ └── start_rpcbind.yml └── templates └── exports.j2 4 directories, 8 files
tasks任务目录信息
[ ansible_roles]$ cat roles/nfs/tasks/main.yml - include_tasks: install.yml - include_tasks: config.yml - include_tasks: mkdir.yml - include_tasks: start_rpcbind.yml - include_tasks: start_NFS.yml [ ansible_roles]$ cat roles/nfs/tasks/install.yml - name: "install package NFS " yum: name: - nfs-utils - rpcbind state: present [ ansible_roles]$ cat roles/nfs/tasks/config.yml - name: "NFS server config and edit restart" template: src: exports.j2 dest: /etc/exports owner: root group: root mode: ‘644‘ notify: "reload NFS server" [ ansible_roles]$ cat roles/nfs/tasks/mkdir.yml - name: "create NFS dir" file: path: /data owner: yun group: yun state: directory recurse: yes [ ansible_roles]$ cat roles/nfs/tasks/start_rpcbind.yml - name: "rpcbind server start" systemd: name: rpcbind state: started daemon_reload: yes enabled: yes [ ansible_roles]$ cat roles/nfs/tasks/start_NFS.yml - name: "NFS server start" systemd: name: nfs state: started daemon_reload: yes enabled: yes
handlers任务目录信息
[ ansible_roles]$ cat roles/nfs/handlers/main.yml - name: "reload NFS server" systemd: name: nfs state: reloaded
模板目录信息
1 [ ansible_roles]$ cat roles/nfs/templates/exports.j2 2 {{ nfs_dir }} 172.16.1.0/24(rw,sync,root_squash,all_squash,anonuid=1050,anongid=1050)
客户端就比较简单了,就一个挂载任务
[ ansible_roles]$ cat roles/nfs_client/tasks/main.yml - name: "mount NFS server" mount: src: 172.16.1.180:{{ nfs_dir }} path: /mnt fstype: nfs opts: defaults state: mounted
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [ ansible_roles]$ cat group_vars/all # NFS 服务端目录 nfs_dir: /data
[ ansible_roles]$ cat nfs_server.yml --- # NFS server - hosts: manageservers roles: - nfs - hosts: proxyservers roles: - nfs_client
1 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key --syntax-check nfs_server.yml # 语法检测 2 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key -C nfs_server.yml # 预执行,测试执行 3 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key nfs_server.yml # 执行
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [manager ansible_roles]$ ll total 8 -rw-rw-r-- 1 yun yun 71 Sep 16 09:05 memcached_server.yml drwxrwxr-x 5 yun yun 52 Sep 16 08:38 roles [ ansible_roles]$ tree roles/ roles/ └── memcached ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── install.yml │ ├── main.yml │ └── start.yml └── templates └── memcached.j2 11 directories, 15 files
目录结构
[ memcached]$ pwd /app/ansible_info/ansible_roles/roles/memcached [manager memcached]$ ll total 0 drwxrwxr-x 2 yun yun 22 Sep 16 08:56 handlers drwxrwxr-x 2 yun yun 76 Sep 16 08:53 tasks drwxrwxr-x 2 yun yun 26 Sep 16 08:55 templates [manager memcached]$ tree . ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── install.yml │ ├── main.yml │ └── start.yml └── templates └── memcached.j2 3 directories, 6 files
tasks任务目录信息
[ memcached]$ cat tasks/main.yml - include_tasks: install.yml - include_tasks: config.yml - include_tasks: start.yml [ memcached]$ cat tasks/install.yml - name: " install package memcached" yum: name: memcached state: present [ memcached]$ cat tasks/config.yml - name: "memcached server config and edit restart" template: src: memcached.j2 dest: /etc/sysconfig/memcached owner: root group: root mode: ‘644‘ notify: "restart memcached server" [ memcached]$ cat tasks/start.yml - name: "memcached server start" systemd: name: memcached state: started daemon_reload: yes enabled: yes
handlers任务目录信息
[ memcached]$ cat handlers/main.yml - name: "restart memcached server" systemd: name: memcached state: restarted
模板目录信息
[ memcached]$ cat templates/memcached.j2 PORT="11211" USER="memcached" MAXCONN="1024" CACHESIZE="{{ ansible_memtotal_mb // 2 }}" OPTIONS=""
[ ansible_roles]$ cat memcached_server.yml --- # memcached server - hosts: manageservers roles: - memcached
1 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key --syntax-check memcached_server.yml # 语法检测 2 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key -C memcached_server.yml # 预执行,测试执行 3 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key memcached_server.yml # 执行
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [manager ansible_roles]$ ll total 12 drwxrwxr-x 2 yun yun 17 Sep 29 09:33 group_vars drwxrwxr-x 7 yun yun 86 Sep 29 08:49 roles -rw-rw-r-- 1 yun yun 116 Sep 29 09:50 rsyncd_server.yml [ ansible_roles]$ tree roles/ roles/ ├── rsync_client │ ├── tasks │ │ └── main.yml │ └── templates │ └── rsync.password.j2 └── rsyncd ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── install.yml │ ├── main.yml │ ├── mkdir.yml │ └── start_rsyncd.yml └── templates ├── rsyncd.conf.j2 └── rsync.password.j2 18 directories, 25 files
目录结构
[ rsyncd]$ pwd /app/ansible_info/ansible_roles/roles/rsyncd [manager rsyncd]$ tree . ├── handlers │ └── main.yml ├── tasks │ ├── config.yml │ ├── install.yml │ ├── main.yml │ ├── mkdir.yml │ └── start_rsyncd.yml └── templates ├── rsyncd.conf.j2 └── rsync.password.j2 3 directories, 8 files
tasks任务目录信息
[ rsyncd]$ pwd /app/ansible_info/ansible_roles/roles/rsyncd [ rsyncd]$ cat tasks/main.yml - include_tasks: install.yml - include_tasks: config.yml - include_tasks: mkdir.yml - include_tasks: start_rsyncd.yml [ rsyncd]$ cat tasks/install.yml - name: "Install package rsync" yum: name: rsync state: present [ rsyncd]$ cat tasks/config.yml - name: "rsyncd server config and edit restart" template: src: rsyncd.conf.j2 dest: /etc/rsyncd.conf owner: root group: root mode: ‘644‘ notify: "restart rsyncd server" - name: "rsyncd server password file" template: src: rsync.password.j2 dest: /etc/rsync.password owner: root group: root mode: ‘400‘ [ rsyncd]$ cat tasks/mkdir.yml - name: "create rsync business backup dir" file: path: /backup/busi_data owner: root group: root state: directory recurse: yes - name: "create rsync database backup dir" file: path: /backup/database owner: root group: root state: directory recurse: yes [ rsyncd]$ cat tasks/start_rsyncd.yml - name: "rsyncd server start" systemd: name: rsyncd state: started daemon_reload: yes enabled: yes
handlers任务目录信息
[ rsyncd]$ cat handlers/main.yml - name: "restart rsyncd server" systemd: name: rsyncd state: restarted
模板目录信息
[ rsyncd]$ pwd /app/ansible_info/ansible_roles/roles/rsyncd [ rsyncd]$ cat templates/rsyncd.conf.j2 # 文件1 # 备注:更多参数与更多详解,参见 man rsyncd.conf #rsync_config---------------start uid = root gid = root use chroot = false max connections = 200 timeout = 100 pid file = /var/run/rsyncd.pid lock file = /var/run/rsync.lock log file = /var/log/rsyncd.log dont compress = *.gz *.tgz *.zip *.z *.Z *.rpm *.deb *.bz2 ignore errors = true read only = false list = false ## 注意为了避免困惑 hosts allow 和 hosts deny 请二选其一 hosts allow = 172.16.1.0/24,10.9.0.0/16,120.27.48.179 # hosts deny = 10.0.0.0/16 # 支持多个认证账号 auth users = {{ auth_user }} secrets file = /etc/rsync.password # 数据备份 注意 path 目录的权限信息 [back_data_module] path = /backup/busi_data/ # 数据库备份 注意 path 目录的权限信息 [back_db_module] path = /backup/database/ #rsync_config---------------end [ rsyncd]$ cat templates/rsync.password.j2 # 文件2 {{ auth_user }}:{{ auth_pawd }}
[ rsync_client]$ pwd /app/ansible_info/ansible_roles/roles/rsync_client [manager rsync_client]$ tree # 目录结构 . ├── tasks │ └── main.yml └── templates └── rsync.password.j2 2 directories, 2 files [ rsync_client]$ cat tasks/main.yml # tasks 信息 - name: "rsync passwrod file config" template: src: rsync.password.j2 dest: /etc/rsync.password owner: root group: root mode: ‘400‘ [ rsync_client]$ cat templates/rsync.password.j2 # 模板信息 {{ auth_pawd }}
[ ansible_roles]$ pwd /app/ansible_info/ansible_roles [ ansible_roles]$ cat group_vars/all # NFS 服务端目录 nfs_dir: /data # rsync daemon 使用 auth_user: rsync_backup auth_pawd: rsync_backup_pwd
[ ansible_roles]$ cat rsyncd_server.yml --- # rsyncd server - hosts: manageservers roles: - rsyncd - hosts: proxyservers roles: - rsync_client
1 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key --syntax-check rsyncd_server.yml # 语法检测 2 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key -C rsyncd_server.yml # 预执行,测试执行 3 [ ansible_roles]$ ansible-playbook -b -i ../hosts_key rsyncd_server.yml # 执行
https://galaxy.ansible.com
———END———
如果觉得不错就关注下呗 (-^O^-) !