ansible總結

1 介紹

 

Ansible中文權威指南:http://www.ansible.com.cn/javascript

 

ansible是一種自動化運維工具,基於paramiko開發的,而且基於模塊化工做,Ansible是一種集成IT系統的配置管理、應用部署、執行特定任務的開源平臺,它是基於python語言,由Paramiko和PyYAML兩個關鍵模塊構建。集合了衆多運維工具的優勢,實現了批量系統配置、批量程序部署、批量運行命令等功能.ansible是基於模塊工做的,自己沒有批量部署的能力.真正具備批量部署的是ansible所運行的模塊,ansible只是提供一種框架.ansible不須要在遠程主機上安裝client/agents,由於它們是基於ssh來和遠程主機通信的.php

ansible被定義爲配置管理工具,配置管理工具一般具備如下功能:css

  • 確保所依賴的軟件包已經被安裝
  • 配置文件包含正確的內容和正確的權限
  • 相關服務被正確運行

經常使用的自動化運維工具技術特性比較:html

項目 Puppet SaltStack Ansible
開發語言 Ruby Python Python
是否有客戶端
是否支持二次開發 不支持 支持 支持
服務器與遠程機器是否相互驗證
服務器與遠程機器的通訊是否加密 是,標準的SSL協議 是,使用AES加密 是,使用OpenSSH
平臺支持 AIX , BSD, HP-UX, Linux , Mac OSX , Solaris, Windows BSD, Linux , Mac OS X , Solaris, Windows AIX , BSD , HP-UX , Linux , Mac OS X , Solaris
是否提供Web UI 提供 提供 提供,可是是商業版本
配置文件格式 Ruby 語法格式 YAML YAML
命令行執行 不支持,大師能夠經過配置模塊實現 支持 支持

1.1 ansible基本架構

ansible系統由控制主機和被管理主機組成,控制主機不支持windows平臺java

 
ansible基礎架構
  • 核心: ansible
  • Core Modules: ansible自帶的模塊
  • Custom Modules: 核心模塊功能不足時,用戶能夠添加擴展模塊
  • Plugins: 經過插件來實現記錄日誌,發送郵件或其餘功能
  • Playbooks: 劇本,YAML格式文件,多個任務定義在一個文件中,定義主機須要調用哪些模塊來完成的功能
  • Connectior Plugins: ansible基於鏈接插件鏈接到各個主機上,默認是使用ssh
  • Host Inventory: 記錄由Ansible管理的主機信息,包括端口、密碼、ip等

1.2 ansible特色

部署簡單, 只須要在控制主機上部署ansible環境,被控制端上只要求安裝ssh和python 2.5以上版本,這個對於類unix系統來講至關與無需配置.python

  1. no angents: 被管控節點無需安裝agent
  2. no server: 無服務端,使用是直接調用命名
  3. modules in any languages: 基於模塊工做, 可使用任意語言開發模塊
  4. 易讀的語法: 基於yaml語法編寫playbook
  5. 基於推送模式: 不一樣於puppet的拉取模式,直接由調用者控制變動在服務器上發生的時間
  6. 模塊是冪等性的:定義的任務已存在則不會作任何事情,意味着在同一臺服務器上屢次執行同一個playbook是安全的

1.3 ansible程序目錄結構:

  • 配置文件: /etc/ansible/
  • 執行文件目錄: /usr/bin/
  • lib依賴庫: /usr/lib/python2.7/site-packages/ansible/
  • help文件: /usr/lib/python2.7/site-packages/ansible

2. ansible任務執行

2.1 ansible任務執行模式

Ansible任務執行模式分爲如下兩種:web

  • ad-hoc模式(點對點模塊)
    使用單個模塊,支持批量執行單條命令,至關與在bash中執行一句shell命令
  • playbook模式(劇本模式)
    ansible主要的管理方式,經過多個task的集合完成一類功能,能夠理解爲多個ad-hoc的配置文件

