Skip to content

2. 安装 Ansible

主旨

  • ansible安装部署详细文档

说明

环境说明

测试环境:
软件包位置:
10.2.6.106:/home/opt
版本:
ansible-2.15.2 |202307

系统环境:
[root@node-1 opt]# cat /etc/redhat-release 
CentOS Linux release 7.9.2009 (Core)
[root@node-1 opt]# uname -a
Linux node-1 3.10.0-1160.15.2.el7.x86_64 #1 SMP Wed Feb 3 15:06:38 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

安装说明

采用二进制包文件方式

二进制安装要求:
python3.8+ python3.10之间,具体可参考:ansible的requirement.txt
python安装可以参考Python/安装,python3.9.10安装参考示例

部署

安装方式

  • 编译安装
  • rpm安装
  • yum安装
  • 二进制安装
安装方式 优点 缺点
yum安装
二进制安装
编译安装
rpm安装

下载地址

官网地址

github

release.ansible.com

编译安装配置

安装命令测试

# tar xvf ansible-2.15.2.tar.gz 
# mv ansible-2.15.2 ansible
# pwd
/home/opt/ansible
# ll
总用量 68
drwxrwxr-x 2 root root   243 7月  18 10:07 bin
drwxrwxr-x 3 root root   112 7月  18 10:07 changelogs
-rw-rw-r-- 1 root root 35148 7月  18 10:07 COPYING
drwxrwxr-x 6 root root    60 7月  18 10:07 docs
drwxrwxr-x 3 root root   191 7月  18 10:07 examples
drwxrwxr-x 8 root root  4096 7月  18 10:07 hacking
drwxrwxr-x 3 root root    21 7月  18 10:07 lib
drwxrwxr-x 2 root root   104 7月  18 10:07 licenses
-rw-rw-r-- 1 root root  1582 7月  18 10:07 MANIFEST.in
drwxrwxr-x 3 root root    46 7月  18 10:07 packaging
-rw-rw-r-- 1 root root   193 7月  18 10:07 pyproject.toml
-rw-rw-r-- 1 root root  5697 7月  18 10:07 README.rst
-rw-rw-r-- 1 root root   995 7月  18 10:07 requirements.txt
-rw-rw-r-- 1 root root  3432 7月  18 10:07 setup.cfg
-rw-rw-r-- 1 root root  1116 7月  18 10:07 setup.py
drwxrwxr-x 7 root root    78 7月  18 10:07 test
# pip3 install -r requirements.txt
Collecting jinja2>=3.0.0
  Downloading Jinja2-3.1.2-py3-none-any.whl (133 kB)
     |████████████████████████████████| 133 kB 1.1 MB/s 
Collecting PyYAML>=5.1
  Downloading PyYAML-6.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (738 kB)
     |████████████████████████████████| 738 kB 3.0 MB/s 
Collecting cryptography
  Downloading cryptography-41.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (4.3 MB)
     |████████████████████████████████| 4.3 MB 2.4 MB/s 
Collecting packaging
  Downloading packaging-23.1-py3-none-any.whl (48 kB)
     |████████████████████████████████| 48 kB 2.6 MB/s 
Collecting importlib_resources<5.1,>=5.0
  Downloading importlib_resources-5.0.7-py3-none-any.whl (24 kB)
Collecting resolvelib<1.1.0,>=0.5.3
  Downloading resolvelib-1.0.1-py2.py3-none-any.whl (17 kB)
Collecting MarkupSafe>=2.0
  Downloading MarkupSafe-2.1.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Collecting cffi>=1.12
  Downloading cffi-1.15.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (441 kB)
     |████████████████████████████████| 441 kB 2.9 MB/s 
Collecting pycparser
  Downloading pycparser-2.21-py2.py3-none-any.whl (118 kB)
     |████████████████████████████████| 118 kB 2.9 MB/s 
