☰
Peacock Team DevOps 测试任务实战:用 Ansible 在 Ubuntu LTS 上部署与配置 OpenLDAP 服务器
2026/10/10 1:56:20 网站建设 项目流程
  • 教程

【免费下载链接】ru-test-assignments

Тестовые задания для самостоятельного выполнения от разных it компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载

本指南围绕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 脚本实现以下功能:

  1. 在 Ubuntu LTS 操作系统上安装 OpenLDAP 服务器;
  2. 在 LDAP 中设置管理员密码;
  3. 在 LDAP 中设置 domain 与 organization;
  4. 在 LDAP 中添加 2 个用户;
  5. 在 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 与 organizationdebconf 键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),不要求目标包已安装,因此正确的顺序是:

  1. 用debconf预置全部安装提问的答案;
  2. 用apt安装slapd、ldap-utils,安装过程自动读取预置答案,全程无交互;
  3. 兜底执行一次dpkg-reconfigure -f noninteractive slapd,确保即使安装时错过预置也能拿到正确配置;
  4. 用service模块确认slapd服务启动并开机自启。

slapd 的 debconf 参数表

Debian/Ubuntu 的slapd包通过以下 debconf 键(模板内置于包内)控制安装行为,这是任务第 2、3 条的直接落点:

debconf 键vtype作用说明
slapd/backendselect存储后端新版默认MDB(推荐),HDB/BDB已废弃
slapd/domainstringLDAP 域名,决定 base DN如example.com→dc=example,dc=com
slapd/organizationstring组织名称如Example Inc.
slapd/password1password管理员密码与 password2 必须一致
slapd/password2password管理员密码确认—
slapd/no_configurationboolean是否跳过配置false表示正常配置
slapd/allow_ldap_v2boolean是否允许 LDAPv2 协议默认false,安全起见保持关闭
slapd/purge_databaseboolean重配置时是否清空旧库仅当机器上已存在旧库时出现

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: bob

posixGroup的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_lines

ldapadd参数含义:-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 компаний

项目地址:https://gitcode.com/gh_mirrors/ru/ru-test-assignments
点击查看免费下载
上一篇:5分钟掌握binlog2sql的终极数据恢复方案:从误删到闪回的完整指南
下一篇:英雄联盟终极自动化神器:League Akari完整攻略指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询