- 教程
【免费下载链接】ru-test-assignments
Тестовые задания для самостоятельного выполнения от разных it компаний
本指南围绕ru-test-assignments开源仓库中归档的 Peacock Team DevOps 测试任务(other/peacock-team/devops-ansible.md)展开,系统讲解如何用 Ansible 在 Ubuntu LTS 上一键完成 OpenLDAP 的安装、管理员密码与域名/组织配置、用户和组的批量添加,并补齐任务要求的 README 与结果验证。读完本文,你将掌握 slapd 非交互安装(debconf 预置)、LDIF 条目编写、ldapadd/ldapsearch实战用法,能够独立交付一份可运行、可复现的 Ansible 部署方案。
任务背景:这是一道怎样的测试题
本仓库是《Тестовые задания для прокачки》(测试题练习册)开源目录,收录了近 200 家 IT 公司的真实笔试题,且按 README 的说明(README.md)“有意不提供答案”,以保证练习价值。Peacock Team 的 DevOps 系列测试任务被归档在 other/peacock-team/ 下,共 4 道:Ansible(devops-ansible.md)、Docker(devops-docker.md)、Astra Linux(devops-astra.md)、Java、Scraping、Three.js、Vue 等,其中 Ansible 这道在仓库根 README.md 的任务索引中被标注为“Тестовое задание DevOps(Ansible)”。
原文档为俄语,是一份典型的“任务描述 + 交付要求”型笔试题,全文可译为:
编写一个 Ansible 脚本实现以下功能:
- 在 Ubuntu LTS 操作系统上安装 OpenLDAP 服务器;
- 在 LDAP 中设置管理员密码;
- 在 LDAP 中设置 domain 与 organization;
- 在 LDAP 中添加 2 个用户;
- 在 LDAP 中添加 2 个组;
在 README 中添加描述、所有运行所需的命令以及结果截图。
有两个值得注意的细节:一是原文档编号从 4 直接跳到 6(缺第 5 条),属原文笔误,实际是 5 项实质需求;二是文件开头标注“Локальная копия”(本地副本),说明这是从外部归档的题目快照,本文只基于仓库内文本展开,不引入外部链接。
需求拆解与技术选型
把 5 项实质需求映射到具体的 Ansible 技术动作,如下表:
| 任务要求(原文) | 技术动作 | 关键对象 |
|---|---|---|
| 1. 安装 OpenLDAP 服务器 | apt安装slapd(服务端)+ldap-utils(客户端工具) | 包名:slapd、ldap-utils |
| 2. 设置管理员密码 | debconf 预置 +dpkg-reconfigure,密码写入olcRootDN/olcRootPW | 管理员 DN:cn=admin,dc=example,dc=com |
| 3. 设置 domain 与 organization | debconf 键slapd/domain、slapd/organization;base DN 由域名推导 | example.com→dc=example,dc=com |
| 4. 添加 2 个用户 | 编写 LDIF,用ldapadd批量导入 | inetOrgPerson+posixAccount |
| 6. 添加 2 个组 | 编写 LDIF,用ldapadd批量导入 | posixGroup+memberUid |
| README + 命令 + 截图 | 交付文档模板(见下文第七节) | README.md、ldapsearch输出截图 |
核心设计决策:非交互安装。Ansible 通过 SSH 执行任务时没有 TTY,apt install slapd触发的 debconf 交互对话框会卡死任务,因此必须先用debconf模块把安装时的提问答案预置进 debconf 数据库,再让安装过程自动读取——这是 Debian/Ubuntu 系软件无人值守安装的标准做法,同样适用于 tzdata、mysql-server 等包。
另一个关键概念是base DN(基础专有名称):OpenLDAP 的目录树以 domain 为根,example.com会被切分为两段,得到dc=example,dc=com;管理员 DN 固定为cn=admin,<base_dn>。所有用户、组条目都要挂在 base DN 之下。
目录结构与前置准备
推荐按以下结构组织解决方案(控制机任意目录即可,仅目标机为 Ubuntu LTS):
ldap-deploy/ ├── inventory.ini # 目标机清单 ├── ansible.cfg # 可选:默认 inventory、关闭主机指纹校验 ├── playbook.yml # 主脚本:安装 + 配置 + 导入 + 验证 ├── files/ │ ├── users.ldif # 2 个用户条目 │ └── groups.ldif # 2 个组条目 └── README.md # 任务要求的交付文档前置条件与版本要求:
- 控制机:任意装有
ansible-core(Ansible 2.10+)的机器,python3 -m pip install --user ansible-core即可; - 目标机:Ubuntu LTS(22.04/24.04 均可,默认存储后端均为 MDB),支持 SSH 与
sudo; - 连接方式:控制机通过 SSH 免密(或 ssh-agent)连接目标机,
ansible_user使用具有become权限的账号。
inventory.ini示例(把 IP 换成实际目标机):
[ldap] ldap-server ansible_host=10.0.0.10 ansible_user=ubuntu ansible_become=true可选的ansible.cfg:
[defaults] inventory = inventory.ini host_key_checking = False核心 Playbook:安装与初始化配置
步骤顺序为什么是“先预置、再安装”
debconf模块写入的是 debconf 数据库(/var/cache/debconf/config.dat),不要求目标包已安装,因此正确的顺序是:
- 用
debconf预置全部安装提问的答案; - 用
apt安装slapd、ldap-utils,安装过程自动读取预置答案,全程无交互; - 兜底执行一次
dpkg-reconfigure -f noninteractive slapd,确保即使安装时错过预置也能拿到正确配置; - 用
service模块确认slapd服务启动并开机自启。
slapd 的 debconf 参数表
Debian/Ubuntu 的slapd包通过以下 debconf 键(模板内置于包内)控制安装行为,这是任务第 2、3 条的直接落点:
| debconf 键 | vtype | 作用 | 说明 |
|---|---|---|---|
slapd/backend | select | 存储后端 | 新版默认MDB(推荐),HDB/BDB已废弃 |
slapd/domain | string | LDAP 域名,决定 base DN | 如example.com→dc=example,dc=com |
slapd/organization | string | 组织名称 | 如Example Inc. |
slapd/password1 | password | 管理员密码 | 与 password2 必须一致 |
slapd/password2 | password | 管理员密码确认 | — |
slapd/no_configuration | boolean | 是否跳过配置 | false表示正常配置 |
slapd/allow_ldap_v2 | boolean | 是否允许 LDAPv2 协议 | 默认false,安全起见保持关闭 |
slapd/purge_database | boolean | 重配置时是否清空旧库 | 仅当机器上已存在旧库时出现 |
Playbook 完整代码(安装 + 初始化配置部分)
--- # ldap-deploy/playbook.yml # 在 Ubuntu LTS 上部署并配置 OpenLDAP(slapd) - name: Deploy and configure OpenLDAP server hosts: ldap become: true vars: ldap_domain: "example.com" # 任务第 3 条:domain ldap_org: "Example Inc." # 任务第 3 条:organization ldap_admin_password: "ChangeMe!2024" # 任务第 2 条:管理员密码 ldap_base_dn: "dc=example,dc=com" ldap_admin_dn: "cn=admin,{{ ldap_base_dn }}" tasks: # 1) 先预置 debconf 答案,保证 apt 安装全程无交互 - name: Preseed slapd debconf answers ansible.builtin.debconf: name: slapd question: "{{ item.question }}" value: "{{ item.value }}" vtype: "{{ item.vtype }}" loop: - question: slapd/backend value: "MDB" vtype: select - question: slapd/domain value: "{{ ldap_domain }}" vtype: string - question: slapd/organization value: "{{ ldap_org }}" vtype: string - question: slapd/password1 value: "{{ ldap_admin_password }}" vtype: password - question: slapd/password2 value: "{{ ldap_admin_password }}" vtype: password - question: slapd/no_configuration value: "false" vtype: boolean environment: DEBIAN_FRONTEND: "noninteractive" # 2) 安装服务端与客户端工具 - name: Install slapd and ldap-utils ansible.builtin.apt: name: - slapd - ldap-utils state: present update_cache: true register: apt_result environment: DEBIAN_FRONTEND: "noninteractive" # 3) 兜底:强制一次非交互重配置,确保 domain/org/密码生效 - name: Force non-interactive reconfigure of slapd ansible.builtin.command: dpkg-reconfigure -f noninteractive slapd changed_when: false # 4) 确保服务运行并开机自启 - name: Ensure slapd service is running ansible.builtin.service: name: slapd state: started enabled: true两个易错点:
dpkg-reconfigure -f noninteractive slapd会读取 debconf 数据库里的预置值,因此它必须出现在debconf任务之后;- 在每个涉及 apt/debconf 的任务上显式声明
environment: DEBIAN_FRONTEND: "noninteractive",双保险避免任何残留的交互提示。
安装完成后,管理员 DN 即为cn=admin,dc=example,dc=com,密码即为预置的ldap_admin_password,任务第 2、3 条由此完成。
添加用户与组:LDIF + ldapadd
LDIF 语法要点
LDIF(LDAP Data Interchange Format)是 LDAP 的标准数据交换格式,本任务中需要掌握三个规则:
- 每个条目以
dn:(Distinguished Name,专有名称)开头,随后是该条目属性; - 不同条目之间用一个空行分隔;
- 需要换行的长值可用一个前导空格续行。
由于用户与组分属不同组织单元,先分别建立ou=people与ou=groups两个容器。
users.ldif(任务第 4 条:2 个用户)
dn: ou=people,dc=example,dc=com objectClass: organizationalUnit ou: people dn: uid=alice,ou=people,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: alice cn: Alice Smith sn: Smith givenName: Alice displayName: Alice Smith uidNumber: 10001 gidNumber: 20001 homeDirectory: /home/alice userPassword: {SSHA}此处填入哈希 dn: uid=bob,ou=people,dc=example,dc=com objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount uid: bob cn: Bob Brown sn: Brown givenName: Bob displayName: Bob Brown uidNumber: 10002 gidNumber: 20002 homeDirectory: /home/bob userPassword: {SSHA}此处填入哈希说明:
inetOrgPerson强制要求cn、sn;posixAccount强制要求uid、uidNumber、gidNumber,用于后续与posixGroup的memberUid建立 Unix 风格归属关系;userPassword不要写明文,先用slappasswd生成 SSHA 哈希再填入:
slappasswd -s 'alice-secret'groups.ldif(任务第 6 条:2 个组)
dn: ou=groups,dc=example,dc=com objectClass: organizationalUnit ou: groups dn: cn=developers,ou=groups,dc=example,dc=com objectClass: posixGroup cn: developers gidNumber: 20001 memberUid: alice dn: cn=managers,ou=groups,dc=example,dc=com objectClass: posixGroup cn: managers gidNumber: 20002 memberUid: bobposixGroup的memberUid与 users 中的uid对应,gidNumber与用户条目中的gidNumber保持一致,形成完整的“用户—组”映射。若公司场景更偏目录式建模,也可改用groupOfNames对象类配合member: uid=alice,ou=people,dc=example,dc=com这种 DN 引用方式,两种都算“添加了组”,任务未限定对象类。
Playbook 中的导入与验证任务
在上一节 playbook 末尾追加:
# 5) 上传 LDIF 并添加 2 个用户(任务第 4 条) - name: Copy users LDIF ansible.builtin.copy: src: files/users.ldif dest: /tmp/ldap-users.ldif - name: Add users via ldapadd ansible.builtin.command: cmd: >- ldapadd -x -H ldap://localhost -D "{{ ldap_admin_dn }}" -w "{{ ldap_admin_password }}" -f /tmp/ldap-users.ldif # 6) 上传 LDIF 并添加 2 个组(任务第 6 条) - name: Copy groups LDIF ansible.builtin.copy: src: files/groups.ldif dest: /tmp/ldap-groups.ldif - name: Add groups via ldapadd ansible.builtin.command: cmd: >- ldapadd -x -H ldap://localhost -D "{{ ldap_admin_dn }}" -w "{{ ldap_admin_password }}" -f /tmp/ldap-groups.ldif # 7) 验证:列出 base DN 下的全部条目 - name: Verify entries with ldapsearch ansible.builtin.command: cmd: >- ldapsearch -x -H ldap://localhost -D "{{ ldap_admin_dn }}" -w "{{ ldap_admin_password }}" -b "{{ ldap_base_dn }}" "(objectClass=*)" register: search_result - name: Show LDAP search result ansible.builtin.debug: var: search_result.stdout_linesldapadd参数含义:-x使用简单认证,-H指定服务器 URL(本地为ldap://localhost),-D指定绑定 DN,-w指定绑定密码,-f指定 LDIF 文件。
幂等性:重复运行会报错
ldapadd不是幂等命令——playbook 第二次运行时,条目已存在,会返回 LDAP 错误码68(alreadyExists)。测试场景通常只需保证一次成功;若要求可重复执行,可在导入前先ldapsearch判断条目是否存在,或改用ldapmodify/community.general.ldap_entry模块(该模块用state: present管理条目,天然幂等,是更“Ansible 原生”的替代方案)。从任务描述“написать ansible скрипт”看,ldapadd方案已完全满足要求。
验证与排错
Playbook 末尾的ldapsearch会打印整个目录树。也可在目标机上手动验证:
# 列出全部条目 ldapsearch -x -H ldap://localhost -D cn=admin,dc=example,dc=com \ -w 'ChangeMe!2024' -b dc=example,dc=com "(objectClass=*)" # 只查用户(uid + cn) ldapsearch -x -LLL -b dc=example,dc=com \ "(&(objectClass=inetOrgPerson))" uid cn # 只查组 ldapsearch -x -LLL -b dc=example,dc=com \ "(objectClass=posixGroup)" cn memberUid # 验证绑定身份 ldapwhoami -x -D cn=admin,dc=example,dc=com -w 'ChangeMe!2024'常见错误与处理:
| 现象 | 原因 | 处理 |
|---|---|---|
ldap_bind: Invalid credentials (49) | 管理员 DN 或密码不对 | 核对ldap_admin_dn与 debconf 预置的密码 |
Already exists (68) | 重复导入同一条目 | 换ldapmodify或先 search 判重 |
No such object (32) | base DN 或容器ou不存在 | 确认dc与ou=people/ou=groups已创建 |
ldap_add: Insufficient access (50) | 绑定 DN 权限不足 | 确认使用cn=admin,<base_dn>绑定 |
| 连接被拒 | slapd 未启动 | systemctl status slapd,ss -ltn | grep 389检查 389 端口 |
如需在目标机上确认服务与端口:
systemctl status slapd ss -ltn | grep 389 # LDAP 默认端口 389按任务要求补齐 README 与截图
任务的交付要求是三件套:描述、运行所需全部命令、结果截图。这是候选人解决方案的一部分(注意:本仓库是只读题库,README 指你交付物中的说明文档,并非要修改仓库根 README)。README 模板如下:
# OpenLDAP 部署(Ansible) ## 任务目标 在 Ubuntu LTS 上通过 Ansible 完成:安装 OpenLDAP、设置管理员密码、 设置 domain/organization、添加 2 个用户与 2 个组。 ## 环境 - 控制机:装有 ansible-core 的任意 Linux/macOS - 目标机:Ubuntu LTS(22.04/24.04),SSH + sudo 可用 ## 运行步骤 1. 编辑 inventory.ini,填入目标机 IP 与用户名; 2. 修改 playbook.yml 顶部 vars(domain、organization、管理员密码); 3. 执行语法检查: ansible-playbook -i inventory.ini playbook.yml --syntax-check 4. 运行部署: ansible-playbook -i inventory.ini playbook.yml ## 验证命令 ldapsearch -x -LLL -b dc=example,dc=com "(objectClass=*)" ## 结果截图 (插入 ldapsearch 输出的截图)截图建议截取ldapsearch输出的完整目录树(应能看到ou=people、ou=groups、2 个用户、2 个组共 6 条记录),一张图即可证明全部需求落地。
扩展思考与同类任务对比
- 密码安全:playbook 中
ldap_admin_password为明文变量,交付时可改为ansible-vault encrypt加密变量文件,或从环境中读取(lookup('env', ...)),避免口令入库。 - 同系列任务横向参考:Peacock Team 的另外两道 DevOps 题——devops-docker.md(Docker Compose 起 3 节点 Cassandra 集群并配置跨机 SSH)与 devops-astra.md(基于 AstraLinux 1.8 制作支持
systemctl的镜像)——与本题一起构成“自动化部署三板斧”:配置管理(Ansible)、容器编排(Docker)、国产系统适配(AstraLinux)。做完全部三道,基本覆盖了初级 DevOps 岗位笔试的高频考点。
总而言之,这道题考察的并不只是“会装 OpenLDAP”,而是候选人能否把“安装 → 无人值守配置 → 数据导入 → 验证 → 文档化”这条完整的自动化交付链路走通。把握住 debconf 预置与 LDIF 这两个技术支点,用上文 playbook 即可在 Ubuntu LTS 上复现全部任务要求。
- 教程
【免费下载链接】ru-test-assignments
Тестовые задания для самостоятельного выполнения от разных it компаний
相关推荐
5分钟快速上手:跨平台资源下载神器res-downloader完整指南
5分钟快速上手:跨平台资源下载神器res downloader完整指南 你是否经常遇到想保存微信视频号的精彩内容却无从下手?抖音、快手上的有趣视频无法无水印下载
桌面应用网络音视频Smena DevOps 测试任务实战:FastAPI 应用容器化与 Helm/Kubernetes 多环境部署
Smena DevOps 测试任务实战:FastAPI 应用容器化与 Helm/Kubernetes 多环境部署 本文基于仓库 devops/smena/doc
教程Smena DevOps 测试任务实战:FastAPI 应用容器化与 Helm 多环境 Kubernetes 部署
Smena DevOps 测试任务实战:FastAPI 应用容器化与 Helm 多环境 Kubernetes 部署 导读 :本文以仓库 devops/smena
教程
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考