运维工具Ansible部署、配置

一、基础介绍

1、简介

ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:

(1)、连接插件connection plugins:负责和被监控端实现通信;

(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;

(3)、各种模块核心模块、command模块、自定义模块;

(4)、借助于插件完成记录日志邮件等功能;

(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。

2、总体架构

3、特性

(1)、no agents:不需要在被管控主机上安装任何客户端;

(2)、no server:无服务器端,使用时直接运行命令即可;

(3)、modules in any languages:基于模块工作,可使用任意语言开发模块;

(4)、yaml,not code:使用yaml语言定制剧本playbook;

(5)、ssh by default:基于SSH工作;

(6)、strong multi-tier solution:可实现多级指挥。

4、优点

(1)、轻量级,无需在客户端安装agent,更新时,只需在操作机上进行一次更新即可;

(2)、批量任务执行可以写成脚本,而且不用分发到远程就可以执行;

(3)、使用python编写,维护更简单,ruby语法过于复杂;

(4)、支持sudo。

5、任务执行流程

二、Ansible基础安装与配置

使用Ansible管理您的AWS资源,官方文档:​​ ​https://www.freecodecamp.org/news/ansible-manage-aws/

2-1、yum源安装

配置epel 源后,可以直接通过yum 进行安装。

  • centos,默认在源里没有ansible,不过在 fedora epel源里有ansible:

    wget http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
    rpm -ivh epel-release-6-8.noarch.rpm
    yum install ansible

  • Amazon Linux,默认在源里没有ansible:

    amazon-linux-extras install epel
    yum -y install ansible
    rpm -qa | grep ansible //查看是否已安装成功

2-2、pip安装

###如果pip您的系统上尚不可用,请运行以下命令进行安装:
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user

###使用pip安装最新版本的ansible
#一旦pip安装,您可以安装Ansible:
python -m pip install --user ansible

#为了使用需要的paramiko连接插件或模块paramiko,请安装所需的模块1:
python -m pip install --user paramiko

#如果要全局安装 Ansible,请运行以下命令:
sudo python get-pip.py
sudo python -m pip install ansible

#指定版本安装
sudo python -m pip install ansible-core==2.11.6

#卸载
sudo python -m pip uninstall ansible

2-3、Ubuntu 安装

配置 PPA 或者安装 Ansible:

sudo apt update
sudo apt install software-properties-common
sudo apt-add-repository --yes --update ppa:ansible/ansible
sudo apt install ansible

2-4、源码安装

(1)、安装devtoolset

yum groupinstall "Development tools"

(2)、安装编译Python需要的包

yum install gcc zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel libffi-devel

(3)、python2.7安装

bash 复制代码
wget https://www.python.org/ftp/python/2.7.14/Python-2.7.14.tgz
tar xvzf Python-2.7.14.tgz
cd Python-2.7.14
./configure
make && make altinstall(altinstall在安装时会区分已存在的版本)(解决libpython2.7.so.1.0办法:vi /etc/ld.so.conf 添加/usr/local/lib,然后ldconfig)
mv /usr/bin/python /usr/bin/python2.6.6
ln -s /usr/local/bin/python2.7 /usr/bin/python
## 将python头文件拷贝到标准目录,以避免编译ansible时,找不到所需的头文件
cd /usr/local/include/python2.7/
cp -a ./* /usr/include/
## 修改yum脚本,使其指向旧版本的python,已避免其无法运行
vim /usr/bin/yum
#!/usr/bin/python  -->  #!/usr/bin/python2.6.6

(4)、setuptools模块安装

bash 复制代码
wget https://pypi.python.org/packages/2.7/s/setuptools/setuptools-0.6c11-py2.7.egg  --no-check-certificate 
chmod +x setuptools-0.6c11-py2.7.egg 
sh setuptools-0.6c11-py2.7.egg

(5)、pycrypto模块安装

bash 复制代码
wget https://pypi.python.org/packages/source/p/pycrypto/pycrypto-2.6.1.tar.gz
tar zxvf pycrypto-2.6.1.tar.gz
cd pycrypto-2.6.1
python setup.py install
cd ..

(6)、PyYAML模块安装

bash 复制代码
##安装libyaml
wget http://pyyaml.org/download/libyaml/yaml-0.1.5.tar.gz
tar zxvf yaml-0.1.5.tar.gz
cd yaml-0.1.5
./configure --prefix=/usr/local
make --jobs=`grep processor /proc/cpuinfo | wc -l`
make install
cd ..
##安装PyYAML
wget http://pyyaml.org/download/pyyaml/PyYAML-3.11.tar.gz
tar zxvf PyYAML-3.11.tar.gz
cd PyYAML-3.11
python setup.py install
cd ..

(7)、Jinja2模块安装

##安装MarkupSafe

wget https://pypi.python.org/packages/source/M/MarkupSafe/MarkupSafe-0.9.3.tar.gz
tar zxvf MarkupSafe-0.9.3.tar.gz
cd MarkupSafe-0.9.3
python setup.py install
cd ..
##安装Jinja
wget https://pypi.python.org/packages/source/J/Jinja2/Jinja2-2.7.3.tar.gz
tar zxvf Jinja2-2.7.3.tar.gz
cd Jinja2-2.7.3
python setup.py install
cd ..

(8)、paramiko模块安装

##安装ecdsa
wget https://pypi.python.org/packages/source/e/ecdsa/ecdsa-0.11.tar.gz
tar xvzf ecdsa-0.11.tar.gz
cd ecdsa-0.11
python setup.py install
cd ..
##安装paramiko
wget https://pypi.python.org/packages/2b/27/b64860e7b208ff1dd36fe208d07bca1f9637a11fe733e2f2ceea587c3f75/paramiko-1.7.5.zip
unzip paramiko-1.7.5.zip
cd paramiko-1.7.5
python setup.py install
cd ..

(9)、simplejson模块安装

wget https://pypi.python.org/packages/08/48/c97b668d6da7d7bebe7ea1817a6f76394b0ec959cb04214ca833c34359df/simplejson-3.11.1.tar.gz
tar zxvf simplejson-3.11.1.tar.gz
cd simplejson-3.11.1
python setup.py install
cd ..(10)、ansible安装
wget https://github.com/ansible/ansible/archive/stable-2.3.zip
unzip stable-2.3.zip
cd ansible-stable-2.3/
python setup.py install

2、Ansible配置

配置用户名密码

(1)、使用examles包做为默认配置,具体如下:

mkdir -p /etc/ansible
cp -r examples/* /etc/ansible/
ls /etc/ansible/
ansible.cfg  DOCUMENTATION.yml  hosts  hosts.yaml  hosts.yml  playbooks  scripts

(2)、ansible配置

# mkdir -p /etc/ansible
# vim /etc/ansible/ansible.cfg

remote_port = 36000

[defaults]
# 跳过 ssh 首次连接提示验证部分。
host_key_checking = False
......

(3)、使用默认示例配置文件后,先备份文件,编辑/etc/ansible/hosts文件:

cp /etc/ansible/hosts /etc/ansible/hosts.bak 

vim /etc/ansible/hosts   
...... 
[all:children]
test
dev

[test]
#设置主机的默认连接用户,及密码
172.16.52.236 ansible_ssh_user=root ansible_ssh_pass=test
 
#设置ssh的连接方式,默认是openssh。官网推荐用openssh,因为paramiko查询key的时候,很耗时,效率不高。
172.16.52.226 ansible_connection=paramiko

[dev]
#给主机取个别名"qsh_test",如果ssh默认端口不是22,这里可以指定特定的端口
qsh_test ansible_ssh_host=172.16.52.100 ansible_ssh_port=21100

#指定ssh端口也可以像下面这么指定。
172.16.52.23[1:9]:22

---------------------------------------
注:
1、all这个组包含俩子组分别是下面的test,和dev
2、以上两种指定ssh端口方法,只针对我们有少部分的主机是特殊端口,配置文件里有个选项,改成我们需要的端口就OK了,修改后对全局有效
grep "remote_port" /etc/ansible/ansible.cfg remote_port = 22    
3、172.16.52.236可以在不同的组中。在现实当中就像我一台服务器即可以装mysql也可以装apache是一个道理。
4、后面的用户和密码项是非必须的,在配置key认证的情况下,不使用密码也可以直接操作 。
未使用key的,也可以在ansible通过 -k参数在操作前询问手动输入密码。

(4)、列出目标组里的主机清单。

ansible <group_name>|host --list-host

ansible有两个默认组:

  • all:包含每个主机;
  • ungrouped:包含的主机仅属于all组且不属于其他任何组;

(5)、修改默认远程端口号

  • 配置文件里有个选项,改成我们需要的端口就OK了,修改后对全局有效;

    lixc@ansible:~$ grep "remote_port" /etc/ansible/ansible.cfg
    remote_port = 2222

  • 可在主机名之后加上端口号,用冒号分割;

    app.example.com:2222

(6)、匹配主机、主机组。

  • 如果要添加大量格式类似的主机,不用列出每个主机名:在看一组相似的```
    hostname或者ip,可简写如下:

    [webservers]
    www[01:50].example.com

方括号[01:50]也可写为[1:50],表示从www1 到www50,webservers共有50台主机;

  • 定义字母范围简写模式

    [databases]
    db-[a:f].example.com

表示从db-a到db-f,共6台主机;

  • 如下写法分别表示一个或多个groups,多组之间以冒号分割表示或的关系;这意味着一个主机可以同时存在多个组;

    webservers
    webservers:databases

  • 排除一个特定组,如下示例中,所有执行命令的主机必须隶属webservers组但同时不在databases组中;

    webservers:!databases

  • 指定两个组的交集,如下实例中,所有执行命令的主机必须隶属webservers组和appservers组中;

    webservers:&appservers

  • 或者更复杂,如下实例中,webservers组和databases组中隶属于appservers组并且不属于test组的主机才执行命令;

    webservers:databases:&appservers:!test

  • 单个hostname、IP、groups都支持通配符,同时也支持通配和groups的混合使用;

    *.example.com
    .com
    one
    .com:appservers

  • 也可以在groups中选择对应编号的server和一部分servers;

    webservers[0] #匹配webservers组的第1个主机
    webservers[0-25] #匹配webservers组的第1-26台主机

  • 大多数人会使用正则表达式匹配,只需要以~开头即可;

    ~(web|db).*.example.com

  • 也可以使用 --limit标记来添加排除条件,ansible 和 ansible-playbook都支持;

    ansible-playbook nginx.yml --limit appserver02

  • 通过文件读取hosts,文件名以@为前缀即可;

    ansible-playbook nginx.yml --limit @limit.txt --list-host

(7)、通过以下方式验证ansible是否可用,有结果输出,证明安装成功。

ansible test -a 'uptime'
172.16.52.236 | SUCCESS | rc=0 >>
 18:33:05 up 7 days,  8:07,  1 user,  load average: 0.06, 0.05, 0.00

172.16.52.226 | SUCCESS | rc=0 >>
 18:33:05 up 7 days,  8:08,  1 user,  load average: 0.00, 0.00, 0.00

报错:"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).\r\n"

解决:

提示需要安装sshpass,安装sshpass,sshpass也是epel源提供的

[root@ansible~]# yum install -y sshpass

3、SSH免密钥登录设置

(1)、生成公钥/私钥

ssh-keygen -t rsa -P ''

写入信任文件(把本地的ssh公钥文件安装到远程主机对应的账户下):

ssh-copy-id -i ~/.ssh/id_rsa.pub <remote-host>

(2)、ansible配置

  • 修改ansible配置文件

    vim /etc/ansible/ansible.cfg

    private_key_file = /root/.ssh/id_rsa_ansible

  • 添加host文件

bash 复制代码
# vim hosts
############################################################
[test]
<remote-host>  ansible_ssh_port=22  ansible_ssh_private_key_file=/root/.ssh/id_rsa_ansible

(3)、简单测试

ansible test -m command -a 'uptime'

说明:第一次运行时,需要输入一下"yes"【进行公钥验证】,后续无需再次输入。

说说ansible的工作流程吧,工作流程差不多是这样的

  1. ansible通过OPENSSH或者python的pramamiko连接客户端

  2. 把ansible module推送到客户端。推送到客户端哪里的呢,请看

    [root@qsh_server ansible]# grep "remote_tmp" /etc/ansible/ansible.cfg
    remote_tmp = $HOME/.ansible/tmp
    [root@qsh_server ansible]# ansible test -a "ls ~/.ansible"
    172.16.52.236 | SUCCESS | rc=0 >>
    tmp

3.通过ssh执行客户端上的ansible module

4.执行完毕

5.删除刚刚推送过去的ansible module

4、常用模块使用

请查看:Ansible常用模块

5、一些概念补充

playbook的组成:playbook是由一个或多个"play"组成的列表,可以让它们联同起来按事先编排的机制执行;所谓task无非是调用ansible的一个module,而在模块参数中可以使用变量;模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致;

执行模型:task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在顺序运行某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在修改playbook后重新执行一次即可;

task组成:每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出;

notify指定handler的执行机制:"notify"这个action可用于在每个play的最后被触发,在notify中列出的操作称为handler,仅在所有的变化发生完成后一次性地执行指定操作。

错误小结

"module_stdout": "/bin/sh: 1: /usr/bin/python2.7: not found\r\n"

解决方法:

  • 命令指定Python3

    ansible-playbook --version -e 'ansible_python_interpreter=/usr/bin/python3'

  • host主机文件指定

    vim /etc/ansible/hosts

    127.0.0.1 ansible_python_interpreter=/usr/bin/python3

  • vars 指定环境变量

    • name: Common package
      hosts: all
      gather_facts: no
      vars:
      ansible_python_interpreter: /usr/bin/python3
      roles:
      • { role: python, tags: [ init, python, common, addusers] }

[WARNING]: sftp transfer mechanism failed on [xx]. Use ANSIBLE_DEBUG=1 to see detailed information

解决方法:

一、修改sshd_config文件,取消注释Subsystem sftp /usr/lib/ssh/sftp-server

Subsystem      sftp    /usr/lib/ssh/sftp-server

当该行注释时,表示禁用sftp,需取消注释启用,修改配置后重启sshd服务

二、当sftp已启用时,报错仍然存在,修改ansible配置文件,添加scp_if_ssh=True

vi /etc/ansible/ansible.cfg

[ssh_connection]
scp_if_ssh=True

重新执行ansible,报错不存在了

一些学习资料

相关推荐
x_ SpiderMan20 分钟前
nfs服务器
运维·服务器
艾4424 分钟前
nfs服务器--RHCE
运维·服务器
ling-4527 分钟前
Javaweb-day12(登录认证)
服务器·前端·servlet
Parrot 安全小子32 分钟前
shell编程--永久环境变量和字符串显位
linux·运维·服务器
mit6.82437 分钟前
[Docker#11] 容器编排 | .yml | up | 实验: 部署WordPress
运维·后端·docker·云原生·容器
喵叔哟1 小时前
重构代码之内联类
服务器·重构
@大迁世界1 小时前
通过覆盖原型属性拦截 XMLHttpRequest 响应
运维·服务器
努力学习的小廉2 小时前
初识Linux—— 基本指令(上)
linux·服务器
skywalk81632 小时前
三周精通FastAPI:42 手动运行服务器 - Uvicorn & Gunicorn with Uvicorn
运维·服务器·fastapi·gunicorn
我言秋日胜春朝★2 小时前
【Linux】环境变量
linux·运维·服务器