Rocky Linux 9服务器自动化:使用Ansible实现高效初始化配置

引言

在系统管理中,服务器自动化扮演着关键角色,这得益于现代应用环境的可抛弃性。通常,我们会使用配置管理工具,例如 Ansible,来简化服务器设置的自动化流程。通过建立新服务器的标准流程,可以有效减少手动设置带来的人为错误。

Ansible 提供了简洁的架构,无需在被管理节点上安装任何特殊软件。它还提供了一系列强大的功能和内置模块,极大地促进了自动化脚本的编写。

本指南将详细阐述如何使用 Ansible 自动化我们在 Rocky Linux 9 服务器上的初始设置步骤。

先决条件

要跟随本教程,你需要:

  • 一个 Ansible 控制节点:一台安装并配置了 Ansible 的 Rocky Linux 9 机器,用于通过 SSH 密钥连接到你的 Ansible 主机。确保控制节点拥有一个具有 sudo 权限的普通用户,并且启用了防火墙,正如我们的初始服务器设置指南中所述。要设置 Ansible,请参阅我们如何在 Rocky Linux 9 上安装和配置 Ansible 指南的第 1 步。虽然通常不需要从完全相同的 Linux 版本安装到相同的目标版本(例如,本例中从 Rocky Linux 9 到 Rocky Linux 9),但这有助于保持演示的一致性。
  • 一台全新安装的 Rocky Linux 9 远程服务器:这台服务器无需任何预先设置,但你必须能够从上述 Ansible 控制节点通过 SSH 访问它。如果你尚未从 Ansible 控制节点获得对远程服务器的 SSH 访问权限,请参阅我们的如何设置 SSH 密钥教程。这台服务器将成为 Ansible 主机远程服务器,由 Ansible 控制节点进行自动化配置。

本 Ansible Playbook 有何作用?

这个 Ansible Playbook 提供了一种替代方法,可以避免每次启动服务器时手动按照《Rocky Linux 9 初始服务器设置指南》和《Rocky Linux 9 SSH 密钥设置指南》的步骤进行操作。只需设置一次 Playbook,之后每次都可以使用它来设置服务器。

运行此 Playbook 将在你的 Ansible 主机上执行以下操作:

  1. 创建一个新的 sudo 用户并设置无密码 sudo。
  2. 将本地 SSH 公钥复制并包含在远程主机上新的管理员用户的 authorized_keys 文件中(如果你之前对 SSH 使用的是密码)。
  3. 禁用 root 用户的基于密码的身份验证。
  4. 安装系统软件包。

一旦 Playbook 完成运行,你将拥有一个可用于登录服务器的新用户。

首先,在你的 Ansible 控制节点服务器上,使用具有 sudo 权限的用户登录。

步骤 1 — 准备你的 Ansible 控制节点

在你的 Ansible 控制节点服务器上,将你的 Ansible 主机远程服务器的 IP 地址添加到你的 Ansible 清单文件中。使用 vi 或你喜欢的文本编辑器,打开 Ansible 清单文件。

sudo vi /etc/ansible/hosts

打开你的 Ansible 清单文件。将你的 Ansible 主机远程服务器的 IP 地址添加到 [servers] 块中。

/etc/ansible/hosts

[servers]
server1 ansible_host=your_remote_server_ip

. . .

保存并关闭文件。

现在,你将在 Ansible 控制节点和 Ansible 主机远程服务器之间测试并验证你的 SSH 连接。

ssh root@your_remote_server_ip

接受身份验证请求,如果有提示,请输入密码。在验证 SSH 连接后,按下 CTRL+D 关闭连接并返回到你的控制节点。

步骤 2 — 准备你的 Playbook 文件

playbook.yml 文件是定义所有任务的地方。一个任务是你可以使用 Ansible Playbook 自动化的最小动作单元。使用 vi 或你喜欢的文本编辑器创建你的 Playbook 文件。

vi playbook.yml

这将打开一个空的 YAML 文件。在开始添加任务到你的 Playbook 之前,先添加以下内容:

playbook.yml

---
- hosts: all
  become: true
  vars:
    created_username: sammy

请随意用你选择的用户名替换此用户名。

几乎每个 Playbook 都会以类似的声明开始。hosts 可以声明 Ansible 控制节点将使用此 Playbook 来操作哪些服务器。become 则表明所有命令将使用提升的 root 权限来执行。

使用变量可以将数据存储在变量中。如果将来决定更改用户名,你只需编辑文件中的这一行即可。

注意:如果你想看到 Playbook 文件的最终成品,请跳到第六步。YAML 文件对缩进结构要求严格,所以在添加完所有的任务后,你可能需要再次检查你的 Playbook。

步骤 3 — 将 Sudo 用户设置任务添加到你的 Playbook 中

默认情况下,Ansible 按照 Playbook 中从上到下的顺序同步执行任务。这意味着任务的顺序很重要,你可以安全地假设一个任务在下一个任务开始之前会完成执行。

这个 Playbook 中的所有任务都可以独立存在,并且可以在你的其他 Playbook 中重复使用。

避免频繁使用 root 用户是一个良好的实践。你可以通过添加 sudo 特权来自动创建一个用户。

playbook.yml
  tasks:
    - name: 设置无密码sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s' 

    - name: 创建一个具有sudo权限的新普通用户
      user:
        name: "{{ created_username }}"
        state: present
        groups: wheel
        append: true
        create_home: true

