RHCE
RHCE ansible+playboot剧本基本上没什么可以注意的 ,唯一注意的点就只有playbook剧本里的语法、一些变量和模块拼写的错误 ,只要用心去写这些都是可 以避免的。
刚开始学,容易出现一些普遍的错误,尽量自己学着处理这些报错,实在不行就上群问问。
建议练习再写playbook剧本的时候一步一步来,写完一个任务或一个模块执行一次,这样报错了还比较容易去排查。考试的时候觉得不稳也可以这样子。 文档中的剧本别随便复制,可能格式会有误。 (太多了,懒得整理格式)
一、安装及配置ansible
在 control 上安装并配置 ansible, 要求如下: 安装相应的软件包 创建一个静态 inventory 到/home/greg/ansible/inventory, 清单包含: node1 属于 dev 组 node2 属 于 test 组 node3 和 node4 属 于 prod 组 node5 属 于 balancers 主 机 组 prod 组 属 于 webservers 主 机 组 创 建 一 个 /home/greg/ansible/ansible.cfg 使 用/home/greg/ansible/inventory 角色目录为/home/greg/ansible/roles
# sudo yum -y install ansible
# mkdir -p ansible/roles
配置ansible需要管理的主机
# vim /home/greg/ansible/inventory
[dev]
node1
[test]
node2
[prod]
node3
node4
[balancers]
node5
[webservers:children]#组继承
prod
# cp /etc/ansible/ansible.cfg .
修改当前用户的配置文件
# vim ansible/ansible.cfg
inventory = /home/greg/ansible/inventory
roles_path = /home/greg/ansible/roles
取消ssh验证 ,也就是第一次ssh机器时不需要按yes更新密钥
host_key_checking = False
remote_user = greg
[privilege_escalation]
become=True
become_method=sudo
become_user=root
become_ask_pass=False
或者通过root用户远程管理
# vim ansible/ansible.cfg
inventory = /home/greg/ansible/inventory
roles_path = /home/greg/ansible/roles
host_key_checking = False
remote_user = root
# vim /home/greg/ansible/inventory
...........
最下面写上一个ansible调用ssh密码变量
[all:vars]
ansible_password=flectrag
# ansible dev --list-hosts
# ansible all --list-hosts
二、 创建并运行ansible ad-hoc 命令
创 建 ad-hoc 脚 本 /home/student/ansible/adhoc.sh , 为 所 有 节 点 配 置 yum 仓 库 : 仓 库 1 : 仓 库 名 : repo_base 描 述 为 : repo_base Base URL : http://foundation0.ilt.example.com/dvd/BaseOS 开启 GPG 签名验证 ,密钥为:http://foundation0.ilt.example.com/dvd/RPM-GPGKEY-redhat-release 仓库的状态是 enabled 仓库 2: 仓库名: repo_stream 描述为: repo_stream Base URL :http://foundation0.ilt.example.com/dvd/AppStream 开启 GPG 签名验证 ,密钥为: http://foundation0.ilt.example.com/dvd/RPM-GPGKEY-redhat-release 仓库的状态是 enabled
# ansible all -m ping -o
# ansible-doc yum_repository
# Shift + G
# vim adhoc.sh
#!/bin/bash
ansible all -m yum_repository -a "file=repo_base name= 'repo_base ' description=repo_base
baseurl='http://foundation0.ilt.example.com/dvd/BaseOS ' gpgcheck=yes gpgkey= 'http://foundation0.ilt.example.com/dvd/RPM-GPGKEY- redhat-release ' enabled=yes"
ansible all -m yum_repository -a "file=repo_stream name= 'repo_stream ' description=repo_stream
baseurl='http://foundation0.ilt.example.com/dvd/AppStream '
gpgcheck=yes gpgkey= 'http://foundation0.ilt.example.com/dvd/RPM-GPGKEY-redhat-release ' enabled=yes"
# chmod +x adhoc.sh
# ./adhoc.sh
# ansible all -m shell -a "yum repolist"
三、安装软件包
创建/home/student/ansible/install_packages.yml 的 playbook: 在 dev、test、prod 组中安装 php 和 mariadb 软件包 在 dev 组中安装 Development Tools 包组 在 dev 组中的主机升级所有的软件包
# vim install_packages.yml
---
- name: install php and mariadb hosts:
- dev
- test
- prod
tasks:
- name: install packages
yum:
name:
- php
- mariadb state: present
- name: install development tools group hosts: dev
tasks:
- name: install dev tools
yum:
name: "@Development Tools"
state: present
- name: update all
yum:
name: '* '
state: latest
# rpm -qa php mariadb
# yum grouplist
四、 使用RHEL system role
安装 RHEL system roles 软件包 ,并创建一个 playbook 名字为 timesync.yml 在所有受管主机中运行 使用 172.25.254.254 配置时间同步的方式是 iburstk
# ansible all -m ping -o
# sudo yum -y install rhel-system-roles
# vim ansible.cfg
roles_path = /home/greg/ansible/roles:/usr/share/ansible/roles
# ansible-galaxy list
# cp -r /usr/share/doc/rhel-system-roles/timesync/example-timesync-playbook.yml /home/greg/ansible/timesync.yml
修改主机
#vim /home/greg/ansible/timesync.yml
---
- hosts: all vars:
timesync_ntp_servers:
- hostname: 172.25.254.254 iburst: yes
relos:
- rhel-system-roles.timesync
修改服务器主机
# ansible-playbook timesync.ym
五、 使用Ansible Galaxy 安装roles
使 用 名 为 requirements.yml 的 文 件 下 载 并 安 装 Ansible Galaxy 角 色 到 /home/greg/ansible/roles 目 录 中 , 可 以 从 下 列 URL 下 载 : http://materials.example.com/haproxy.tar 这个角色的名字叫 balance http://materials.example.com/phpinfo.tar 这个角色的名字叫 phpinfo
# vim roles/requirements.yml
---
- src: http://materials.example.com/haproxy.tar name: balance
- src: http://materials.example.com/phpinfo.tar name: phpinfo
# ansible-galaxy install -r /home/greg/ansible/roles/requirements.yml -p /home/greg/ansible/roles
# ansible-galaxy list
六、 创建并使用role
在/home/greg/ansible/roles 目录中创建名为 apache 的角色 ,要求: 安装 httpd 软件包 ,开机启动 ,并自动运行 启用防火墙 ,开放 web 服务 模板文件 index.html.j2,复制到/var/www/html/index.html,内容如下: welcome to HOSTNAME on IPADDRESS
防火墙也需要自启动
# cd /home/greg/ansible/roles
# ansible-galaxy init apache
# cd ..
# vim roles/apache/tasks/main.yml
---
- name: install apache yum:
name: httpd
state: latest
- name: start service apache service:
name: httpd
state: started
enabled: yes
- name: start service firewalld service:
name: firewalld
state: started
enabled: yes
- name: open firewalled port firewalld:
service: http
permanent: yes
state: enabled
immediate: yes
- name: template a file template:
src: index.html.j2
dest: /var/www/html/index.html
# vim roles/apache/templates/index.html.j2
Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4.address }}
七、 使用来自Ansible Galaxy 的roles
做此题之前 ,先停一下 node5 主机上的 httpd 服务 ,但会导致node1-4 重启时无法启动到登录界 面 ,不过不 影响。停止方法: sudo systemctl stop httpd 创建 一个 playbook 名字叫/home/greg/ansible/roles.yml, 要求如下: 这个 playbook 运行在 balancers 这个主机组上,并使用 balance 的角色。 这个角色配置一个用来 在 webservers 主机组上实现 一 个负载均衡服务 使用浏览器访问 balancers 主机组 , 如 http://node5.lab.example.com 可 以 看 到 如 下 输 出: Welcome to serverc.lab.example.com on 172.25.250.12 重新刷新浏览器 ,可以看到如下输出: Welcome to node2.lab.example.com on 172.25.250.13 这个 playbook 运行在 webservers 主机组上使用 phpinfo 的角色。 使用浏览器 URL:node5.lab.example.com/hello.php 访问主机组 webservers 时 ,看到如下输出: Hello PHP World from FQDN 注意 ,FQDN 是主机的完整域名 。 比如 ,浏览器访问 URL :http://node3.lab.example.com/hello.php 看到如下输出: Hello PHP World from node3.lab.example.com 类似的,浏览器访问 URL:http://node4.lab.example.com/hello.php 看到如下输出: Hello PHP World from node4.lab.example.com
bastion ( role: balancer ) LB
serverc,serverb ( role: apache,phpinfo )
先使用phpinfo、apache角色 ,再使用balance角色
# vim roles.yml
---
- name: use apache and php hosts: webservers
roles:
- apache
- phpinfo
- name: use role balancer hosts: balancers
roles:
- balance
# ansible-playbook roles.yml
八、 创建并使用逻辑卷
创建一个 playbook 名字叫/home/greg/ansible/lv.yml ,对所有的节点操作:创建一个逻辑卷要求如下: LV 创建在 vg0 这个卷组里 LV 的名字叫 lv01 LV 的大小 是 1500M 格式化成 ext4 文件系统 如果 LV 的大小不满足 ,产生报错信息:could not create logical vol of that size 则创建分区大小变成 800M 如果卷组 vg0 不 存在,显示错误信息: volume group does not exist 不要使用任何方式挂载逻辑卷
练习环境里的vg逻辑卷组需要自己创建出来,考试是不用的
# vim lv.yml
---
- name: create lv hosts: all
tasks:
- block:
- name: create lv01 of 1500M lvol:
vg: vg0
lv: lv01
size: 1500
- name: ext4 filesystem
filesystem:
fstype: ext4
dev: /dev/vg0/lv01
rescue:
- debug:
msg: could not create logical vol of that size
- name: create lv01 of 800M
lvol:
vg: vg0
lv: lv01
size: 800
when: ansible_lvm.vgs.vg0 is defined
- name: ext4 filesystem
filesystem:
fstype: ext4
dev: /dev/vg0/lv01
when: ansible_lvm.vgs.vg0 is defined
ignore_errors: yes
- debug:
msg: volume group does not exist
when: ansible_lvm.vgs.vg0 is undefined
# ansible-playbook lv.yml
九、生成一个 hosts 文件
在 /home/greg/ansible/ 目 录 下 编 辑 一 个 hosts.j2 以 便 可 以 使 用 它 以 与 /etc/hosts 相 同 的 格 式 生 成 每 个 库 存 主 机 的 文 件 创 建 一 个 playbook 名 为/home/greg/ansible/hosts.yml, 来使用模板为 dev 组中的主机生成 /etc/myhosts 文件 完成时 ,myhosts 文件内容为: 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.25.250.10 node1.lab.example.com servera 172.25.250.11 node2.lab.example.com serverb 172.25.250.12 node3.lab.example.com serverc 172.25.250.13 node4.lab.example.com serverd 172.25.250.14 node5.lab.example.com bastion 注意:生成的文件顺序不对没有关系。
# vim hosts.j2
*
*
{% for host in groups[ 'all '] %}
{{ hostvars[host][ 'ansible_facts '][ 'default_ipv4'][ 'address '] }} {{ hostvars[host][ 'ansible_facts '][ 'fqdn '] }} {{ hostvars[host][ 'ansible_facts '][ 'hostname '] }}
{% endfor %}
# vim hosts.yml
---
- name: create myhosts hosts: all
tasks:
- name: template a file /etc/myhosts
template:
src: /home/greg/ansible/hosts.j2
dest: /etc/myhosts
#when: '"dev" in group_names '
when: 'inventory_hostname in groups.dev '
# ansible-playbook hosts.yml
十、 修改文件内容
创建一个 playbook 名为/home/greg/ansible/issue.yml ,修改/etc/issue 的内容 ,要求如下: 在 dev 主机组上 ,单行显示的内容是: Development 在 test 主机组上, 单行显示的内容是: Test 在 prod 主机组上,单行显示的内容是: Production
# vim issue.yml
---
- name: replace issue hosts: all
tasks:
- name: replace Development
copy:
content: "Development\n"
dest: /etc/issue
when: inventory_hostname in groups.dev
- name: replace Test
copy:
content: "Test\n"
dest: /etc/issue
when: inventory_hostname in groups.test
- name: replace Production
copy:
content: "Production\n"
dest: /etc/issue
when: inventory_hostname in groups.prod
# ansible dev -m shell -a "cat /etc/issue"
# ansible test -m shell -a "cat /etc/issue"
# ansible prod -m shell -a "cat /etc/issue"
十一、 创建一个 WEB 内容目录
创建一个 playbook 名字叫/home/greg/ansible/webcontent.yml, 要求如下: 这个 playbook 运行在 dev 主机组 创建/webdev 目录 ,要求如下: 目录属于 webdev 组 权限是 2775 软链接/var/www/html/webdev 到/webdev 在/webdev 中创建 index.html, 内容为: Development 通过 node1.lab.example.com/webdev/ 能访问到内容
# vim webcontent.yml
---
- name: create web directory hosts: dev
roles:
- apache
tasks:
- name: create group group:
name: webdev
state: present
- name: create directory webdev
file:
state: directory
path: /webdev
mode: '2775 '
group: webdev
- name: create a symbolic link
file:
state: link
src: /webdev
dest: /var/www/html/webdev
- name: create web content
copy:
content: "Development\n"
dest: /webdev/index.html
setype: httpd_sys_content_t
# ls -lhd /webdev
# ls -lhZ /webdev/index.html
# ls -lh /var/www/html/webdev
# curl http://node1.lab.example.com/webdev/
十二、 创建硬件报告
创建一个 playbook 名字叫/home/greg/ansible/hwreport.yml, 在所有的受管主机上 创建/root/hwreport.txt, 包含 如下内容: inventory 的主机名 Total memory in MB BIOS version vda size vdb size 每行均为一个键值对 playbook 会下载 http://materials.example.com/hwreport.empty, 并 修 改 成 为 hwreport.txt 如果硬件不存 在,则对应的值为: NONE
# vim hwreport.yml
---
- name: hw report
hosts: all
vars:
hw_all:
- hw_name: HOST
hw_cont: "{{ inventory_hostname | default( 'NONE ', true) }}"
- hw_name: MEMORY
hw_cont: "{{ ansible_memtotal_mb | default( 'NONE ', true) }}"
- hw_name: BIOS
hw_cont: "{{ ansible_bios_version | default( 'NONE ', true) }}"
- hw_name: DISK_SIZE_VDA
hw_cont: "{{ ansible_devices.vda.size | default( 'NONE ', true) }}"
- hw_name: DISK_SIZE_VDB
hw_cont: "{{ ansible_devices.vdb.size | default( 'NONE ', true) }}"
tasks:
- name: download hw_temp
get_url:
url: "http://materials.example.com/hwreport.empty"
dest: /root/hwreport.txt
- name: generate hw report
lineinfile:
path: /root/hwreport.txt
regexp: "^{{ item.hw_name }}="
line: "{{ item.hw_name }}={{ item.hw_cont }}"
loop: "{{ hw_all }}"
# ansible-playbook hwreport.yml
十三、 创建一个包含密码的vault 文件
vault 文 件 名 : locker.yml , 其 中 包 含 两 个 变 量 : pw_developer: Imadev pw_manager: lmamgr vault
在/home/greg/ansible/secret.txt
# vim ansible.cfg
vault_password_file = /home/greg/ansible/secret.txt
# vim locker.yml
---
pw_developer: Imadev
pw_manager: lmamgr
# vim secret.txt
redhat
# ansible-vault encrypt /home/greg/ansible/locker.yml
十四、 创建用户账户
使用 http://materials.example.com/user_list .yml 文件和/home/greg/ansible/locker.yml 文件,创建 playbook 文 件 users.yml 以创建用户 dev 和 test 主机组中创建带
有工作描述为: developer 的用户 ,密码使用: pw_developer 变量 ,用户的附属组为 devops prod 主机组中创建带有工作描述为: manager 的用户 ,密码使用 pw_manager 变量,用户的附属组为 opsmgr 密码均基于 SHA512hash 格式创建
# wget http://materials.example.com/user_list .yml
developer ----→ groups.dev or groups.test ------ locker.yml(pw_developer) --- devops
sally (job manager) ------ groups.prod ------ locker.yml(pw_manager) ------ opsmgr
sha512
# vim users.yml
---
- name: create users hosts: all vars_files:
- /home/greg/ansible/locker.yml
- /home/greg/ansible/user_list.yml tasks:
- name: create group devops
group:
name: devops
state: present
when: inventory_hostname in groups.dev or inventory_hostname in groups.test
- name: create group opsmgr
group:
name: opsmgr
state: present
when: inventory_hostname in groups.prod
- name: create user developer
user:
name: "{{ item.name }}"
groups: devops
password: "{{ pw_developer | password_hash( 'sha512 ', 'mysecretsalt ') }}"
comment: "{{ item.job }}"
loop: "{{ users }}"
when: item.job == 'developer ' and ( inventory_hostname in groups.dev or inventory_hostname in groups.test ) - name: create user manager
user:
name: "{{ item.name }}"
groups: opsmgr
password: "{{ pw_manager | password_hash( 'sha512 ', 'mysecretsalt ') }}"
comment: "{{ item.job }}"
loop: "{{ users }}"
when: item.job == 'manager ' and inventory_hostname in groups.prod
# ansible_playbook users.yml
十五、 更新Ansible 库的密钥
按照下方所述 ,更新现有 Ansible 库的密钥 从 http://xxx.example.com/materials/salaries.yml 下载 Ansible 库到 /home/greg/ansible 当前库的密码为: mysecret 新 的库密码为: yournewsecret 库使用新密码保持加密状态
salaries.yml文件练习里是没有的,需要在群里下载出来,考试时这个文件是有的
突然发现群里的这个salaries.yml文件解密密码是错的,所以只能自己随便建一个出来练习加密解密
创建一个有数据的文件
#echo 'the is encrypt ' > salaries.txt
创建两个存放密码的密码谱
# echo 'mysecret ' > secret_current.txt
# echo 'yournewsecret ' > secret_new.txt
编辑ansible.cfg配置文件 ,把vault_password_file存在的行注释掉
# vim ansible.cfg
使用 secret_new.txt密码谱加密
# ansible-vault encrypt salaries.txt --vault-password-file=/home/greg/ansible/secret_new.txt
解密
# ansible-vault decrypt salaries.txt --vault-password-file=/home/greg/ansible/secret_new.txt
使用secret_current.txt密码谱加密
# ansible-vault encrypt salaries.txt --vault-password-file=/home/student/ansible/secrect_current.txt
# wget http://materials.example.com/salaries.yml
# echo 'mysecret ' > secret_current.txt
# echo 'yournewsecret ' > secret_new.txt
用当前库密码解密
# ansible-vault decrypt salaries.yml --vault-password-file=/home/student/ansible/secrect_current.txt
用新库密码加密
# ansible-vault encrypt salaries.yml --vault-password-file=/home/student/ansible/secret_new.txt
# vim ansible.cfg
# 取消注释
vault_password_file = /home/greg/ansible/secrect.txt
十六、 安装RHEL角色
安装RHEL角色,并使用SeLinux角色,要求在所有节点运行,将SELINUX设置为强制模式
安装角色
# yum install rhel-system-roles -y
# cp -rf /usr/share/ansible/roles/linux-system-roles.selinux ./
安装出来的可以改也可以不改 ,剧本里面只留那么多 ,别的多余删掉
# vim selinux.yml
---
- hosts: all vars:
selinux_policy: targeted
selinux_state: enforcing
roles:
- role: rhel-system-roles.selinux
tasks:
- name: apply SElinux role block:
- include_role:
name: rhel-system-roles.selinux
rescue:
name: check fail:
when: not selinux_reboot_required
- name: reboot shell: reboot
- name: changed include_role:
name: rhel-system-roles.selinux
十七、 创建到期用户账户
创建用户账户,账户jack,新增设置密码有效期为30天。账户jony,新增设置相应的ID1111,用户有效期到2022-01-20
# date -d 2022-01-20 +%s #获取对应日期的unix时间戳
1642636800
---
- hosts: all vars:
- users:
- name: jack
- name: jony
tasks:
- name: create user user:
name: "{{ item.name }}"
password: "{{ 'redhat ' | password_hash( 'sha512 ' ) }}"
loop: "{{ users }}"
- name: Set user validity period user:
name: "{{ item.name }}"
expires: 1642636800
loop: "{{ users }}"
when: item.name == 'jack '
#源设置密码到期参数password_expire_max也被移除 ,所以只能用shell模块
# - name: Password expired
# user:
# password_expire_max: 30
- name: Password expired
shell: chage -M 30 "{{ item.name }}"
loop: "{{ users }}"
when: item.name == 'jony '
十八、 使用crontab模块
用户jack每三个月的每周日晚上22点39分查看一次自身用户登录情况
# vi crontab.yml
---
- hosts: all tasks:
- name: Creates a cron file under /etc/cron.d cron:
name: Login time
minute: "39"
hour: "22"
#day: ""
month: "*/3"
weekday: "0"
user: jack
job: "(last && lastb)|grep jack"
十九、 创建新的磁盘分区
在balancers主机上,划分新的partition ,/dev/vdd,编号1,大小1500m,格式化成ext4 ,mount到/newpart1目录,如果空间不够,分800m,如果没有vdd,报错
练习环境可能需要自己添加一个磁盘
# vim partition.yml
---
- name: partition hosts: balancers tasks:
- name: Create a directory file:
name: /newpart
state: directory
- block:
- name: device 1500M parted:
device: /dev/vdb
number: 1
state: present
part_end: 1500MiB
- name: ext4 filesystem filesystem:
fstype: ext4
dev: /dev/vdb1
- name: mount mount:
path: /newpart
src: /dev/vdb1
fstype: ext4
state: mounted
rescue:
- debug:
msh: Could not create partation of that size
- name: device 800M parted:
device: /dev/vdb
number: 1
state: present
part_end: 800MiB
when: ansible_facts.devices.vdb is defined
- name: ext4 filesystem filesystem:
fstype: ext4
dev: /dev/vdb1
when: ansible_facts.devices.vdb is defined
- name: mount mount:
path: /newpart
src: /dev/vdb1
fstype: ext4
state: mounted
when: ansible_facts.devices.vdb is defined
ignore_errors: yes
- debug:
msg: Disk does not exist
when: ansible_facts.devices.vdb is undefined