运维 RHCE Redhat RHCE8-EX294 试题解析记录 Zelas2Xerath 2023-01-05 2023-07-22 RHCE-EX294
勘误:leancode@189.cn
合计 16 题,校验 16 题
建议完成时间:1 小时
【更新】修正部分文字描述和错误
【更新】更新了新题型
前置信息 将使⽤以下虚拟系统进⾏此考试:
System
IP address
Role
control.domainx.example.com
172.24.250.254
Ansinle Server
node1.domainx.example.com
172.25.250.9
Ansible Client
node2.domainx.example.com
172.25.250.10
Ansible Client
node3.domainx.example.com
172.25.250.11
Ansible Client
node4.domainx.example.com
172.25.250.12
Ansible Client
node5.domainx.example.com
172.25.250.13
Ansible Client
所有系统的root密码都是 redhat
请勿更改root密码。
安装和配置 Ansible 照下方所述,在控制节点 control.domainx.example.com 上安装和配置 Ansible:
安装所需的软件包
创建名为 /home/greg/ansible/inventory 的静态清单文件,以满足以下要求:
nodel 是dev 主机组的成员
node2 是 test 主机组的成员
node3 和 node4 是 prod 主机组的成员
node5 是 balancers 主机组的成员
prod 组是 webservers 主机组的成员
创建名为 /home/greg/ansible/ansible.cfg 的配置文件,以满足以下要求:
机清单文件为 /home/greg/ansible/inventory
playbook 中使用的角色的位置包括 /home/greg/ansible/roles
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 ssh root@control yum repolist yum-config-manager --add-repo=http://content.example.com/rhel8.0/x86_64/ucfupdates/ echo "gpgcheck=0" >>/etc/yum.repo.d/content.example.com_rhe18.0_x86_64_ucfupdates.repoyum install -y ansible ansible --version exit ssh control mkdir ansiblecd ansible/mkdir group_varsvim inventory vim ansible.cfg vim group_vars/all
ansible/inventory
完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 node1 node2 node3 node4 ndoe5 [dev] node1 [test ] node2 [prod] node3 node4 [balancers] node5 [webservers:children] prod
ansible/ansible.cfg
完整文件(远程使用普通用户)
1 2 3 4 5 6 7 8 9 10 11 [defaults] inventory = /home/greg/ansible/inventory roles_path = /home/greg/ansible/roles:/usr/share/ansible/roles remote_user = greg ask_pass = false [privilege_escalation] become=true become_method=sudo become_user=root become_ask_pass=false
ansible/ansible.cfg
远程用户指定为 root 时,无需配置提权部分(使用如下的配置)
1 2 3 4 [defaults] inventory = /home/greg/ansible/inventory remote_user = root roles_path = /home/greg/ansible/roles
ansible/group_vars/all
完整文件(被控制节点未做免密登录时可以设置此变量)
1 ansible_ssh_pass: redhat
1 2 3 4 5 6 7 8 9 10 ansible -i inventory --list dev ansible -i inventory --list test ansible -i inventory --list prod ansible -i inventory --list balancers ansible -i inventory --list webservers ansible all -m ping ansible all -a "id"
创建和使用 ansible 的临时命令 创建一个名为 /home/greg/ansible/adhoc.sh
的 shell 脚本该脚本将使用 Ansible 临时命在各个受管节点上安装 yum 存储库
存储库1:
储库的名称为 EX294_BASE
描述为 EX294 base software
BaseURL为 http://repo.domainx.example.com/BaseOS
GPG 签名检查为后用状态
GPG密钥URL为http://repo.domainx.example.com/RPM-GPG-KEYredhat-release
存储库为启用状态-
存储库2:
存储库的名称为 EX294_STREAM
描述为 EX294 stream software
BaseURL为 http://rhgls.domainx.example.com/AppStream
GPG 签名检查为启用状态
GPG密钥 URL为http://rhgls.domainx.example.com/RPM-GPG-KEYredhat-release
储库为启用状态
adhoc.sh
完整文件
1 2 3 #!/bin/bash ansible all -m yum_repository -a 'name="EX294_BASE" description="EX294 base software" baseurl="http://repo.domainx.example.com/BaseOS" gpgcheck="yes" gpgkey="http://repo.domainx.example.com/RPM-GPG-KEYredhat-release"' ansible all -m yum_repository -a 'name="EX294_STREAM" description="EX294 stream software" baseurl="http://rhgls.domainx.example.com.com/AppStream" gpgcheck="yes" gpgkey="http://repo.domainx.example.com/RPM-GPG-KEYredhat-release"'
1 2 3 chmod +x adhoc.sh./adhoc.sh ansible all -a 'yum repolist'
安装软件包 创建一个名为/home/greg/ansible/packages.yml
的 playbook:
将 php 和 mariadb 软件包安装到 dev、test 和 prod 主机组中的主机上
RPM Development Tools 软件包组安装到 dev 主机组中的主机上
dev 主机组中主机上的所有软件包更新为最新版本
packages.yml
完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 --- - name: install packages hosts: dev,test,prod tasks: - name: instal pkgs task1 yum: name: - php - mariadb state: present - name: install pkgs task2 hosts: dev tasks: - name: use yum moudle yum: name: "@RPM Development Tools" state: latest - name: update all pkgs yum: name: "*" state: latest
另一种使用条件判断写法(2选1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 --- - name: install packages hosts: dev,test,prod tasks: - name: instal pkgs task1 yum: name: - php - mariadb state: present - name: use yum moudle yum: name: "@RPM Development Tools" state: latest when: '"dev" in group_names' - name: update all pkgs yum: name: "*" state: latest when: '"dev" in group_names'
1 2 3 4 ansible-playbook packages.yml ansible dev -m "shell" -a "yum group list" ansibel dev,test ,prod -m "shell" -a "rpm -qa php mariadb"
使用RHEL系统角色 安装 RHEL系统角色软件包,并创建符合以下条件的 playbook /home/greg/ansible/timesync.yml
在所有受管节点上运行
使用 timesync 角色
配置该角色,以使用当前有效的 NTP 提供商
配置该角色,以使用时间服务器 172.25.254.254
配置该角色,以后用 iburst 参数
创建符合以下条件的 playbook /home/greg/ansible/selinux.yml
:
在所有受管节点上运行
使用 selinux 角色
设置所有的节点 selinux 状态为 enforcing
1 2 3 4 5 sudo yum install -y rhel-sysyem-roles mkdir rolesansible-galaxy list
timesync.yml
完整文件
1 2 3 4 5 6 7 8 9 --- - name: use system roles hosts: all vars: timesync_ntp_servers: - hostname: 172.25 .254 .254 iburst: yes roles: - rhel-system-roles.timesync
1 2 3 ansible-playbook timesync.yml ansible all -m "shell" -a "chronyc -n sources"
/home/greg/ansible/selinux.yml
完整文件
1 2 3 4 5 6 7 8 --- - name: set selinux hosts: all vars: selinux_policy: targeted selinux_state: enforcing roles: - rhel-system-roles.selinux
1 2 3 ansible-playbook selinux.yml ansible all -m shell -a "grep -v # /etc/selinux/config"
使用AnsibleGalaxy安装角色 用 Ansible Galaxy 安装角色:
新建 playbook为 /home/greg/ansible/requirements.yml
。从以下URL下载并安装到 /home/greg/ansible/roles
:
http://rhgls.domainx.example.com/materials/haproxy.tar
此角色的名字设置为balancer
http://rhgls.domainx.example.com/materials/phpinfo.tar
此角色的名字设置为phpinfo
requirements.yml
完整文件
1 2 3 4 5 - src: http://rhgls.domainx.example.com/materials/haproxy.tar name: balancer - src: http://rhgls.domainx.example.com/materials/phpinfo.tar name: phpinfo
1 2 3 4 5 ansible-galaxy install -r requirements.yml ansible-galaxy list cp requirements.yml roles/ls roles/
创建一个 web role 根据下列要求,在 /home/greg/ansible/roles
中创建名为 apache 的角色:
装 httpd 包,并启动 httpd 服务,设置服务下次开机启动
启动防火墙服务,设置防火墙服务下次开机启动,放行web流量
创建 index.html.j2
文件,该模板文件用于输出如下文件 /var/www/html/index.html
Welcome to HOSTNAME ON IPADDRESS
HOSTNAME 是受管节点的 FQDN
IPADDRESS 则是受管节点的 IP 地址
创建 playbook /home/greg/ansible/apache.yml
在 webservers 主机组使用 apache 的角色
1 2 cd roles/ansible-galaxy init apache
Changed roles/apache/tasks/main.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 --- - name: install pkgs yum: name: httpd state: latest - name: enable service service: name: httpd state: started enabled: yes - name: enable firewalld service service: name: firewalld state: started enabled: yes - name: set firewalld firewalld: service: http immediate: yes permanent: yes state: enabled - name: set pages template: src: index.html.j2 dest: /var/www/html/index.html
Create roles/apache/templates/index.html.j2
1 Welcome to {{ ansible_fqdn }} on {{ ansible_default_ipv4['address'] }}
Changed apache.yml
1 2 3 4 5 --- - name: use apache roles hosts: webservers roles: - apache
1 2 3 ansible-playbook apache.yml curl node3 curl node4
从 Ansible Galaxy 使用角色 根据下列要求,创建一个名为 /home/greg/ansible/roles.yml
的 playbook:
playbook 中包含一个 play,该 play 在 balancers 主机组中的主机上运行并将使用 balancer 角色
此角色配置一项服务,以在 webservers 主机组中的主机之间平衡 Web 服务器请求的负载
浏览到 balancers 主机组中的主机(例如 http://node5.domainx.example.com/)将生成以下输出
Welcome to node3.domainx.example.com on 172.25.250.11
新加载浏览器将从另一 Web 服务器生成输出Welcome to node4.domainx.example.com on 172.25.250.12
playbook 中包含一个 play,该 play 在 webservers 主机组中的主机上运行并使用 phpinfo 角色通过 URL/hello.php
的到 webservers 主机组中的主机将生成以下输出
Hello PHP World from FQDN
其中,FQDN 是主机的完全限定名称
浏览到 http://node3.example.com/hello.php 会生成以下输出:
Hello PHP World from node3.domainx.example.com
另外还有 PHP 配的各种详细信息,如安装的 PHP 版本等
浏浏览到 http://node4.example.com/hello.php 会生成以下输出:
Hello PHP World from node4.domainx.example.com。
另外还有 PHP 配置的各种详细信息,如安装的 PHP 版本等
roles.yml
完整文件
注:先执行 phpinfo role 以避免错误
1 2 3 4 5 6 7 8 9 --- - name: use phpinfo role hosts: webservers roles: - phpinfo - name: use haproxy role hosts: balancers roles: - balancer
1 2 3 4 5 6 7 8 9 10 11 12 13 ssh root@node5 firewall-cmd --list-all firewall-cmd --add-port=80/tcp firewall-cmd --add-port=80/tcp --per exit ansible-playbook roles.yml curl node5 curl node5 curl node3/hello.php curl node4/hello.php
创建和使用逻辑卷 创建一个叫做 lv.yml
的playbook,它将在所有被管理节点上执行下列任务:
创建逻辑卷
通过 research 卷组创建逻辑卷
逻辑卷的名称叫做 data
逻辑卷大小是 1500MB
格式化逻辑卷为ext4文件系统
如果逻卷不能被创建(由于大小不满足),应显示误 “Could not create logical volume of that size”,然后创建 800MB 代替
如果卷组 research 不存在,应显示错误 “Volume group does not exist”
不要以任何方式挂载逻辑卷
lv.yml
完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 --- - name: create lv hosts: all tasks: - block: - name: create a lv use research vg lvol: vg: research lv: data size: 1500 - name: format ext4 fs filesystem: fstype: ext4 dev: /dev/research/data rescue: - name: output some info debug: msg: "Could not create logical volume of that size" when: ansible_lvm.vgs.research is defined - name: create a lv use research vg lvol: vg: research lv: data size: 800 when: ansible_lvm.vgs.research is defined - name: format ext4 fs filesystem: fstype: ext4 dev: /dev/research/data when: ansible_lvm.vgs.research is defined - name: output some info debug: msg: "Volume group does not exist" when: ansible_lvm.vgs.research is undefined
1 2 3 ansible all -a 'vgs' ansible-playbook lv.yml ansible all -a 'lvs'
生成主机文件
下载http://rhgls.domainx.example.com/materials/hosts.j2
到 /home/greg/ansible
修改模板文件,让他能用来为每个 inventory 主机生成和 /etc/hosts 同样格式的文件
创建名为 home/greg/ansible/hosts.yml
的 playbook,它将使用此模板在 dev 主机组中的主机上生成文件 /etc/myhosts
该 playbook 运行后,dev 主机组中主机上的文件 /etc/myhosts 应针对每个受管主机包含一行内容
1 2 3 4 5 6 7 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 172.25.250.9 node1.domainx.example.com nodel 172.25.250.10 node2.domainx.example.com node2 172.25.250.11 node3.domainx.example.com node3 172.25.250.12 node4.domainx.example.com node4 172.25.250.13 node5.domainxexample.com node5
Download and changed /home/greg/ansible/hosts.j2
1 wget http://rhgls.domainx.example.com/materials/hosts.j2
1 2 3 4 5 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 {% for host in groups['all'] %} {{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ hostvars[host]['ansible_fqdn'] }} {{ hostvars[host]['ansible_hostname'] }} {% endfor %}
hosts.yml
1 2 3 4 5 6 7 8 9 --- - name: deploy hosts: all tasks: - name: template a host file template: src: hosts.j2 dest: /etc/myhosts when: '"dev" in group_names'
1 2 ansible-playbook hosts.yml ansible dev -a 'cat /etc/myhosts'
修改文件内容 按照下方所述,创建一个名为 /home/greg/ansible/issue.yml
的 playbook:
playbook 将在所有 inventory 主机上运行
该 playbook 会将 /etc/issue 的内容替换为下方所示的一行文本:
在 dev 主机组中的主机上,这文本显示 为:Development
在 test 主机组中的主机上,这行文本显示为:Test
在 prod 主机组中的主机上,这行文本显示 为:Production
issue.yml 完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- - name: modify file content hosts: all tasks: - copy: content: Development dest: /etc/issue when: '"dev" in group_names' - copy: content: Test dest: /etc/issue when: '"test" in group_names' - copy: content: Production dest: /etc/issue when: '"prod" in group_names'
1 2 ansible-playbook issue.yml ansible all -a 'cat /etc/issue'
创建web内容目录 按照下方所述,创建一个名为 /home/greg/ansible/webcontent.yml
的 playbook
该 playbook 在 dev 主机组中的受管节点上运行
建符合下列要求的目录/webdev
所有者为 webdev 组
具有常规权限:owner=rwx, group=rwx ,other=rx
有特殊权限:set gid
用符号链接将 /var/www/html/webdev 链接到 /webdev
创建文件 /webdev/index.html,其中包合如下所示的单行文件: Development
在 dev 主机组中主机上浏览此目录(例如 http://node1.domainx.example.com/webdev
) 将生成以下输出:Development
webcontent.yml 完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 --- - name: set web content hosts: dev tasks: - name: create a directory file: path: /webdev state: directory group: webdev mode: "2775" - name: create a soft link file: src: /webdev dest: /var/www/html/webdev state: link - name: set web content copy: content: Development dest: /webdev/index.html setype: "httpd_sys_content_t" - name: start httpd service service: name: httpd state: started enabled: yes - name: set firewall rule to allow http traffix firewalld: service: http permanent: yes immediate: yes state: enabled
1 2 ansible-playbook webcontent.yml curl -L node1/webdev
生成硬件报告
新建一个名为home/greg/ansible/hwreport.yml
的 playbook,它将在所有受管节点上生成含有以下信息的输出文件 root/hwreport.txt
清单主机名称
以 MB 表示的总内存大小
BIOS 版本
磁盘设备 vda 的大小
磁盘设备 vdb 的大小
输出文件中的每一行含有一个 key=value对
playbook 应当
从 http://rhgls.domainx.example.com/materials/hwreport.empty
下载文件,并将它保存为/root/hwreport.txt
使用正确的值改为 /root/hwreport.txt
如果硬件项不存在,相关的值应设为 NONE
hwreport.yml 完整文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 --- - name: create hardware report hosts: all vars: hardware: - hw_name: HOST hw_info: "{{ ansible_hostname }} " - hw_name: MEMORY hw_info: "{{ ansible_memtotal_mb }} " - hw_name: BIOS hw_info: "{{ ansible_bios_version }} " - hw_name: DISK_SIZE_VDA hw_info: "{{ ansible_devices['vda']['size'] | default('NONE') }} " - hw_name: DISK_SIZE_VDB hw_info: "{{ ansible_devices['vdb']['size'] | default('NONE') }} " tasks: - name: get hw report from url get_url: url: http://rhgls.domainx.example.com/materials/hwreport.empty dest: /root/hwreport.txt - name: set hw report content lineinfile: path: /root/hwreport.txt regexp: "^{{ item['hw_name'] }} =" line: "{{ item['hw_name'] }} ={{ item['hw_info'] }} " loop: "{{ hardware }} "
1 2 ansible-playbook hwreport.yml ansible all -a 'cat /root/hwreport.txt'
使用Ansible Vault
vault 的名字是 locker.yml
vault 包含两个变量
pw_developer 的值是 Imadev
pw_manager 的值是 Imamgr
加密解密的密码为whenyouwishuponastar
密码存放在/home/greg/ansible/secret.txt
1 2 3 4 5 6 7 8 cat > locker.yml <<EOF pw_developer: Imadev pw_manager: Imamgr EOF echo "whenyouwishuponastar" > secret.txtansible-vault encrypt --vault-id=./secret.txt locker.yml cat locker.ymlansible-vault view --vault-id=./secret.txt locker.yml
创建批量添加用户role
在http://rhgls.domainx.example.com/materials
中下载user_list.yml到/home/greg/ansible中
用 locker.yml 变量文件,创建 users.yml 来创建账号
带 developer 描述的 job 的用户应该满足如下条件
在 dev 和 test 主机组下创建用户
设置密码为 pw_developer 变量的值
附加组为 devops
带 manager 描述的 job 的用户应该满足如下条件
在prod主机组下创建用户
设置密码为 pw_manager 变量的值
附加组为 opsmgr
密码应该是 SHA512 的格式
playbook 应该使用 vault 密码文件来工作
users.yml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 --- - name: create user on dev and test hosts: dev,test vars_files: - locker.yml - user_list.yml tasks: - name: create group group: name: devops - name: create user user: name: "{{ item['name'] }} " password: "{{ pw_developer | password_hash('sha512','mysecretsalt') }} " groups: devops loop: "{{ users }} " when: item.job == 'developer' - name: create user on prod hosts: prod vars_files: - locker.yml - user_list.yml tasks: - name: create group group: name: opsmgr - name: create user user: name: "{{ item['name'] }} " password: "{{ pw_manager | password_hash('sha512','mysecretsalt') }} " uid: 6666 groups: opsmgr loop: "{{ users }} " when: item.job == 'manager'
1 2 3 4 wget http://rhgls.domainx.example.com/materials/user_list.yml ansible-playbook --vault-id=./secret.txt users.yml ansible dev -a 'id gzy001' ansible prod -a 'id gzy101'
重新设置 AnsibleVault 密码
下载 http://rhgls.domainx.example.com/materials/salaries.yml
保存到 /home/greg/ansible/salaries.yml
当前的密码是 insecure4sure
新的密码是 bbe2de98389b
vault文件使用新的密码保持为加密的状态
1 2 3 4 5 6 7 wget http://rhgls.domainx.example.com/materials/salaries.yml ansible-vault view salaries.yml > insecure4sure ansible-vault rekey salaries.yml > bbe2de98389b ansible-vault view salaries.yml > bbe2de98389b
创建定时任务 使用 crod 模块在所有节点给用户 natasha 创建一个任务,每两分钟运行一条命令
crond.yml 完整文件
1 2 3 4 5 6 7 8 9 10 11 12 --- - name: hosts: all tasks: - name: create user user: name: natasha - name: set cron cron: user: natasha minute: "*/2" job: logger "EX294 in progress"
1 2 ansible-playbook crond.yml ansible all -m shell -a "crontab -l -u natasha"