Installing collected packages: pycparser, MarkupSafe, cffi, resolvelib, PyYAML, packaging, jinja2, importlib-resources, cryptography
Successfully installed MarkupSafe-2.1.3 PyYAML-6.0.1 cffi-1.15.1 cryptography-41.0.2 importlib-resources-5.0.7 jinja2-3.1.2 packaging-23.1 pycparser-2.21 resolvelib-1.0.1
# pip3 install --user ansible
Collecting ansible
  Downloading ansible-8.2.0-py3-none-any.whl (45.1 MB)
     |███████████▌                    | 16.2 MB 2.4 MB/s eta 0:00:12^C
ERROR: Operation cancelled by user
WARNING: You are using pip version 21.2.4; however, version 23.2.1 is available.
You should consider upgrading via the '/usr/local/python3/bin/python3.9 -m pip install --upgrade pip' command.
[root@node-1 ansible]# pip3 install --user ansible
Collecting ansible
  Downloading ansible-8.2.0-py3-none-any.whl (45.1 MB)
     |████████████████████████████████| 45.1 MB 112 kB/s 
Collecting ansible-core~=2.15.2
  Downloading ansible_core-2.15.2-py3-none-any.whl (2.2 MB)
     |████████████████████████████████| 2.2 MB 3.1 MB/s 
Requirement already satisfied: PyYAML>=5.1 in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (6.0.1)
Requirement already satisfied: cryptography in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (41.0.2)
Requirement already satisfied: importlib-resources<5.1,>=5.0 in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (5.0.7)
Requirement already satisfied: jinja2>=3.0.0 in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (3.1.2)
Requirement already satisfied: packaging in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (23.1)
Requirement already satisfied: resolvelib<1.1.0,>=0.5.3 in /usr/local/python3/lib/python3.9/site-packages (from ansible-core~=2.15.2->ansible) (1.0.1)
Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/python3/lib/python3.9/site-packages (from jinja2>=3.0.0->ansible-core~=2.15.2->ansible) (2.1.3)
Requirement already satisfied: cffi>=1.12 in /usr/local/python3/lib/python3.9/site-packages (from cryptography->ansible-core~=2.15.2->ansible) (1.15.1)
Requirement already satisfied: pycparser in /usr/local/python3/lib/python3.9/site-packages (from cffi>=1.12->cryptography->ansible-core~=2.15.2->ansible) (2.21)
Installing collected packages: ansible-core, ansible
  WARNING: The scripts ansible, ansible-config, ansible-connection, ansible-console, ansible-doc, ansible-galaxy, ansible-inventory, ansible-playbook, ansible-pull and ansible-vault are installed in '/root/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
  WARNING: The script ansible-community is installed in '/root/.local/bin' which is not on PATH.
  Consider adding this directory to PATH or, if you prefer to suppress this warning, use --no-warn-script-location.
Successfully installed ansible-8.2.0 ansible-core-2.15.2
// 如果下载慢的情况可以指定国内源
# pip3 install --user ansible -i https://mirrors.aliyun.com/pypi/simple
Looking in indexes: https://mirrors.aliyun.com/pypi/simple
Collecting ansible
  Downloading https://mirrors.aliyun.com/pypi/packages/b4/1a/c88115997ce826c402d63da78bcbf5183a1ffe23308898eafedc5db9a8aa/ansible-8.7.0-py3-none-any.whl (48.4 MB)
     |████████████████████████████████| 48.4 MB 773 kB/s
Collecting ansible-core~=2.15.7
# pwd
/home/opt/ansible
# bin/ansible --version
Traceback (most recent call last):
  File "bin/ansible", line 11, in <module>
    from ansible.cli import CLI
ImportError: No module named ansible.cli

# /root/.local/bin/ansible --version
ansible [core 2.15.2]
  config file = /home/opt/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /root/.local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /root/.local/bin/ansible
  python version = 3.9.10 (main, Jul 27 2023, 15:15:15) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] (/usr/local/python3/bin/python3.9)
  jinja version = 3.1.2
  libyaml = True