2.2 ansible執行流程:

 
image.png

3. ansible使用實例

3.1 安裝

  1. 編譯安裝
    ansible依賴於Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。
# yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto # tar xf ansible-1.5.4.tar.gz # cd ansible-1.5.4 # python setup.py build # python setup.py install # mkdir /etc/ansible # cp -r examples/* /etc/ansible 
  1. rpm包安裝
# yum install ansible 

3.2 修改配置文件

ansible配置文件查找順序docker

  1. 檢查環境變量ANSIBLE_CONFIG指向的路徑文件(export ANSIBLE_CONFIG=/etc/ansible.cfg);
  2. ~/.ansible.cfg,檢查當前目錄下的ansible.cfg配置文件;
  3. /etc/ansible.cfg檢查etc目錄的配置文件。

ansible配置文件
ansible 有許多參數,下面咱們列出一些常見的參數:shell

inventory = /etc/ansible/hosts      #這個參數表示資源清單inventory文件的位置 library = /usr/share/ansible #指向存放Ansible模塊的目錄,支持多個目錄方式,只要用冒號(:)隔開就能夠 forks = 5 #併發鏈接數,默認爲5 sudo_user = root #設置默認執行命令的用戶 remote_port = 22 #指定鏈接被管節點的管理端口,默認爲22端口,建議修改,可以更加安全 host_key_checking = False #設置是否檢查SSH主機的密鑰,值爲True/False。關閉後第一次鏈接不會提示配置實例 timeout = 60 #設置SSH鏈接的超時時間,單位爲秒 log_path = /var/log/ansible.log #指定一個存儲ansible日誌的文件(默認不記錄日誌) 

3.3 定義Inventory(主機列表)

ansible的主要功用在於批量主機操做,爲了便捷地使用其中的部分主機,能夠在inventory file中將其分組命名。默認的inventory file爲/etc/ansible/hosts。
inventory file能夠有多個,且也能夠經過Dynamic Inventory來動態生成。apache

Inventory文件格式:

  • inventory文件遵循INI文件風格,中括號中的字符爲組名。能夠將同一個主機同時歸併到多個不一樣的組中;此外,當如若目標主機使用了非默認的SSH端口,還能夠在主機名稱以後使用冒號加端口號來標明。
ntp.com [webservers] www1.com:2222 www2.com [dbservers] db1.com db2.com db3.com 
  • 若是主機名稱遵循類似的命名模式,還可使用列表的方式標識各主機,例如:
[webservers] www[01:50].example.com [databases] db-[a:f].example.com 
  • 主機變量: 能夠在inventory中定義主機時爲其添加主機變量以便於在playbook中使用。例如:
[webservers]
www1.com http_port=80 maxRequestsPerChild=808
www2.com http_port=8080 maxRequestsPerChild=909
  • 組變量
[webservers]
www1.com
www2.com

[webservers:vars]
ntp_server=ntp.com
nfs_server=nfs.com

inventory其餘的參數

  • ansible基於ssh鏈接inventory中指定的遠程主機時,還能夠經過參數指定其交互方式;這些參數以下所示:
ansible_ssh_host # 遠程主機 ansible_ssh_port # 指定遠程主機ssh端口 ansible_ssh_user # ssh鏈接遠程主機的用戶,默認root ansible_ssh_pass # 鏈接遠程主機使用的密碼,在文件中明文,建議使用--ask-pass或者使用SSH keys ansible_sudo_pass # sudo密碼, 建議使用--ask-sudo-pass ansible_connection # 指定鏈接類型: local, ssh, paramiko ansible_ssh_private_key_file # ssh 鏈接使用的私鑰 ansible_shell_type # 指定鏈接對端的shell類型, 默認sh,支持csh,fish ansible_python_interpreter # 指定對端使用的python編譯器的路徑 

3.4 基於ad-hoc模式運行

