Python之Ansible

Ansible简介

  • Ansible是一个配置管理和配置工具,类似于Chef,Puppet或Salt
  • 这是一款很简单也很容易入门的部署工具,它使用SSH连接到服务器并运行配置好的任务
  • 服务器上不用安装任何多余的软件,只需要开启ssh,所有工作都交给client端的ansible负责

安装ansible

  • 在线安装
[root@localhost ~]#	yum install -y ansible
  • 创建ansible工作目录
[root@bogon ~]# mkdir /root/myansi/
  • 创建配置文件
[root@bogon ~]# cd /root/myansi/
[root@bogon myansi]# cat	ansible.cfg
[defaults]
inventory	= hosts
remote_user = root
  • 声明被管理主机
[root@bogon myansi]# cat hosts	
[myself]
localhost
[webservers]
node1.cn
  • 配置名称解析
[root@bogon myansi]# cat	/etc/hosts
127.0.0.1			localhost.localdomain localhost
192.168.113.134	node1.cn		node1
  • 添加远程主机密钥到信任列表
[root@bogon myansi]# ssh-keyscan localhost 127.0.0.1	node1.cn	
192.168.113.134 >> /root/.ssh/known_hosts
  • 测试
#加-k是进入交互式密码,免密不需要加-k
[root@bogon myansi]# ansible all -m	 ping -k
SSH	password:	
localhost |	SUCCESS	=>	{
"changed":	false,	
"ping":	"pong"
}
node1.cn	| SUCCESS	=>	{
"changed":	false,	
"ping":	"pong"
}

Ansible应用

使用playbook
  • Playbooks是Ansible的配置、部署、编排语言。
  • 它们可以被描述为一个需要希望远程主机执行命令的方案,或者一组程序运行的命令集合
  • Playbook由一到多个Play组成
  • 每个play可以指定哪些主机执行哪些任务
  • 执行任务一般通过调用模块来实现
Yaml简介
  • Playbooks的格式是YAML
  • 语法做到最小化,意在避免 playbooks 成为一种编程语言或是脚本
  • 使用 YAML 是因为它像 XML 或 JSON 是一种利于人们读写的数据格式
Yaml语法
  • 每一个 YAML 文件都是从一个列表开始
  • 列表中的每一项都是一个键值对, 通常它们被称为一个“哈希 或“字典”
  • 所有的 YAML 文件开始行都应该是 —。这是 YAML 格式的一部分,表明一个文件的开始
  • 列表中的所有成员都开始于相同的缩进级别,并且使用一个 "- " 作为开头(一个横杠和一个空格)
  • 一个字典是由一个简单的 键: 值 的形式组成(冒号后面必须是一个空格)
配置VIM
  • Yaml的缩进不能使用tab键
  • 建议缩进为两个空格
  • 为了实现yml文件按tab键缩进两个空格,可以按以下方式对vim进行定制
[root@bogon myansi]# cat	~/.vimrc
autocmd FileType yaml setlocal sw=2	ts=2	et	ai
使用模块
  • Ansible的模块实际上就是一个个的python程序文件
  • Ansible执行任务就是通过调用这些模块来完成的
  • 查看模块列表
[root@bogon myansi]# ansible-doc -l
  • 查看模块帮助
[root@bogon myansi]# ansible-doc yum

编写playbook,在web服务器上安装httpd服务

[root@bogon myansi]# vim	install_web.yml
Ansible编程基础
执行playbook
  • 检查语法
[root@bogon myansi]# ansible-playbook --syntax-check install_web.yml
  • 执行
[root@bogon myansi]# ansible-playbook install_web.yml -k

配置lamp分离结构

# vim lamp.yml
---
- name: configure webservers
  hosts: webservers
  tasks:
    - name: install web pkgs
      yum:
        name: [httpd, php, php-mysql]
        state: present
    - name: configure web service
      service:
        name: httpd
        state: started
        enabled: yes

- name: configure dbservers
  hosts: dbservers
  tasks:
    - name: install db pkgs
      yum:
        name: mariadb-server
        state: present
    - name: configure db service
      service:
        name: mariadb
        state: started
        enabled: yes
# ansible-playbook lamp.yml
命名元组
  • 命名元组与普通元组一样,有相同的表现特征,其添加的功能就是可以根据名称引用元组中的项
  • collections 模块提供了namedtuple()函数,用于创建自定义的元组数据类型
>>>	from collections import	namedtuple
>>>	user = namedtuple('user', ['name',	'age'])
>>>	bob	= user('Bob	Green',	23)
>>>	bob[0]
'Bob Green'
>>>	bob[1]
23
>>>	bob.name
'Bob Green'

ansible-cmdb

可以将服务器的信息以web形式展现

# 在虚拟环境中安装ansible-cmdb
# pip3 install ansible-cmdb_pkgs/*
# 或在线安装
# pip3 install ansible-cmdb

# 获取远程主机的信息
# ansible all -m setup --tree /tmp/servers
# ls /tmp/servers