// 可以在文件末尾处追加
# cat /etc/profile
export PATH=/root/.local/bin:$PATH
# source /etc/profile
// 思考
下载的二进制文件为何不能直接使用?
执行了pip3 install -r requirements.txt,为何查看二进制版本还是报错
// 将文件中的配置文件拷贝到本地服务器
cp /opt/ansible/examples/ansible.cfg /etc/ansible
cp /opt/ansible/examples/hosts /etc/ansible
# cat /etc/ansible/hosts 
[test]
10.2.6.103 ansible_ssh_port=22 ansible_ssh_user=root  ansible_ssh_pass=asdfghjkl
# cat /etc/ansible/ansible.cfg
[defaults]
inventory = /etc/ansible/hosts          # 指定主机清单文件的路径
remote_user = root                      # 指定远程主机的登录用户名
private_key_file = /path/to/private_key # 指定用于 SSH 认证的私钥文件路径
host_key_checking = False               # 设置是否检查主机密钥
roles_path = /etc/ansible/roles         # 指定角色文件的路径
log_path = /var/log/ansible.log         # 指定ansible日志信息路径
retry_files_enabled = False             # 设置是否启用任务重试
forks = 5                               # 指定同时在多少个主机上并行执行任务
timeout = 30                            # 设置 SSH 连接超时时间

配置文件优先级

ANSIBLE_CFG:首先,Ansible命令会先检查环境变量,及这个环境变量将指向的配置文件;
./ansible.cfg:其次,将会检查当前目录下的ansible.cfg配置文件;
~/.ansible.cfg:再次,将会检查当前用户home目录下的.ansible.cfg配置文件;
/etc/ansible/ansible.cfg:最后,将会检查在安装Ansible时自动生成的配置文件。

测试连通性

# ansible 10.2.6.103 -m ping


// 正常执行结果
# ansible 10.2.6.103 -m ping
10.2.6.103 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

常用命令介绍

ansible             //
ansible-config      //配置命令行类
ansible-console     //
ansible-galaxy      //
ansible-playbook    //
ansible-test        //
ansible-community   //
ansible-connection  //
ansible-doc         //
ansible-inventory   //
ansible-pull        //
ansible-vault       //

yum安装配置

# 安装依赖epel-release
yum -y install epel-release

# 安装ansible
yum -y install ansible

// 回顾
EPEL (Extra Packages for Enterprise Linux)是基于Fedora的一个项目,为“红帽系”的操作系统提供额外的软件包,适用于RHEL、CentOS和Scientific Linux.
# ansible常用命令
ansible               ansible-config        ansible-console-2     ansible-doc-2         ansible-galaxy-2      ansible-playbook      ansible-pull          ansible-vault
ansible-2             ansible-connection    ansible-console-2.7   ansible-doc-2.7       ansible-galaxy-2.7    ansible-playbook-2    ansible-pull-2        ansible-vault-2
ansible-2.7           ansible-console       ansible-doc           ansible-galaxy        ansible-inventory     ansible-playbook-2.7  ansible-pull-2.7      ansible-vault-2.7
# ansible --version
ansible 2.9.27
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]


// yum安装与编译安装的版本对比
# ansible --version
ansible [core 2.15.2]
  config file = /home/opt/ansible/ansible.cfg
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /root/.local/lib/python3.9/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.9.10 (main, Jul 27 2023, 15:15:15) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] (/usr/local/python3/bin/python3.9)
  jinja version = 3.1.2
  libyaml = True

项目一

简单案例入门
mkdir /etc/ansible/roles/ -p 
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all
mkdir /etc/ansible/roles/common -p
mkdir /etc/ansible/roles/exporter/{files,templates,tasks,handlers,vars,defaults,meta} -p
touch /etc/ansible/roles/exporter/{defaults,vars,tasks,meta,handlers}/main.yml
[root@node-1 ansible]# pwd
/etc/ansible
[root@node-1 ansible]# tree -LN 4
.
├── ansible.cfg     //ansible配置文件
├── group_vars      //
│   └── all             //
├── hosts                   //主机组配置
├── roles                   //角色目录
│   ├── common      //通用目录
│   └── exporter    //一个exporter应用项目示例
│       ├── defaults
│       │   └── main.yml
│       ├── files
│       ├── handlers
│       │   └── main.yml
│       ├── meta
│       │   └── main.yml
│       ├── tasks
│       │   └── main.yml
│       ├── templates
│       └── vars
│           └── main.yml
└── site.yml
# pwd
/etc/ansible/roles

