ansible基礎

一、流程圖html

二、簡介python

ansible是新出現的自動化運維工具,基於Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優勢,實現了批量系統配置、批量程序部署、批量運行命令等功能。web

Ansible的核心程序:shell

  • Host Lnventory:記錄了每個由Ansible管理的主機信息,信息包括ssh端口,root賬號密碼,ip地址等等。能夠經過file來加載,能夠經過CMDB加載
  • Playbooks:YAML格式文件,多個任務定義在一個文件中,使用時能夠統一調用,「劇本」用來定義那些主機須要調用那些模塊來完成的功能.
  • Core Modules:Ansible執行任何管理任務都不是由Ansible本身完成,而是由核心模塊完成;Ansible管理主機以前,先調用core Modules中的模塊,而後指明管理Host Lnventory中的主機,就能夠完成管理主機。
  • Custom Modules:自定義模塊,完成Ansible核心模塊沒法完成的功能,此模塊支持任何語言編寫。
  • Connection Plugins:鏈接插件,Ansible和Host通訊使用

ansible是基於模塊工做的,自己沒有批量部署的能力,真正具備批量部署的是ansible所運行的模塊,ansible只是提供一種框架。主要包括:json

  • 鏈接插件connection plugins:負責和被監控端實現通訊;
  • host inventory:指定操做的主機,是一個配置文件裏面定義監控的主機;
  • 各類模塊核心模塊、command模塊、自定義模塊;
  • 藉助於插件完成記錄日誌郵件等功能;
  • playbook:劇本執行多個任務時,非必需可讓節點一次性運行多個任務。

三、特性和優勢api

特性:ruby

  • no agents:不須要在被管控主機上安裝任何客戶端;
  • no server:無服務器端,使用時直接運行命令便可;
  • modules in any languages:基於模塊工做,可以使用任意語言開發模塊;
  • yaml,not code:使用yaml語言定製劇本playbook;
  • ssh by default:基於SSH工做;
  • strong multi-tier solution:可實現多級指揮。

優勢:服務器

  • 輕量級,無需在客戶端安裝agent,更新時,只需在操做機上進行一次更新便可;
  • 批量任務執行能夠寫成腳本,並且不用分發到遠程就能夠執行;
  • 使用python編寫,維護更簡單,ruby語法過於複雜;
  • 支持sudo。

四、相關配置框架

Ansible讀取配置文件的順序:運維

  • ansible.cfg       位於當前位置
  • ANSIBLE_CONFIG      一個環境變量
  • .ansible.cfg                 位於家目錄下
  • /etc/ansible/ansible.cfg

配置文件詳解

inventory        = /etc/ansible/hosts
forks               = 5
sudo_user      = root
remote_port    = 22

五、優化

①、開啓ssh長鏈接:

ansible模式是使用ssh和被管機器進行通訊的,因此ansible對ssh的依賴很是強,那麼咱們就從ssh入手來優化ansible 在openssh5.6之後的版本就支持了Multiplexing,若是咱們中控機中的ssh -v版本大於5.6,那麼咱們能夠直接在ansible.cfg文件中設置ssh長鏈接便可

ssh_args = -C -o ControlMaster=auto -o ControlPersist=5d

ControlPersisit=5d 這個參數是設置整個長鏈接保持時間這裏設置爲5天,若是開啓後,經過ssh連接過的設備都會在當前ansible\/cp目錄下面生成一個socket文件,也能夠經過netstat命令查看,會發現有一個ESTABLISHED狀態的鏈接一直與遠端設備進行着TCP鏈接

②、開啓accelerate模式

accelerate是使用python程序在被管機器上運行一個守護進程,而後ansible會經過這個守護進程監聽端口進行通訊。

開發方法:

只須要在playbook中配置 accelerate: true 就能夠了,可是開啓這個功能須要在中控機和被管機器上面都安裝 python-keyczar 軟件包,下面是在ansible.cfg中定義一些accelerate參數,列如遠程機器的監聽端口以及一些timeout的設置,固然這些參數也能夠在playbook的時候再定義:

[accelerate]

accelerate_port= 5099
accelerate_timeout=30
accelerate_connect_timeount=5.0

沒有性能瓶頸的狀況下 不推薦使用

③、Ansible取消交互

去除ssh無交互添加known_hosts配置文件/etc/ansible/ansible.cfg

# uncomment this to disable SSH key host checking
host_key_checking = False

打開註釋就OK

取消ssh的yes和no的交互:

cat > ~/.ssh/config << end
UserKnownHostsFile /dev/null
ConnectTimeout 15
StrictHostKeyChecking no
end

或者直接ssh時增長一個參數

ssh -o StrictHostKeyChecking=no root@192.168.1.1

六、模塊