ansible經過ssh實現配置管理、應用部署、任務執行等功能,所以,須要事先配置ansible端能基於密鑰認證的方式聯繫各被管理節點。

ansible命令使用語法:

ansible <host-pattern> [-f forks] [-m module_name] [-a args] -m module:默認爲command 

例如:

  1. 定義好inventory後能夠調用ping模塊來檢測網絡是否可達
# ansible all -m ping 192.168.57.22 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.57.11 | SUCCESS => { "changed": false, "ping": "pong" } 
  1. 使用command模塊遠程執行命令:
# 若是/etc/passwd文件存在就執行grep命令 # ansible all -m command -a 'removes=/etc/passwd grep root /etc/passwd' 192.168.57.22 | SUCCESS | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin 192.168.57.11 | SUCCESS | rc=0 >> root:x:0:0:root:/root:/bin/bash operator:x:11:0:operator:/root:/sbin/nologin 

能夠經過ansible-doc -l列出全部可用的module,經常使用的module有:

ping # 主機連通性測試 command # 在遠程主機上執行命令,不支持管道 shell # 在遠程主機上調用shell解析器,支持管道命令個 copy # 用於將文件複製到遠程主機,支持設定內容和修改權限. file # 建立文件,建立鏈接文件,刪除文件等 fetch # 從遠程複製文件到本地 cron # 管理cron計劃任務 yum # 用於模塊的安裝 service # 管理服務 user # 管理用戶帳號 group # 用戶組管理 script # 將本地的腳本在遠端服務器運行 setup # 該模塊主要用於收集信息,是經過調用facts組件來實現的,以變量形式存儲主機上的信息 

ansible -s <module-name>能夠查看指定module的用法,或者參看官方幫助文檔:

# ansible-doc -s service - name: Manage services service: arguments: # Additional arguments provided on the command line enabled: # Whether the service should start on boot. *At least one of state and enabled are required.* name: # (required) Name of the service. pattern: # If the service does not respond to the status command, name a substring to look for as would be found in the output of the `ps' command as a stand-in for a status result. If the string is found, the service will be assumed to be running. runlevel: # For OpenRC init scripts (ex: Gentoo) only. The runlevel that this service belongs to. sleep: # If the service is being `restarted' then sleep this many seconds between the stop and start command. This helps to workaround badly behaving init scripts that exit immediately after signaling a process to stop. state: # `started'/`stopped' are idempotent actions that will not run commands unless necessary. `restarted' will always bounce the service. `reloaded' will always reload. *At least one of state and enabled are required.* Note that reloaded will start the service if it is not already started, even if your chosen init system wouldn't normally. use: # The service module actually uses system specific modules, normally through auto detection, this setting can force a specific module. Normally it uses the value of the 'ansible_service_mgr' fact and falls back to the old 'service' module when none matching is found. 

3.5 基於playbook執行

playbook是由一個或多個「play」組成的列表。play的主要功能在於將事先歸併爲一組的主機裝扮成事先經過ansible中的task定義好的角色。從根本上來說,所謂task無非是調用ansible的一個module。將多個play組織在一個playbook中,便可以讓它們聯同起來按事先編排的機制同唱一臺大戲。

下面是一個簡單示例:

- hosts: master
  user: root
  vars:
    - motd_warning: 'WARNING: Use by master ONLY' tasks: - name: setup a MOTD copy: dest=/etc/motd content="{{ motd_warning }}" notify: say something handlers: - name: say something command: echo "copy OK" 

playbooks的組成部分

  • Target section: 定義要運行playbook的遠程主機組
    • hosts: hosts用於指定要執行指定任務的主機,其能夠是一個或多個由冒號分隔主機組
    • user: 指定遠程主機上的執行任務的用戶,還能夠指定sudo用戶等
  • Variable section: 定義playbook運行時使用的變量
  • Task section: 定義要在遠程主機上運行的任務列表
    • name: 每一個任務都有name,建議描述任務執行步驟,未經過name會用執行結果做爲name
    • 'module:options': 調用的module和傳入的參數args
  • Handler section: 定義task完成後須要調用的任務
    • notify: 在Task Section在每一個play的最後觸發,調用在hendler中定義的操做
    • handler: 也是task的列表

