在RHEL/CentOS 8上安装Ansible的初学者指南

时间:2020-01-09 10:37:46  来源:igfitidea点击:

在本文中,我将分享在RHEL/CentOS 8 Linux环境上安装Ansible的分步教程。我们将设置一个具有一个控制器节点和两个受管节点的三节点环境。但是在我们开始在RHEL 8或者CentOS 8上安装Ansible的步骤之前,让我们了解什么是Ansible及其工作方式(如果我们还不知道的话)

什么是Ansible及其运作方式?

Ansible是一种现代化的自动化工具,可通过帮助我们管理服务器,部署和基础架构来使我们的生活更轻松。我们声明我们想要的东西,让Ansible努力工作。 Ansible可以做的一些事情如下:

  • 安装和配置软件

  • 管理用户和数据库

  • 部署应用

  • 远程执行

  • 以代码管理基础架构

与其他类似工具相比,Ansible具有某些明显的优势。

  • " Ansible是无代理的。"因此,我们不需要在要管理的服务器上安装任何软件。它确实需要服务器上的Python运行时和远程主机上的SSH服务器。

  • Ansible支持pushpull模式。因此,我们可以从中央控制机器执行Ansible代码以对远程机器进行更改,或者远程机器可以定期从定义明确的源中提取配置。

  • Ansible的代码使用YAML(http://yaml.org/)编写,代表" YAML不是标记语言"。

  • Ansible不会尝试重新发明轮子。因此,它使用SSH作为传输方式,并使用YAML作为领域特定语言(DSL)。

实验室环境

我已经创建了三个在Linux服务器上安装的Oracle Virtual Box上运行的虚拟机。

这些VM中的一个将是将在其上安装ansible的控制器,而其他两个VM将作为一个受管服务器(客户端),在该服务器上我们将使用剧本执行不同的任务。

以下是这3个VM的配置:

配置控制节点管理节点1管理节点2
主机名controller.example.comserver1. example.comserver2. example.com
操作系统CentOS 8CentOS 8CentOS 8
IP地址10.10.10.610.10.10.1210.10.10.13
需要RPMansible

python3
python3python3

步骤1:更新/etc/hosts

我们可以配置BIND DNS服务器来解析主机名,也可以使用设置中控制器和托管主机的主机名和IP详细信息更新/etc/hosts文件

[root@controller ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
10.10.10.6    controller     controller.example.com
10.10.10.12   server1        server1.example.com
10.10.10.13   server2        server2.example.com

步骤2:安装Ansible

我将分享使用不同方法在RHEL和CentOS 8上安装Ansible的步骤:

方法1:使用EPEL REPO安装CentOS 8 Ansible

对于CentOS 8安装ansible,在这种方法中,我们将显示通过EPEL存储库的安装。首先在CentOS 8 Linux节点上手动安装EPEL repo:

[root@controller ~]# dnf -y install epel-release

现在,一旦安装了epel repo,我们就可以搜索ansible软件包

# dnf search ansible
======================================= Name Exactly Matched: ansible =======================================
ansible.noarch : SSH-based configuration management, deployment, and task execution system

因此,我们现在可以使用dnf或者yum在控制器节点上安装ansible.noarchrpm

[root@controller ~]# dnf install -y ansible.noarch

方法2:使用pip安装CentOS 8 Ansible

在CentOS 8安装ansbile的下一种方法中,我们也可以使用pip。要通过pip安装ansible,请在控制器节点上安装以下rpm:

[root@controller ~]# dnf install python3 python3-pip -y

接下来使用pip3作为普通用户hynman安装ansible

[hynman@controller ~]$pip3 install ansible --user
Requirement already satisfied: ansible in /usr/lib/python3.6/site-packages
Requirement already satisfied: jinja2 in /usr/lib/python3.6/site-packages (from ansible)
Requirement already satisfied: PyYAML in /usr/lib64/python3.6/site-packages (from ansible)
Requirement already satisfied: cryptography in /usr/lib64/python3.6/site-packages (from ansible)
Requirement already satisfied: MarkupSafe>=0.23 in /usr/lib64/python3.6/site-packages (from jinja2->ansible)
Requirement already satisfied: idna>=2.1 in /usr/lib/python3.6/site-packages (from cryptography->ansible)
Requirement already satisfied: asn1crypto>=0.21.0 in /usr/lib/python3.6/site-packages (from cryptography->ansible)
Requirement already satisfied: six>=1.4.1 in /usr/lib/python3.6/site-packages (from cryptography->ansible)
Requirement already satisfied: cffi!=1.11.3,>=1.7 in /usr/lib64/python3.6/site-packages (from cryptography->ansible)
Requirement already satisfied: pycparser in /usr/lib/python3.6/site-packages (from cffi!=1.11.3,>=1.7->cryptography->ansible)

方法3:RHEL 8安装Ansible

要在RHEL 8上安装ansible,必须首先注册RHEL 8节点。现在,我已经将我的RHEL 8节点注册到Red Hat Network。

接下来,我们可以启用Red Hat Ansible Engine存储库:

# subscription-manager repos --enable ansible-VERSION-for-rhel-8-x86_64-rpms

目前,在撰写本文时," ansible-2.8.5"是最新的文章。

# subscription-manager repos --enable ansible-2.8-for-rhel-8-x86_64-rpms

接下来在RHEL 8上使用dnf安装ansible

# dnf install ansible -y

根据环境,一旦我们安装Ansible,接下来我们会看到这还将安装python3作为依赖项

[root@controller ~]# ansible --version
ansible 2.8.5
  config file = /etc/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 3.6.8 (default, Jan 21 2019, 23:51:36) [GCC 8.2.1 20160905 (Red Hat 8.2.1-3)]

步骤3:在受管节点上安装Python

现在我们不需要在托管主机上安装ansible,但是必须在所有托管主机上安装" python3":

我们可以使用dnf来搜索并安装python3软件包。我已经在两台托管主机上的rpm以下安装了dnf将处理所有依赖项的主机

[root@server2 ~]# rpm -qa | grep python36
python36-3.6.8-2.module_el8.1.0+245+c39af44f.x86_64
[root@server1 ~]# rpm -qa | grep python36
python36-3.6.8-2.module_el8.1.0+245+c39af44f.x86_64

第4步:创建普通用户

这很重要,因为我们将使用该用户执行所有与ansible相关的任务。为了这篇文章,我将创建一个用户ansible

[root@controller ~]# useradd ansible

为该用户分配密码

[root@controller ~]# passwd ansible

在受管节点上重复相同的操作,即在所有受管主机上创建相同的用户:

[root@server1 ~]# useradd ansible
[root@server1 ~]# passwd ansible
[root@server2 ~]# useradd ansible
[root@server1 ~]# passwd ansible

步骤5:创建SSH密钥并将其分发给受管节点

现在,我们必须在控制器节点和所有托管主机之间启用少密码登录。因此,我们可以使用ssh-keygen配置基于密码的登录

另请阅读:

6种SSH身份验证方法来保护连接(sshd_config)

登录或者切换用户到ansible并以以下格式执行ssh-keygen。使用-P,我们给密钥对分配一个空密码

[ansible@controller ~]$ssh-keygen -t rsa -P ""
Generating public/private rsa key pair.
Enter file in which to save the key (/home/ansible/.ssh/id_rsa):
Created directory '/home/ansible/.ssh'.
Your identification has been saved in /home/ansible/.ssh/id_rsa.
Your public key has been saved in /home/ansible/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:NYGxDBObnWXDGHpM1MtvnMQpOWS59MsVtTZFfl//Ym0 [email protected]
The key's randomart image is:
+---[RSA 2048]----+
|      +o=B=.   o+|
|       @o=Bo  ..o|
|      + B=o* . =+|
|       . .B.= o *|
|        S  B +  o|
|            B  ..|
|           .  o E|
|             . o |
|                 |
+----[SHA256]-----+

这将在主目录中的~/.ssh /下创建公钥和私钥对。现在,由于我们具有公用密钥和专用密钥对,因此可以将公用密钥复制到目标受管服务器。我们使用ssh-copy-id可以节省时间并执行启用基于密码短语的登录所需的所有任务。

[ansible@controller ~]$ssh-copy-id server1
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/ansible/.ssh/id_rsa.pub"
The authenticity of host 'server1 (10.10.10.12)' can't be established.
ECDSA key fingerprint is SHA256:RxJuKeoiMc/+4H7IO52YTFOStE3hgd7ulMwjpAVGDZs.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
ansible@server1's password:
Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'server1'"
and check to make sure that only the key(s) you wanted were added.

对其他托管主机重复相同的操作

[ansible@controller ~]$ssh-copy-id server2

还要在控制器节点上复制localhost的公钥。稍后也需要这样做。

[ansible@controller ~]$ssh-copy-id controller

减少密码验证SSH身份验证

ssh-copy-id命令将我们刚刚创建的公共密钥复制到server1和server2,并将密钥内容添加到ansible用户的~/.ssh下的authorized_keys文件中。 .ssh其中是一个隐藏目录。

我们可以对托管主机执行ssh,以确保无需输入任何密码或者密码即可连接到服务器。

[ansible@controller ~]$ssh server1
Last login: Wed Jan 29 20:24:46 2017
[ansible@server1 ~]$

这样我们就可以在没有任何密码的情况下连接到我们的" server1"托管主机。

类似地验证从控制器到其他托管主机的SSH

步骤6:使用sudo配置权限提升

由于我们的ansible用户需要特权升级,因此我们将在/etc/sudoers.d下使用新文件为ansible用户创建一条新规则。

[root@controller ~]# cat /etc/sudoers.d/ansible
ansible ALL=(ALL) NOPASSWD: ALL

在所有托管主机上添加相同规则

[root@server1 ~]# echo "ansible ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ansible
[root@server2 ~]# echo "ansible ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/ansible

步骤7:在控制器节点上配置Ansible

安装ansible后,让我们将ansible配置为运行一些临时命令。

创建自定义项目

我们将在主目录下创建一个项目" base":

[ansible@controller ~]$mkdir base

创建并配置ansible.cfg

Ansible的配置文件可以存在于几个不同的位置,这些位置将使用找到的第一个文件。搜索涉及以下内容:

  • ANSIBLE_CFG:使用此环境变量(前提是已设置)

  • ansible.cfg:位于当前目录中

  • ~/.ansible.cfg:位于用户的主目录中

  • /etc/ansible/ansible.cfg

我们将在base项目下创建一个ansible.cfg。在本文中,我们确定了如何连接远程主机。

[ansible@controller base]$cat ansible.cfg
[defaults]
remote_user = ansible          ; use ansible user
host_key_checking = false      
inventory = inventory          ; Inventory file exists in the current directory
log_path = base.log            ; base.log file will be created/used as log file
[privilege_escalation]
become = True                  ; Become someone else to perform tasks
become_method = sudo           ; use sudo
become_user = root             ; Become root user
become_ask_pass = False        , Don't ask for password with sudo

清单(Inventory)参数告诉相对的文件名,其中包含托管主机的列表。因此,我们必须在项目目录下创建一个文件"列表"。

提示:

配置文件是INI格式的一种变体。当注释开始该行时,允许将井号(#)和分号(;)用作注释标记。但是,如果注释与常规值内联,则仅允许使用分号引入注释

创建静态清单(Inventory)文件

  • 列表包含主机名或者IP地址的列表。尽管我们应该避免在列表中使用IP地址

  • " ansible.cfg"定义特权的升级方式。我们可以为每个项目创建此文件,也可以使用通用文件

  • 通常使用包含这些文件的项目目录

  • 在Ansible中,我们有静态和动态清单(Inventory)。目前,我们将仅使用静态AD资源

  • 即使在本地主机上执行的即席操作也需要列表,尽管该列表可能仅由本地主机组成。

  • 列表是Ansible体系结构的最基本构建块。

  • 执行Anansible或者Anable-Playbook时,必须参考列表。列表是运行ansible或者ansible-playbook的同一系统上存在的文件或者目录。

  • 可以在运行时使用--inventory-file(-i)参数或者在Ansibleconfig文件中定义路径来引用列表的位置。

[ansible@controller base]$cat inventory
server1.example.com
server2.example.com

要使用我们的列表文件列出匹配的主机,请使用以下命令。这不会在列表节点上执行任何命令:

[ansible@controller base]$ansible all --list-hosts
  hosts (2):
    server1.example.com
    server2.example.com

步骤8:运行临时命令

  • Ansible中的临时命令用于根据需要临时执行或者仅执行一次所需的任务或者操作。

  • 换句话说,这些是用户希望即时执行但又不想保存以备后用的任务。

  • 可以使用ansible命令调用Ansible模块

  • 使用ansible-doc -l获取模块列表,使用ansible-doc <modulename>获取有关模块选项的信息

  • 使用-m指定要使用的模块

  • 命令模块是默认模块,不必指定

另请阅读:

在编写带有示例的第一本Ansible剧本之前,我们需要了解的所有内容

例子:

ansible all -m command -a id
	ansible all -m shell -a env

在下面的示例中,我们将使用free -m命令检查托管主机上的可用内存。

[ansible@controller base]$ansible all -m shell -a "free -m"
server1.example.com | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           4789         201        4100           8         487        4353
Swap:           955           0         955
server2.example.com | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           4789         204        4102           8         482        4350
Swap:           955           0         955

接下来,我们将尝试在server1.example.com上的文件中添加一些内容

[ansible@controller base]$ansible server1.example.com -m copy -a "content='Hello, My name is hynman' dest=~/hello.txt"
server1.example.com | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/libexec/platform-python"
    },
    "changed": true,
    "checksum": "3fa09515585e1da48417b015f7bd40cd665d9cf2",
    "dest": "/root/hello.txt",
    "gid": 0,
    "group": "root",
    "md5sum": "4f5f6876ea14b5e5d005059b0112dd32",
    "mode": "0644",
    "owner": "root",
    "size": 24,
    "src": "/home/ansible/.ansible/tmp/ansible-tmp-1580546381.2696378-140602648211740/source",
    "state": "file",
    "uid": 0
}