# ansible-cmdb分析获取的信息文件,生成html文件
# ansible-cmdb /tmp/servers > /tmp/servers.html
# firefox /tmp/servers.html
Ansible常用属性
  • from ansible.parsing.dataloader import DataLoader
    用来加载解析yaml文件或JSON内容,并且支持vault的解密
  • from ansible.vars.manager import VariableManager
    管理变量的类,包括主机,组,扩展等变量
  • from ansible.inventory.manager import InventoryManager
    用于创建主机清单,主机清单的源采用配置文件或是逗号分开主机名字符串
  • from ansible.playbook.play import Play
    用于创建play对象,能够通过play_source提供的信息自动创建任务对象
  • from ansible.executor.task_queue_manager import TaskQueueManager
    用于处理进程池中的多进程。队列管理器负责加载play策略插件,以便在选定的主机上执行任务
  • import ansible.constants as C
    存储ansible一些预定义变量
ad-hoc模式
使用TaskQueueManager
  • 创建TaskQueueManager实例,用于管理子进程、通过主机列表和任务建立对象
  • TaskQueueManager需要主机清单参数、主机变量参数、连接选项等
导入模块
  • 不管是执行ad-hoc还是playbook都需要以下模块
#!/usr/bin/env python
import shutil
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
import ansible.constants as C
设置参数
  • 运行命令时有很多参数要指定,这些参往往很长,可以先把它们提前定义出来
  • 注:ansible2.7跟2.8版本写法不同,注意看文档区别
Options =	namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
options	=	Options(connection='local',	module_path=[''],	forks=10,	
become=None,	become_method=None,	become_user=None,	
check=False,	diff=False)
loader	=	DataLoader()
passwords	=	dict(vault_pass='secret')
inventory	=	InventoryManager(loader=loader,	sources='localhost,')
variable_manager =	VariableManager(loader=loader,	
inventory=inventory)
Ansible常用属性
  • from ansible.parsing.dataloader import DataLoader
    用来加载解析yaml文件或JSON内容,并且支持vault的解密
  • from ansible.vars.manager import VariableManager
    管理变量的类,包括主机,组,扩展等变量
  • from ansible.inventory.manager import InventoryManager
    用于创建主机清单,主机清单的源采用配置文件或是逗号分开主机名字符串
  • from ansible.playbook.play import Play
    用于创建play对象,能够通过play_source提供的信息自动创建任务对象
  • from ansible.executor.task_queue_manager import TaskQueueManager
    用于处理进程池中的多进程。队列管理器负责加载play策略插件,以便在选定的主机上执行任务
  • import ansible.constants as C
    存储ansible一些预定义变量

运行命令时有很多参数要指定,这些参往往很长,可以先把它们提前定义出来

play_source = dict(name = "Ansible Play",hosts = 'localhost',gather_facts =	'no',tasks=[
dict(action=dict(module='shell',args='mkdir /tmp/mytestdir'),register='shell_out')])
play	= Play().load(play_source, variable_manager=variable_manager, loader=loader)
执行ad-hoc命令
  • 创建实例并执行命令
tqm =None
try:
	tqm =TaskQueueManager(
		inventory=inventory,
		variable_manager=variable_manager,
		loader=loader,
		options=options,
		passwords=passwords,
	)
	result	=	tqm.run(play)	
finally:
	if tqm is	not	None:
		tqm.cleanup()
	shutil.rmtree(C.DEFAULT_LOCAL_TMP,	True)
调用playbook
Playbook编程概述
  • Playbooks 是 Ansible的配置、部署、编排语言
  • 它们可以被描述为一个需要希望远程主机执行命令的方案或者一组IT程序运行的命令集合
  • 可以通过python编程的方式执行playbook
相关模块
  • 与执行ad-hoc命令一样,playbook的执行也需要相关模块
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor


def runpb(sources,playbooks):
    Options = namedtuple('Options',
                         ['connection',
                          'remote_user',
                          'ask_sudo_pass',
                          'verbosity',
                          'ask_pass',
                          'module_path',
                          'forks',
                          'become',
                          'become_method',
                          'become_user',
                          'check',
                          'listhosts',
                          'listtasks',
                          'listtags',
                          'syntax',
                          'sudo_user',
                          'sudo',
                          'diff'])
    options = Options(connection='smart',
                      remote_user=None,
                      ask_pass=None,
                      sudo_user=None,
                      forks=5,
                      sudo=None,
                      ask_sudo_pass=False,
                      verbosity=5,
                      module_path=None,
                      become=None,
                      become_method=None,
                      become_user=None,
                      check=False,
                      diff=False,
                      listhosts=None,
                      listtasks=None,
                      listtags=None,
                      syntax=None)
    loader = DataLoader()
    passwords = dict()
    inventory = InventoryManager(loader=loader, sources=sources)
    variable_manager = VariableManager(loader=loader, inventory=inventory)
    playbook = PlaybookExecutor(
        playbooks= playbooks,
        inventory=inventory,
        variable_manager=variable_manager,
        loader=loader,
        options=options,
        passwords=passwords
    )
    result = playbook.run()
    return result