# cat exporter/tasks/main.yml 
- name: ensure apache is at the latest version 
  yum: pkg={{ pkg }} state=latest

# cat exporter/vars/main.yml 
pkg: httpd
# pwd
/etc/ansible
# cat site.yml 
- hosts: 10.2.6.103
  remote_user: root
  roles:
     - exporter
# ansible-playbook site.yml 

PLAY [10.2.6.103] **********************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************
ok: [10.2.6.103]

TASK [exporter : ensure apache is at the latest version] *******************************************************************************************************************************
changed: [10.2.6.103]

PLAY RECAP *****************************************************************************************************************************************************************************
10.2.6.103                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
// 待部署服务器安装前后的版本对比
[root@master-1 ~]# rpm -qa | grep httpd
httpd-tools-2.4.6-97.el7.centos.5.x86_64
[root@master-1 ~]# 
[root@master-1 ~]# rpm -qa | grep httpd
httpd-2.4.6-99.el7.centos.1.x86_64
httpd-tools-2.4.6-99.el7.centos.1.x86_64
tasks目录:角色需要执行的主任务文件放置在此目录中,默认的主任务文件名为main.yml,当调用角色时,默认会执行main.yml文件中的任务,你也可以将其他需要执行的任务文件通过include的方式包含在tasks/main.yml文件中。
handlers目录:当角色需要调用handlers时,默认会在此目录中的main.yml文件中查找对应的handler
defaults目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,通常,defaults/main.yml文件中的变量都用于设置默认值,以便在你没有设置对应变量值时,变量有默认的值可以使用,定义在defaults/main.yml文件中的变量的优先级是最低的。
vars目录:角色会使用到的变量可以写入到此目录中的main.yml文件中,看到这里你肯定会有疑问,vars/main.yml文件和defaults/main.yml文件的区别在哪里呢?区别就是,defaults/main.yml文件中的变量的优先级是最低的,而vars/main.yml文件中的变量的优先级非常高,如果你只是想提供一个默认的配置,那么你可以把对应的变量定义在defaults/main.yml中,如果你想要确保别人在调用角色时,使用的值就是你指定的值,则可以将变量定义在vars/main.yml中,因为定义在vars/main.yml文件中的变量的优先级非常高,所以其值比较难以覆盖。
meta目录:如果你想要赋予这个角色一些元数据,则可以将元数据写入到meta/main.yml文件中,这些元数据用于描述角色的相关属性,比如 作者信息、角色主要作用等等,你也可以在meta/main.yml文件中定义这个角色依赖于哪些其他角色,或者改变角色的默认调用设定,在之后会有一些实际的示例,此处不用纠结。
templates目录: 角色相关的模板文件可以放置在此目录中,当使用角色相关的模板时,如果没有指定路径,会默认从此目录中查找对应名称的模板文件。
files目录:角色可能会用到的一些其他文件可以放置在此目录中,比如,当你定义nginx角色时,需要配置https,那么相关的证书文件即可放置在此目录中。

项目二

# ansible 批量部署prometheus node_exporter探针在不同服务器
https://github.com/cloudalchemy/ansible-node-exporter

拓展知识

软件包目录文件结构

