1ansible介紹
- Ansible基于Python語言實作,由paramiko和PyYAML兩個關鍵子產品建構
- 不需要安裝用戶端,通過sshd去通信
- 基于子產品工作,子產品可以由任何語言開發
- 不僅支援指令行使用子產品,也支援編寫yaml格式的playbook,易于編寫和閱讀
- 有提供UI(浏覽器圖形化)www.ansible.com/tower,收費的
- 官方文檔 http://docs.ansible.com/ansible/latest/index.html
- ansible已經被redhat公司收購,它在github上是一個非常受歡迎的開源軟體,github位址https://github.com/ansible/ansible
- 一本不錯的入門電子書 https://ansible-book.gitbooks.io/ansible-first-book/
- Ansible的基本架構:
<a href="https://s4.51cto.com/oss/201711/07/5efdd30fad117b7da83254dc3ba10cb2.png-wh_500x0-wm_3-wmp_4-s_3801953742.png" target="_blank"></a>
1. 核心引擎:即圖中所看到的ansible
2. 核心子產品(core module):在子產品庫(module library)中分為兩塊,一個是核心子產品另外一個就是自定義子產品(custom modules)。核心子產品中都是ansible自帶的子產品,Ansible子產品資源分發到遠端節點使其執行特定任務或比對一個特定的狀态。這些核心核心子產品都遵循這batteries included哲學。其實這裡這個還是很有意思的,batterires included:Python has a large standard library, commonly cited as one of Python’s greatest strengths,providing tools suited to many tasks. 這就意味着Python有這巨大的庫支援你完成你想完成的任務工作。
3. 自定義子產品(custom modules):如果在Ansible中滿足不了你所需求的子產品,那麼Ansible也能提供添加自定義化的子產品。
4. 插件(plugin):這裡我的了解就是完成較小型的任務。輔助協助子產品來完成某個功能。
5. 劇本(playbook):定義需要給遠端主機執行的一系列任務。例如安裝一個nginx服務,那麼我們可以把這拆分為幾個任務放到一個playbook中。例如:第一步需要下載下傳nginx的安裝包。第二步我可能考慮需要做的就是将我事先寫好的nginx.conf的配置檔案下發的目标伺服器上。第三步,我們需要把服務啟動起來。第四步,我們可能需要檢查端口是否正常開啟。那麼這些步驟可以通過playbook來進行整合,然後通過inventory來下發到想要執行劇本的主機上。并且playbook也支援互動式執行playbook裡面的步驟,而且如果有那一個步驟執行傳回了一個錯誤報告,那麼我們可以僅僅隻單獨執行這個步驟。你可以把playbook了解成為一個組政策,控制管理這個OU下所有的主機行為。
6. 連接配接插件(connectior plugins):Ansible預設是基于SSH連接配接到目标機器上執行操作的。但是同樣的Ansible支援不同的連接配接方法,要是這樣的話就需要連接配接插件來幫助我們完成連接配接了。
7. 主機清單(host inventory):為Ansible定義了管理主機的政策。一般小型環境下我們隻需要在host檔案中寫入主機的IP位址即可,但是到了中大型環境我們有可能需要使用靜态inventory或者動态主機清單來生成我們所需要執行的目标主機。
2 ansible安裝
- 環境:準備兩台機器
- chy 192.168.212.10 //隻需要在這台機器上安裝ansible
- chy01 192.168.212.11
- 安裝如下 chy//192.168.212.10
<code>[root@chy ~]</code><code># yum list |grep ansible //看到有2.4版本的yum包,隻需要安裝自帶的源即可</code>
<code>ansible.noarch 2.4.0.0-5.el7 extras </code>
<code>ansible-doc.noarch 2.4.0.0-5.el7 extras </code>
<code>ansible-inventory-grapher.noarch 2.3.2-1.el7 epel </code>
<code>ansible-lint.noarch 3.4.15-1.el7 epel </code>
<code>ansible-openstack-modules.noarch 0-20140902git79d751a.el7 epel </code>
<code>ansible-review.noarch 0.13.0-2.el7 epel </code>
<code>kubernetes-ansible.noarch 0.6.0-0.1.gitd65ebd5.el7 epel </code>
<code>python2-ansible-tower-cli.noarch 3.1.7-1.el7 epel </code>
<code>[root@chy ~]</code><code># yum install -y ansible ansible-doc //安裝ansible</code>
<code>[root@chy ~]</code><code># ls /root/.ssh/ //檢視有沒有密鑰對,如果有就無需在重新生成,如果之前沒有生成過需要用ssh-keygen生成一下密鑰對。</code>
<code>authorized_keys id_rsa id_rsa.pub known_hosts </code>
<code>之後将公鑰複制到另一台機器上</code>
<code>[root@chy01 ~]</code><code># cat .ssh/authorized_keys //公鑰已經放在了裡面</code>
<code>[root@chy ~]</code><code># ssh chy01</code>
<code>The authenticity of host </code><code>'chy01 (192.168.212.11)'</code> <code>can't be established.</code>
<code>ECDSA key fingerprint is de:d2:32:86:e0:89:5c:2c:51:68:92:9b:7e:40:52:5c.</code>
<code>Are you sure you want to </code><code>continue</code> <code>connecting (</code><code>yes</code><code>/no</code><code>)? </code><code>yes</code>
<code>Warning: Permanently added </code><code>'chy01'</code> <code>(ECDSA) to the list of known hosts.</code>
<code>Last login: Wed Nov 8 01:04:24 2017 from chy</code>
<code># cat /etc/motd </code>
<code>[root@chy ~]</code><code># vi /etc/ansible/hosts //配置主機組</code>
<code>## [webservers]</code>
<code>## alpha.example.org</code>
<code>## beta.example.org</code>
<code>## 192.168.1.100</code>
<code>## 192.168.1.110</code>
<code>[testhost]</code>
<code>chy02</code>
<code>chy01</code>
<code>說明: testhost為主機組名字,自定義的。 下面兩個ip為組内的機器ip。</code>
<code>增加testhost裡的内容,testhost下面可以寫主機名也可以寫ip位址,如果寫了主機名切記需要去</code><code>/etc/hosts</code><code>裡配置,如果做了dns則不需要去/etc/hosts配置(這裡需要注意的是組裡添加的機器的前提是都要做密鑰認證的)</code>
3ansible遠端執行指令
-遠端執行指令操作如下
<code>[root@chy ~]</code><code># ansible testhost -m command -a 'w'</code>
<code>chy01 | SUCCESS | rc=0 >></code>
<code> </code><code>01:46:28 up 1:00, 2 </code><code>users</code><code>, load average: 0.16, 0.05, 0.06</code>
<code>USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT</code>
<code>root pts</code><code>/0</code> <code>192.168.212.1 00:54 37:48 0.02s 0.02s -</code><code>bash</code>
<code>root pts</code><code>/1</code> <code>chy 01:46 0.00s 0.26s 0.05s w</code>
<code>chy02 | SUCCESS | rc=0 >></code>
<code> </code><code>01:46:28 up 2:24, 2 </code><code>users</code><code>, load average: 0.00, 0.01, 0.05</code>
<code>root pts</code><code>/0</code> <code>192.168.212.1 00:27 1:08m 0.02s 0.02s -</code><code>bash</code>
<code>root pts</code><code>/1</code> <code>chy 01:46 1.00s 0.30s 0.00s w</code>
<code>文法介紹:ansible 後跟定義的主機組 -m 跟子產品,- a跟需要執行的指令</code>
<code>[root@chy ~]</code><code># ansible chy01 -m command -a 'hostname'</code>
<code>如上也可以隻針對一台機器進行操作</code>
如果出現了如下錯誤,請按照如下的方法解決
<code>ansible 127.0.0.1 -m </code><code>command</code> <code>-a </code><code>'hostname'</code>
<code> </code><code>錯誤:</code><code>"msg"</code><code>: </code><code>"Aborting, target uses selinux but python bindings (libselinux-python) aren't installed!"</code>
<code> </code><code>解決:yum </code><code>install</code> <code>-y libselinux-python</code>
4 anonymous拷貝檔案或目錄
<code>[root@chy ~]</code><code># ansible chy01 -m copy -a "src=/etc/ansible dest=/tmp/ansible_test owner=root group=root mode=0755"</code>
<code>chy01 | SUCCESS => {</code>
<code> </code><code>"changed"</code><code>: </code><code>true</code><code>, </code>
<code> </code><code>"dest"</code><code>: </code><code>"/tmp/ansible_test/"</code><code>, </code>
<code> </code><code>"failed"</code><code>: </code><code>false</code><code>, </code>
<code> </code><code>"src"</code><code>: </code><code>"/etc/ansible"</code>
<code>}</code>
<code>拷貝目錄注意:源目錄會放到目标目錄下面去,如果目标指定的目錄不存在,它會自動建立。如果拷貝的是檔案,dest指定的名字和源如果不同,并且它不是已經存在的目錄,相當于拷貝過去後又重命名。但相反,如果desc是目标機器上已經存在的目錄,則會直接把檔案拷貝到該目錄下面。</code>
<code>[root@chy ~]</code><code># ansible chy01 -m copy -a "src=/etc/passwd dest=/tmp owner=root group=root mode=0755" //copy檔案</code>
<code> </code><code>"checksum"</code><code>: </code><code>"84c5bb4be970a90c7157c2d57401ca0ac0039eca"</code><code>, </code>
<code> </code><code>"dest"</code><code>: </code><code>"/tmp/passwd"</code><code>, </code>
<code> </code><code>"gid"</code><code>: 0, </code>
<code> </code><code>"group"</code><code>: </code><code>"root"</code><code>, </code>
<code> </code><code>"md5sum"</code><code>: </code><code>"177c3249629069b366250d27ef7820df"</code><code>, </code>
<code> </code><code>"mode"</code><code>: </code><code>"0755"</code><code>, </code>
<code> </code><code>"owner"</code><code>: </code><code>"root"</code><code>, </code>
<code> </code><code>"size"</code><code>: 2182, </code>
<code> </code><code>"src"</code><code>: </code><code>"/root/.ansible/tmp/ansible-tmp-1510078509.74-153887684649484/source"</code><code>, </code>
<code> </code><code>"state"</code><code>: </code><code>"file"</code><code>, </code>
<code> </code><code>"uid"</code><code>: 0</code>
[root@chy ~]# ansible chy01 -m copy -a "src=/etc/passwd dest=/tmp/copy.txt owner=root group=root mode=0755" //這裡需要注意一下就是如果想要将cp過去的檔案改名稱直接可以在cp的過程中改名字,在操作時拷貝到相應的目錄後,後面直接跟檔案名,這樣就會直接cp過去的
chy01 | SUCCESS => {
"changed": true,
"checksum": "84c5bb4be970a90c7157c2d57401ca0ac0039eca",
"dest": "/tmp/copy.txt",
"failed": false,
"gid": 0,
"group": "root",
"md5sum": "177c3249629069b366250d27ef7820df",
"mode": "0755",
"owner": "root",
"size": 2182,
"src": "/root/.ansible/tmp/ansible-tmp-1510078638.87-216978821762184/source",
"state": "file",
"uid": 0
}
[root@chy01 ~]# ls -ls /tmp/copy.txt //可以檢視到已經cp過來并且已經改名成功
4 -rwxr-xr-x 1 root root 2182 Nov 8 02:17 /tmp/copy.txt
5 ansible遠端執行腳本
- shell子產品是用來執行腳本的,如下是更詳細的操作
<code>[root@chy ~]# cat /tmp/</code><code>1</code><code>.sh </code>
<code>#!/bin/bash</code>
<code> </code><code>echo `date` > /tmp/ansible_test.txt</code>
<code>寫一個輸出時間的腳本</code>
<code>之前的saltstack腳本可以直接搞到遠端并且執行,但是ansible必須先拷貝,之後在執行</code>
<code>[root@chy ~]# ansible testhost -m copy -a </code><code>"src=/tmp/1.sh dest=/tmp/test.sh mode=0755"</code> <code>//執行的是兩台機器</code>
<code>chy02 | SUCCESS => {</code>
<code> </code><code>"checksum"</code><code>: </code><code>"1d452b51a06996a4ead87e91a7a288d3318f3e0c"</code><code>, </code>
<code> </code><code>"dest"</code><code>: </code><code>"/tmp/test.sh"</code><code>, </code>
<code> </code><code>"gid"</code><code>: </code><code>0</code><code>, </code>
<code> </code><code>"md5sum"</code><code>: </code><code>"8d6e5eb9fca38ae7c456a9da182e4426"</code><code>, </code>
<code> </code><code>"size"</code><code>: </code><code>50</code><code>, </code>
<code> </code><code>"src"</code><code>: </code><code>"/root/.ansible/tmp/ansible-tmp-1510080028.29-281241865001849/source"</code><code>, </code>
<code> </code><code>"uid"</code><code>: </code><code>0</code>
<code> </code><code>"src"</code><code>: </code><code>"/root/.ansible/tmp/ansible-tmp-1510080028.3-155921385180503/source"</code><code>, </code>
<code>[root@chy ~]# ansible testhost -m shell -a </code><code>"/tmp/test.sh"</code> <code>//之後在執行腳本,-a 後跟執行的腳本即可</code>
<code>chy01 | SUCCESS | rc=</code><code>0</code> <code>>></code>
<code>chy02 | SUCCESS | rc=</code><code>0</code> <code>>></code>
- command不能帶管道符,而shell可以用管道符
測試如下
<code>[root@chy ~]# ansible chy01 -m command -a </code><code>"cat /etc/passwd|wc -l"</code>
<code>chy01 | FAILED | rc=</code><code>1</code> <code>>></code>
<code>cat:無效選項 -- l</code>
<code>Try </code><code>'cat --help'</code> <code>for</code> <code>more information.non-zero </code><code>return</code> <code>code</code>
<code>[root@chy ~]# ansible chy01 -m shell -a </code><code>"cat /etc/passwd|wc -l"</code>
<code>34</code>
6 管理計劃
- 管理計劃用到的子產品是cron
如下操作
<code>[root@chy ~]# ansible chy01 -m cron -a </code><code>"name='test cron' job='/bin/touch/tmp/1212.txt' weekday=6"</code>
<code>-m 後跟子產品的名稱,-a 跟執行的指令"name 跟任務的名稱,job跟指令是什麼,在後面就是分時日月周,如果定義就跟具體的,不定義直接跟*就可以</code>
<code> </code><code>"envs"</code><code>: [], </code>
<code> </code><code>"jobs"</code><code>: [</code>
<code> </code><code>"test cron"</code>
<code> </code><code>]</code>
<code>[root@chy01 ansible]# crontab -l </code><code>//檢視任務計劃</code>
<code>0</code> <code>0</code> <code>* * * /bin/bash /usr/local/sbin/nginx_logrotate.sh</code>
<code>0</code> <code>1</code> <code>* * * /bin/python /home/jumpserver/manage.py crontab run 3718e5baf203ed0f54703b2f0b7e9e16 # django-cronjobs </code><code>for</code> <code>jumpserver</code>
<code>*/</code><code>10</code> <code>* * * * /bin/python /home/jumpserver/manage.py crontab run 9956b75140f4453ab1dc4aeb62962a74 # django-cronjobs </code><code>for</code> <code>jumpserver</code>
<code># Lines below here are managed by Salt, </code><code>do</code> <code>not edit</code>
<code>#Ansible: test cron</code>
<code>* * * * </code><code>6</code> <code>/bin/touch/tmp/</code><code>1212</code><code>.txt</code>
<code>You have </code><code>new</code> <code>mail </code><code>in</code> <code>/</code><code>var</code><code>/spool/mail/root</code>
<code>[root@chy ~]# ansible testhost -m cron -a </code><code>"name='test cron' state=absent"</code> <code>删除任務計劃</code>
<code> </code><code>"jobs"</code><code>: []</code>
<code>切記在做任務計劃時千萬不要手動修改,任務計劃裡的# # Lines below here are managed by Salt, </code><code>do</code> <code>not edit</code>
<code>這行内容。</code>

本文轉自我不是瘦子51CTO部落格,原文連結:http://blog.51cto.com/chy940405/1979724,如需轉載請自行聯系原作者