if __name__ == '__main__':
    sources = ['myansible/hosts']
    playbooks = ['myansible/dbweb.yaml']
    result = runpb(sources=sources,playbooks=playbooks)
    print(result)

编写ansible模块

模块基础
官方模块
模块执行流程
  • 将模块文件读入内存,然后添加传递给模块的参数,最后将模块中所需要的类添加到内存,由zipfile压缩后,再由base64进行编码,写入到模板文件内

  • 通过默认的连接方式(一般是ssh),ansible连接到远程主机,创建临时目录,并关闭连接

  • 打开另外一个ssh连接,将模板文件以sftp方式传送到刚刚创建的临时目录中,写完后关闭连接

  • 打开一个ssh连接将任务对象赋予可执行权限,执行成功后关闭连接

  • 最后,ansible将再打开一个新连接来执行模块,并删除临时目录及其所有内容

  • 模块的结果是从标准输出stdout中获取json格式的字符串。ansible将解析和处理此字符串

模块开发

模块库目录

  • 可以使用 ANSIBLE_LIBRARY环境变量来指定模块的存放位置
  • 也可以在playbook当前目录下创建library目录
    [root@localhost myansi]# mkdir /opt/myansible_lib/

指定自己编写模块的文件路径是/opt/myansible_lib/

# export ANSIBLE_LIBRARY=/opt/myansible_lib/
# mkdir /opt/myansible_lib/

编写模块文件rcopy.py,实现远程主机在自己的系统内执行拷贝操作

# vim /opt/myansible_lib/rcopy.py
#!/usr/bin/env python

from ansible.module_utils.basic import AnsibleModule
import shutil

def main():
    module = AnsibleModule(
        argument_spec=dict(
            yuan=dict(required=True, type='str'),
            mubiao=dict(required=True, type='str')
        )
    )
    shutil.copy(module.params['yuan'], module.params['mubiao'])
    module.exit_json(changed=True)

if __name__ == '__main__':
    main()

调用自己写的模块,将服务器上/etc/hosts拷贝到/tmp/zhuji

# ansible webservers -m rcopy -a "yuan=/etc/hosts mubiao=/tmp/zhuji"

编写下载模块

  1. 环境变量

    # export ANSIBLE_LIBRARY=/opt/myansible_lib/
    
  2. 编写模块

    # vim /opt/myansible_lib/download.py 
    #!/usr/bin/env python
    # -*- coding: utf8 -*-
    '用于下载指定文件'
    
    from ansible.module_utils.basic import AnsibleModule
    import wget
    
    def main():
        module = AnsibleModule(
            argument_spec=dict(
                url=dict(required=True, type='str'),
                path=dict(required=True, type='str')
            )
        )
        wget.download(module.params['url'], module.params['path'])
        module.exit_json(changed=True)
    
    if __name__ == '__main__':
        main()
    

    注意:远程主机只有python2,不是python3。python2默认字符采用的是ASCII码,而不是unicode,所以python2的文本中不能写汉字。如果需要添加汉字,需要在文件中指定字符集。

  3. 在远程主机上安装wget。因为ansible准备好的模块,需要在远程主机上执行。

    # 在本机上下载wget
    # pip3 download wget --trusted-host pypi.douban.com
    
    # 在远程主机上安装wget
    # ansible webservers -m copy -a "src=files/wget-3.2.zip dest=/root"
    # ansible webservers -m shell -a "cd /root; unzip wget-3.2.zip"
    # ansible webservers -m shell -a "cd /root/wget-3.2/; python setup.py install"
    
  4. 通过自己编写的模块,下载文件

    # ansible webservers -m download -a "url=http://192.168.4.254/zabbix.png path=/tmp/zabbix.png"
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Python中安装Ansible,可以按照以下步骤进行操作: 1. 确保已经安装了Python和pip工具。Python版本应为2.7或更高版本。 2. 使用以下命令安装Ansible的依赖包: ``` pip install -U setuptools pycrypto cryptography ``` 3. 安装Ansible本身。可以使用以下命令安装最新版本的Ansible: ``` pip install ansible ``` 你也可以指定特定的版本进行安装,例如: ``` pip install ansible==2.9.9 ``` 在安装过程中,pip会自动下载并安装Ansible及其相关依赖包。 4. 安装完成后,可以使用以下命令检查Ansible的版本: ``` ansible --version ``` 这将显示已安装的Ansible版本以及其他配置信息。 请注意,安装Ansible时可能需要管理员权限。确保以管理员身份运行命令或在虚拟环境中进行安装。 引用提供了一个完整的安装Ansible的示例,其中包含更多细节和依赖项安装的步骤。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [python自动化之Ansible的安装教程](https://download.csdn.net/download/weixin_38706951/13991839)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Linux-基于python2.7.5安装ansible最强攻略【适用于python3版本安装ansible】](https://blog.csdn.net/weixin_36522099/article/details/106595572)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值