# tree -LN 2
.
├── bin
│   ├── ansible -> ../lib/ansible/cli/adhoc.py
│   ├── ansible-config -> ../lib/ansible/cli/config.py
│   ├── ansible-connection -> ../lib/ansible/cli/scripts/ansible_connection_cli_stub.py
│   ├── ansible-console -> ../lib/ansible/cli/console.py
│   ├── ansible-doc -> ../lib/ansible/cli/doc.py
│   ├── ansible-galaxy -> ../lib/ansible/cli/galaxy.py
│   ├── ansible-inventory -> ../lib/ansible/cli/inventory.py
│   ├── ansible-playbook -> ../lib/ansible/cli/playbook.py
│   ├── ansible-pull -> ../lib/ansible/cli/pull.py
│   ├── ansible-test -> ../test/lib/ansible_test/_util/target/cli/ansible_test_cli_stub.py
│   └── ansible-vault -> ../lib/ansible/cli/vault.py
├── changelogs
│   ├── CHANGELOG.rst
│   ├── CHANGELOG-v2.15.rst
│   ├── changelog.yaml
│   ├── config.yaml
│   └── fragments
├── COPYING
├── docs
│   ├── bin
│   ├── docsite
│   ├── man
│   └── templates
├── examples
│   ├── ansible.cfg
│   ├── DOCUMENTATION.yml
│   ├── hosts
│   ├── hosts.yaml
│   ├── hosts.yml -> hosts.yaml
│   ├── inventory_script_schema.json
│   ├── play.yml
│   ├── plugin_filters.yml
│   └── scripts
├── hacking
│   ├── ansible-profile
│   ├── azp
│   ├── backport
│   ├── build-ansible.py
│   ├── build_library
│   ├── create_deprecation_bug_reports.py
│   ├── deprecated_issue_template.md
│   ├── env-setup
│   ├── env-setup.fish
│   ├── fix_test_syntax.py
│   ├── get_library.py
│   ├── README.md
│   ├── report.py
│   ├── return_skeleton_generator.py
│   ├── templates
│   ├── test-module -> test-module.py
│   ├── test-module.py
│   ├── tests
│   ├── ticket_stubs
│   └── update-sanity-requirements.py
├── lib
│   └── ansible
├── licenses
│   ├── Apache-License.txt
│   ├── MIT-license.txt
│   ├── PSF-license.txt
│   └── simplified_bsd.txt
├── MANIFEST.in
├── packaging
│   ├── pep517_backend
│   └── release.py
├── pyproject.toml
├── README.rst
├── requirements.txt
├── setup.cfg
├── setup.py
└── test
    ├── integration
    ├── lib
    ├── sanity
    ├── support
    └── units

问题排错

项目一可能遇到的问题

# ansible 10.2.6.103 -m ping
10.2.6.103 | FAILED! => {
    "msg": "to use the 'ssh' connection type with passwords or pkcs11_provider, you must install the sshpass program"
}
# yum install -y sshpass
Downloading packages:
sshpass-1.06-2.el7.x86_64.rpm                                                                                                                                  |  21 kB  00:00:00     
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
  正在安装    : sshpass-1.06-2.el7.x86_64                                                                                                                                         1/1 
  验证中      : sshpass-1.06-2.el7.x86_64                                                                                                                                         1/1 
已安装:
  sshpass.x86_64 0:1.06-2.el7                                                                                                                                                         
完毕
# ansible 10.2.6.103 -m ping
10.2.6.103 | UNREACHABLE! => {
    "changed": false,
    "msg": "Failed to connect to the host via ssh: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @\r\n@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\nIT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!\r\nSomeone could be eavesdropping on you right now (man-in-the-middle attack)!\r\nIt is also possible that a host key has just been changed.\r\nThe fingerprint for the ECDSA key sent by the remote host is\nSHA256:OOGUM3YE0kGcdmI7CQZBP+AlDxCUOojx+iQMDlwEiKo.\r\nPlease contact your system administrator.\r\nAdd correct host key in /root/.ssh/known_hosts to get rid of this message.\r\nOffending ECDSA key in /root/.ssh/known_hosts:2\r\nECDSA host key for 10.2.6.103 has changed and you have requested strict checking.\r\nHost key verification failed.",
    "unreachable": true
}
# ansible 10.2.6.103 -m ping
10.2.6.103 | FAILED! => {
    "msg": "Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this.  Please add this host's fingerprint to your known_hosts file to manage this host."
}
// 错误原因:登录时提示交互模式,密码yes,可以手动登录一次,不建议!或者在配置文件增加,这里我其实已经增加
// 继续定位,刚才目录中有模版ansible.cfg文件且为空,所以等同于没有配置host_key_checking = False,原因是ansible.cfg文件有优先级
// 正常执行结果
# ansible 10.2.6.103 -m ping
10.2.6.103 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "ping": "pong"
}

历史事件

2023-07-27|创建说明文档