①、ping模塊

ansible all -m ping

第二個參數是模塊名字,all表明全部的ip

②、command模塊

ansible 192.168.48.129  -m command -a "w「

③、shell模塊

ansible –i 1.txt all  -m shell  -a "w"

Command模塊和shell模塊都是遠程執行命令的模塊,可是推薦使用shell模塊,當咱們須要在字符串中使用特殊字符的時候,使用shell就不須要轉義

④、cope模塊

ansible 192.168.48.129 -m copy -a "src=/root/1.py dest=/home/admin/1.py owner=root group=root mode=0755"
192.168.48.129 | SUCCESS => {
    "changed": true,
    "checksum": "bc917730b55d2e3d16fda4d867596036dc184b42",
    "dest": "/home/admin/1.py",
    "gid": 0,
    "group": "root",
    "md5sum": "cc07adb0e56175fa165a2a741eee8f4c",
    "mode": "0755",
    "owner": "root",
    "size": 510,
    "src": "/root/.ansible/tmp/ansible-tmp-1517479393.27-183914298703434/source",
    "state": "file",
    "uid": 0
}

⑤、cron模塊

[root@localhost ~]# ansible 192.168.48.129 -m cron -a "name='ajing' user=admin job='touch /home/admin/1.txt' minute=1 hour=1 day=1 month=1 weekday=5"  
192.168.48.129 | SUCCESS => {
    "changed": true,
    "envs": [],
    "jobs": [
        "ajing"
    ]
}

129服務器上查看結果:

[admin@localhost ~]$ crontab  -l

#Ansible: ajing
1 1 1 1 5 touch /home/admin/1.txt

cron模塊刪除定時任務

ansible all -m cron -a "name='ajing' state=absent user=admin"

刪除任務是主須要把state變成absent就能夠了,minute, hour, day, month, weekday 默認不寫時表示*

⑥、yum模塊

[root@localhost ~]# ansible 192.168.48.129 -m yum  -a 'name=gcc'
192.168.48.129 | SUCCESS => {
    "changed": false,
    "msg": "",
    "rc": 0,
    "results": [
        "gcc-4.8.5-11.el7.x86_64 providing gcc is already installed"
    ]
}

name直接寫須要安裝的包名就能夠了

⑦、setup模塊

使用setup獲取ip地址以及主機名使用filter過濾等等

[root@localhost ~]# ansible -i 1.txt all -m setup -a 'filter=ansible_default_ipv4'
192.168.48.129 | SUCCESS => {
    "ansible_facts": {
        "ansible_default_ipv4": {
            "address": "192.168.48.129",
            "alias": "ens33",
            "broadcast": "192.168.48.255",
            "gateway": "192.168.48.2",
            "interface": "ens33",
            "macaddress": "00:0c:29:be:cf:4d",
            "mtu": 1500,
            "netmask": "255.255.255.0",
            "network": "192.168.48.0",
            "type": "ether"
        }
    },
    "changed": false
}

⑧、script模塊(很好用)

遠程執行ansible本地腳本,至關於scp+shell命令的組合,

ansible -i 1.txt all -m script -a  "1.sh"

不能寫成sh 1.sh  寫成sh就是shell模塊,並且報錯

⑨、其餘經常使用操做

指定ip或者指定ip列表文件執行命令:

ansible all -i "10.79.192.125," -m ping
ansible-playbook -i "10.168.101.179," test.yml
ansible -i 1.txt test.yml

須要在咱們返回結果中去使用本地ip, 可使用以下技巧:

[root@localhost ~]# ansible -i 1.txt all -m shell -a "echo {{inventory_hostname}}"     

192.168.48.129 | SUCCESS | rc=0 >>
192.168.48.129

Inventory_hostname    表示的是客戶端的ip

七、API

Ansible的API在2.0和2.0以前有很大的變化,在ansible1.9的時候,API是一個很是簡單的東西。官方說「it's pretty simple」,真是又pretty又simple。

示例:

import ansible.runner    

runner = ansible.runner.Runner(
   module_name='ping',
   module_args='',
   pattern='web*',
   forks=10
)
datastructure = runner.run()

Ansible的2.0API怎麼用

Ansible2.0更加貼近於ansible cli的經常使用命令執行方式,不一樣上個版本只能發送單個命令和playbook;而更推薦用戶在調用ansible的api時, 將palybook的每個task拆分出來,獲取每一個task的結果。可以靈活處理在執行批量做業過程當中的各類反饋。

將執行操做的隊列模型,包含各種環境參數設置,歸結到「ansible.executor.task_queue_manager」類中

將執行過程當中的各個task的設置,或者說playbook中的編排內容,歸結到「ansible.playbook.play」中