執行過程:

[root@localhost ansible]# ansible-playbook set_motd.yaml PLAY [master] ****************************************************************************************************************** TASK [Gathering Facts] ********************************************************************************************************* ok: [192.168.57.11] TASK [setup a MOTD] ************************************************************************************************************ changed: [192.168.57.11] RUNNING HANDLER [say something] ************************************************************************************************ changed: [192.168.57.11] PLAY RECAP ********************************************************************************************************************* 192.168.57.11 : ok=3 changed=2 unreachable=0 failed=0 # cat /etc/motd WARNING: Use by master ONLY 

playbook安裝配置apache實戰

  1. 編寫playbook:install_httpd.yaml
---
- hosts: slave
  vars:
    http_port: 8080 user: root tasks: - name: ensure apache is at the latest version yum: name=httpd state=latest - name: write the apache config file template: src: template/httpd.j2 dest: /etc/httpd/conf/httpd.conf notify: - restart apache - name: ensure apache is running service: name=httpd state=started handlers: - name: restart apache service: name: httpd state: restarted 
  1. 生成apache配置文件jinja2模板,將服務端口配置爲變量Listen {{ http_port }}
  2. 執行playbook並檢查遠端服務端口
[root@localhost ansible]# ansible-playbook install_httpd.yaml PLAY [slave] ******************************************************************************************************************* TASK [Gathering Facts] ********************************************************************************************************* ok: [192.168.57.22] TASK [ensure apache is at the latest version] ********************************************************************************** changed: [192.168.57.22] TASK [write the apache config file] ******************************************************************************************** changed: [192.168.57.22] TASK [ensure apache is running] ************************************************************************************************ changed: [192.168.57.22] RUNNING HANDLER [restart apache] *********************************************************************************************** changed: [192.168.57.22] PLAY RECAP ********************************************************************************************************************* 192.168.57.22 : ok=5 changed=4 unreachable=0 failed=0 [root@localhost ansible]# ansible slave -m shell -a 'ss -lntp | grep 8080' 192.168.57.22 | SUCCESS | rc=0 >> LISTEN 0 128 :::8080 :::* users:(("httpd",pid=29187,fd=4),("httpd",pid=29185,fd=4),("httpd",pid=29184,fd=4),("httpd",pid=29183,fd=4),("httpd",pid=29182,fd=4),("httpd",pid=29181,fd=4)) 

3.6 roles

ansilbe自1.2版本引入的新特性,用於層次性、結構化地組織playbook。roles可以根據層次型結構自動裝載變量文件、tasks以及handlers等。要使用roles只須要在playbook中使用include指令便可。簡單來說,roles就是經過分別將變量、文件、任務、模塊及處理器放置於單獨的目錄中,並能夠便捷地include它們的一種機制。角色通常用於基於主機構建服務的場景中,但也能夠是用於構建守護進程等場景中。

一個roles的案例以下所示:

site.yml
webservers.yml
fooservers.yml
roles/
   common/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/
   webservers/
     files/
     templates/
     tasks/
     handlers/
     vars/
     meta/

在playbook中,能夠這樣使用roles:

---
- hosts: webservers
  roles:
    - common
    - webservers

也能夠向roles傳遞參數:

---  - hosts: webservers  - common  - { role: foo_app_instance, dir: '/opt/a', port: 5000 }  - { role: foo_app_instance, dir: '/opt/b', port: 5001 } 

也能夠用條件來使用roles:

--- - hosts: webservers - { role: some_role, when: "ansible_os_family == 'RedHat'" } 