您正在使用Ansible的lineinfile模块来定位并替换文件中的特定行。在这种情况下,您使用正则表达式来定位sudoers文件中的特定行,然后修改该行以实现sudo无需密码。您还使用visudo来验证您的更改,以防止出现任何错误。

为了利用这个功能,您正在使用user模块添加一个新用户。Ansible将确保在用户不存在时创建该用户,该用户属于“wheel”(管理员)组,同时不会从其他组中删除,还会创建一个家目录。

注意:确保您在花括号周围包含引号,这些引号表示一个变量。忽视这些引号是一个非常常见的Ansible语法错误。

第四步 — 在您的Playbook中添加SSH密钥设置和禁用Root密码任务

Ansible运行的前提是您使用SSH密钥。强烈推荐并且通常最佳实践是将SSH密钥与禁用root密码身份验证配对使用。为了自动化此过程,请添加:

剧本文件.yml

    - name: 为远程用户设置授权密钥
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: 禁用root的密码认证
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

如果您提供用户名和密钥位置,可以使用authorized_key模块。在这里,使用Ansible的lookup函数构建密钥的路径。

使用lineinfile模块可以在sshd_config中搜索和替换一行,以禁用root的密码认证,限制对其特权的访问,提高安全性。

第五步 – 向Playbook中添加软件包安装任务

Ansible可以确保您的服务器始终安装某些软件包。您不需要对每个软件包分别调用dnf install命令,也不需要将其分解为多个任务,只需列出您所有想要的软件包即可。

playbook.yml

这是文章《如何使用Ansible在Rocky Linux 9上自动设置服务器初始化》的第3部分(共4部分)。

    - name: 更新并安装所需的系统软件包
      dnf:
        pkg:
          - curl
          - vim
          - git
          - firewalld
        state: latest
        update_cache: true

您可以根据自己的喜好添加或移除软件包。这将确保所有软件包不仅存在,而且都是最新版本,并在使用 dnf 更新后执行。

第六步 – 检查你的完整策略手册

你的操作手册应该大致像下面这样,根据你的定制可能会有些微差异。

剧本.yml

---
- hosts: all
  become: true
  vars:
    created_username: sammy

  tasks:
    - name: 设置免密sudo
      lineinfile:
        path: /etc/sudoers
        state: present
        regexp: '^%sudo'
        line: '%sudo ALL=(ALL) NOPASSWD: ALL'
        validate: '/usr/sbin/visudo -cf %s'

    - name: 创建一个具有sudo权限的新普通用户
      user:
        name: "{{ created_username }}"
        state: present
        groups: wheel
        append: true
        create_home: true

    - name: 为远程用户设置授权密钥
      ansible.posix.authorized_key:
        user: "{{ created_username }}"
        state: present
        key: "{{ lookup('file', lookup('env','HOME') + '/.ssh/id_rsa.pub') }}"

    - name: 禁用root用户的密码认证
      lineinfile:
        path: /etc/ssh/sshd_config
        state: present
        regexp: '^#?PermitRootLogin'
        line: 'PermitRootLogin prohibit-password'

    - name: 更新并安装所需的系统软件包
      dnf:
        pkg:
          - curl
          - vim
          - git
          - firewalld
        state: latest
        update_cache: true

注意

注意:这是一个提醒,请留心你的缩进。如果遇到错误,很可能是因为缩进的问题。YAML建议使用两个空格作为缩进,就像在这个示例中做的那样。一旦你对你的剧本感到满意,你可以关闭文本编辑器并保存。

第七步:首次运行你的剧本

现在你已经准备好在一个或多个服务器上运行这个剧本了。大多数剧本默认配置为在清单中的每个服务器上执行,但这次你将指定你的服务器。

要仅在以root身份连接的server1上执行剧本,可以使用以下命令:

  1. ansible-playbook playbook.yml -l server1 -u root -k

-l参数指定你的服务器,-u参数指定要登录的远程服务器上的用户。由于你尚未设置远程服务器,root是你唯一的选择。如果你没有使用无密码SSH,则需要-k参数:它会提示你输入SSH密码。

你将会得到类似于这样的输出:

输出

. . . PLAY RECAP ***************************************************************************************************************************************************************************************************************************************************
server1 : ok=6 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

这表示你的服务器设置完成了!你的输出不需要完全相同,但是很重要的是你必须没有任何故障。

现在你已经为你的剧本完成了首次设置,所有后续的Ansible调用都可以使用用户sammy进行(如果你在首次设置中使用了密码,则无需-k标志)。

  1. ansible-playbook playbook.yml -l server1 -u sammy

你还可以使用以下方式登录服务器:

  1. ssh sammy@your_remote_server_ip

记住要用由created_username变量定义的用户名替换sammy,并用你的服务器主机名或IP地址替换your_remote_server_ip

结论

自动化初始服务器设置可以节省时间,同时确保服务器遵循标准配置,便于根据需要进行改进和定制。随着现代应用程序的分布式特性和不同分区环境之间需要更多的一致性,这样的自动化变得必不可少。

在本指南中,你演示了如何使用Ansible自动化执行在新服务器上应执行的初始任务,例如创建一个具有sudo访问权限的非root用户、安装软件包并禁用基于密码的远程root登录。

要了解如何运行Ansible Playbooks的更多信息,请查看我们的Ansible速查指南

如果你想在此手册中包含新的任务,以进一步自定义初始服务器设置,请参考我们的入门指南《配置管理101:编写Ansible剧本》。你还可以查看我们的指南《如何使用Ansible角色来抽象化你的基础设施环境》。

bannerAds