上述兩個東西,幾乎囊括了能夠在執行過程當中設置的全部參數,足夠靈活,也讓人抓狂,至關於須要本身寫一個1.9版本中的runner。

他們的確也都是原生類,並不是專用於外部調用。

Ansible的一個內部類

ansible/executor/task_queue_manager.py

查看一下他的源代碼

class TaskQueueManager:
    def __init__(self, inventory, variable_manager, loader, options, passwords, stdout_callback=None, run_additional_callbacks=True, run_tree=False):
        self._inventory        = inventory
        self._variable_manager = variable_manager
        self._loader           = loader
        self._options          = options
        self._stats            = AggregateStats()
        self.passwords         = passwords
        self._stdout_callback  = stdout_callback
        self._run_additional_callbacks = run_additional_callbacks
        self._run_tree         = run_tree
        self._callbacks_loaded = False
        ………………

Ansible的主要參數介紹:

  • inventory --> 由ansible.inventory模塊建立,用於導入inventory文件
  • variable_manager --> 由ansible.vars模塊建立,用於存儲各種變量信息
  • loader --> 由ansible.parsing.dataloader模塊建立,用於數據解析
  • options --> 存放各種配置信息的數據字典
  • passwords --> 登陸密碼,可設置加密信息
  • stdout_callback --> 回調函數

咱們看到run函數須要傳入一個play的參數

def run(self, play):

而咱們經過ansible.playbook.play下面的Play類來實例化一個play, 最後經過最後,用task_queue_manager(play)中的run方法來執行

Ansible的API官網地址:

http://docs.ansible.com/ansible/latest/dev_guide/developing_api.html

本身代碼以下:

[root@localhost ~]# cat testAnsible.py

import json
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
from ansible.plugins.callback import CallbackBase

class ResultCallback(CallbackBase):
    """A sample callback plugin used for performing an action as results come in

    If you want to collect all results into a single object for processing at
    the end of the execution, look into utilizing the ``json`` callback plugin
    or writing your own custom callback plugin
    """
    def v2_runner_on_ok(self, result, **kwargs):
        """Print a json representation of the result

        This method could store the result in an instance attribute for retrieval later
        """
        host = result._host
        print(json.dumps({host.name: result._result}, indent=4))

Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
# initialize needed objects
loader = DataLoader()
options = Options(connection='ssh', module_path='/path/to/mymodules', forks=100, become=None, become_method=None, become_user='root', check=False, diff=False)
passwords = dict(vault_pass='123456')

# Instantiate our ResultCallback for handling results as they come in
results_callback = ResultCallback()

# create inventory and pass to var manager
inventory = InventoryManager(loader=loader, sources=['/root/1.txt'])
variable_manager = VariableManager(loader=loader, inventory=inventory)

# create play with tasks
play_source =  dict(
        name = "Ansible Play",
        hosts = 'all',
        gather_facts = 'no',
        tasks = [
            #dict(action=dict(module='shell', args='ifconfig'), register='shell_out'),
            dict(action=dict(module='shell', args='ifconfig'), register='shell_out'),
            dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
         ]
    )
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

# actually run it
tqm = None
try:
    tqm = TaskQueueManager(
              inventory=inventory,
              variable_manager=variable_manager,
              loader=loader,
              options=options,
              passwords=passwords,
              stdout_callback=results_callback,  # Use our custom callback instead of the ``default`` callback plugin
          )
    result = tqm.run(play)
finally:
    if tqm is not None:
        tqm.cleanup()

七、playbook

Ansible的palybook應該說是很強大的一個功能,跟saltstack的state的功能差很少,就是在yaml中調用各類modules

①、playbook參數詳解:

  • hosts:hosts 用於指定要執行指定任務的主機其能夠是一個或多個由冒號分隔主機組。
  • user:root     指定遠程主機上執行任務的用戶
  • remote_user:root    
  • vars:變量
  • tasks:任務
  • -name:描述    
  • module:options     如:serverice name=httpd state=running  shell:/sbin/setenforce 0
  • handlers:觸發條件
  • files:文件賦權
  • template:模板

②、循環with_items:

---
- hosts: testhost
  user: root
  tasks:
    - name: change mod for file
      file: path=/tmp/{{ item }} mode=600 owner=root group=root
      with_items:
        - 1.txt
        - 2.txt
        - 3.txt

③、條件判斷:

---
- hosts: testhost
  remote_user: root
  tasks:
    - name: test copy
      copy: src=/tmp/1.txt dest=/tmp/2.txt
      notify: test handlers
  handlers:
    - name: test handlers
     shell: echo "121212" >> /tmp/2.txt

從ansible主上拷貝1.txt  到本身服務器上的2.txt,只有當發生了copy,纔會執行handlers

相關文章
相關標籤/搜索