3.6.1 建立roles步驟:

  1. 建立以roles命名的目錄;
  2. 在roles目錄中分別建立以各角色名稱命名的目錄,如webservers等;
  3. 在每一個角色命名的目錄中分別建立files、handlers、meta、tasks、templates和vars目錄;用不到的目錄能夠建立爲空目錄,也能夠不建立;
  4. 在playbook文件中,調用各角色;

4. ansible速度優化

4.1 SSH Multiplexing

ansible運行playbook時會啓動不少ssh鏈接來執行復制文件,運行命令這樣的操做.openssh支持這樣一個優化,叫作ssh Multiplexing,當使用這個ssh Multiplexing的時候,多個鏈接到相同主機的ssh回話會共享相同的TCP鏈接,這樣就只有第一次鏈接的時候須要進行TCP三次握手.

ansible會默認使用ssh Multiplexing特性,通常不須要更改配置,相關的配置項爲:

[ssh_connection]
control_master = auto # 套接字不存在的狀況下自動建立 control_path = $HOME/.ansible/cp/ansible-ssh-%h-%p-%r # 鏈接套接字存放的位置 control_persist = 60s # 60s沒有ssh鏈接就關閉主鏈接 

4.2 pipelining

ansible執行過程當中,他會基於調用的模塊生成一個python腳本,而後將python腳本複製到主機上,最後執行腳本.ansible支持一個優化,叫作pipelining,在這個模式下ansible執行腳本時並不會去複製它,而是經過管道傳遞給ssh會話,這會讓ansible的ssh會話從2個減小到1個,從而節省時間.

pipelining默認是關閉的, 由於他須要確認被管理主機上的/etc/sudoers文件中的requiretty沒有啓用, 格式以下:

Defaults: <username> !requiretty 

ansible開啓pipelining方法, 修改ansible.cfg配置文件:

[defaults]
pipelining = True 

4.3 fact緩存

ansible playbook會默認先收集fact信息,若是不須要fact數據能夠在playbook中禁用fact採集:

- name: not need facts hosts: myhosts gather_facts: False tasks: ... 

也能夠全局禁用fact採集:

[defaults]
gathering = explicit 

另外一種解決方案就是使用fact緩存,目前ansible支持下面幾種fact緩存:

  • JSON文件
  • Redis
  • memcached

JSON文件作fact緩存示例
ansible把採集到的fact寫入控制主機的json文件中,若是文件已經存在,那麼ansible不會再去主機上採集fact

啓用JSON文件緩存,修改ansible.cfg文件:

[defaults]
gathering = smart

# 設置超時時間 face_caching_timeout = 86400 # 使用JSON文件作爲緩存後端 fact_caching = jsonfile fact_caching_connection = /tmp/ansible_fact_cache 

4.4 併發數

ansible默認併發數是5,能夠用下面兩種方法修改併發數:

  • 環境變量方式
export ANSIBLE_FORKS=20 
  • 設置ansible.cfg
[defaults]
forks = 20

5. ansible 與 docker

ansible內置多種雲計算相關模塊,如aws,openstack,docker等,下圖是ansible與docker相關的模塊:


 
image

5.1 使用ansible建立docker鏡像

經過playbook和dockerfile相結合的方式生成鏡像, 示例以下:

FROM ansible/ubuntu14.04-ansible:stable MAINTAINER xxx ADD ansible /srv/ansible WORKDIR /srv/ansible RUN ansible-playbook web-app.yaml -c local VOLUME /srv/project/static WORKDIR /srv/project EXPOSE 8000 CMD ["gunicorn_django", "-c", "gunicorn.conf.py"] 

5.2 啓動容器

ansible能夠經過docker模塊來操做容器,示例以下:

- name: start the postgres container
  docker:
    image: postgres:9.4 name: postgres public_all_ports: True env: POSTGRES_USER: "{{ database_user }}" POSTFRES_PASSWORD: "{{ database_password }}" 

小禮物走一走,來簡書關注我

相關文章
相關標籤/搜索