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 |
命令行執行 | 不支持,大師能夠經過配置模塊實現 | 支持 | 支持 |
ansible系統由控制主機和被管理主機組成,控制主機不支持windows平臺java
部署簡單, 只須要在控制主機上部署ansible環境,被控制端上只要求安裝ssh和python 2.5以上版本,這個對於類unix系統來講至關與無需配置.python
/etc/ansible/
/usr/bin/
/usr/lib/python2.7/site-packages/ansible/
/usr/lib/python2.7/site-packages/ansible
Ansible任務執行模式分爲如下兩種:web
# 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
# yum install ansible
ansible配置文件查找順序docker
ANSIBLE_CONFIG
指向的路徑文件(export ANSIBLE_CONFIG=/etc/ansible.cfg
);~/.ansible.cfg
,檢查當前目錄下的ansible.cfg配置文件;/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日誌的文件(默認不記錄日誌)
ansible的主要功用在於批量主機操做,爲了便捷地使用其中的部分主機,能夠在inventory file中將其分組命名。默認的inventory file爲/etc/ansible/hosts。
inventory file能夠有多個,且也能夠經過Dynamic Inventory來動態生成。apache
Inventory文件格式:
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
[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_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編譯器的路徑
ansible經過ssh實現配置管理、應用部署、任務執行等功能,所以,須要事先配置ansible端能基於密鑰認證的方式聯繫各被管理節點。
ansible命令使用語法:
ansible <host-pattern> [-f forks] [-m module_name] [-a args] -m module:默認爲command
例如:
ping
模塊來檢測網絡是否可達# ansible all -m ping 192.168.57.22 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.57.11 | SUCCESS => { "changed": false, "ping": "pong" }
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.
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的組成部分
執行過程:
[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實戰
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
Listen {{ http_port }}
[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))
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'" }
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鏈接就關閉主鏈接
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
ansible playbook會默認先收集fact信息,若是不須要fact數據能夠在playbook中禁用fact採集:
- name: not need facts hosts: myhosts gather_facts: False tasks: ...
也能夠全局禁用fact採集:
[defaults]
gathering = explicit
另外一種解決方案就是使用fact緩存,目前ansible支持下面幾種fact緩存:
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
ansible默認併發數是5,能夠用下面兩種方法修改併發數:
export ANSIBLE_FORKS=20
[defaults] forks = 20
ansible內置多種雲計算相關模塊,如aws,openstack,docker等,下圖是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"]
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 }}"
小禮物走一走,來簡書關注我