本文轉載:http://nolinux.blog.51cto.com/4824967/1607459
Ansible特性
基於Python語言實現,由Paramiko, PyYAML和Jinjia2三個關鍵模塊;ansible在控制端只需要告訴監控端的期望狀態就可以實現批量部署。
默認使用SSH協議;
(1) 基於密鑰認證;
(2) 在inventory文件中指定賬號和密碼;
基於“模塊”完成各種“任務”
支持自定義模塊:支持各種編程語言
可以使用YAML語言定製playbook
Ansible架構圖
Ansible核心組件說明:
Ansible:Ansible核心程序
Host Lnventory:記錄每一個由Ansible管理的主機信息,信息包括ssh端口,root帳號密碼,ip地址.
Playbooks:YAML格式文件,多個任務定義在一個文件中,使用時可以統一調用.
Core Modules:Ansible執行任何管理任務都不是由Ansible自己完成,而是由核心模塊完成;Ansible管理主機之前,先調用core Modules中的模塊,然後指明管理Host Lnventory中的主機,就可以完成管理主機。
Custom Modules:自定義模塊,完成Ansible核心模塊無法完成的功能.
Connection Plugins:連接插件,Ansible和Host通信使用.
環境拓撲圖
安裝Ansible
配置好epel源,直接使用yum命令安裝即可
[root@node1 ~]# yum -y install ansible
查看生成的主要文件
[root@node1 ~]# rpm -ql ansible /etc/ansible/ansible.cfg #主配置文件 /etc/ansible/hosts #invertory文件
說明:Ansible不是服務,所以不需要服務腳本.
配置和被管理的主機直接建立基於ssh的密鑰認證
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.101 ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.102 ssh-copy-id -i .ssh/id_rsa.pub 172.16.4.103
定義主機,將所有被管理的主機加入到/etc/ansible/hosts中,否則無法管理
[root@node1 ~]# vim /etc/ansible/hosts [webserver] #定義一個組 172.16.4.101 172.16.4.102 [dbserver] 172.16.4.103
補充:如果沒有設置基於ssh的密鑰認證,可以在hosts文件中直接指定帳號和密碼,方法如下所示:
[webserver] 172.16.4.101 ansible_ssh_user=root ansible_ssh_pass=password 172.16.4.102 ansible_ssh_user=root ansible_ssh_pass=password [dbserver] 172.16.4.103 ansible_ssh_user=root ansible_ssh_pass=password
模塊使用:
ansible 默認提供了很多模塊來供我們使用。在 Linux 中,我們可以通過 ansible-doc -l 命令查看到當前ansible都支持哪些模塊,通過 ansible-doc -s 模塊名 又可以查看該模塊有哪些參數可以使用。
ansible命令應用基礎:
語法: ansible <host-pattern> [-f forks] [-m module_name] [-a args]
-f forks:啓動的併發線程數;
-m module_name: 要使用的模塊;
-a args: 模塊特有的參數;
下面介紹比較常用的幾個模塊:
copy模塊 file模塊 cron模塊 group模塊 user模塊 yum模塊 service模塊 script模塊 ping模塊 command模塊 raw模塊 get_url模塊 synchronize模塊
copy模塊:
[root@node1 ~]# ansible-doc -s copy - name: 將文件複製到被管理主機 action: copy backup # 創建一個備份文件包括時間戳信息,如果以某種方式重創錯了,還可以拿回原始文件 content # 取代src=,表示直接用此處指定的信息生成爲目標文件內容; dest= # 遠程節點存放文件的路徑,必須是絕對路徑 directory_mode # 遞歸複製設置目錄權限,默認爲系統默認權限 force # 如果目標主機包含該文件,但內容不同,如果設置爲yes,則強制覆蓋,如果設置爲no,則只有當目標主機的目標位置不存在該文件時,才複製。默認爲yes group # 複製到遠程主機後,指定文件或目錄的屬 mode # 複製到遠程主機後,指定文件或目錄權限,類似與 `chmod'指明如 0644 owner # 複製到遠程主機後,指定文件或目錄屬主 src # 指定複製的源文件,可以是相對路徑或者絕對路徑,如果給出的源是目錄,那麼會把目錄下的所有文件都複製過去
目的:把主控端/root目錄下的a.sh文件拷貝到到指定節點上
命令:ansible 10.1.1.113 -m copy -a 'src=/root/a.sh dest=/tmp/'
在webserver組主機創建文件,自己手動指定文件內容。
驗證:查看文件內容
[root@node2 ~]# cat /tmp/test.ansible Hello Ansible Hello world[root@node2 ~]#
file模塊:
[root@node1 ~]# ansible-doc -s file - name: 設置文件屬性 action: file force # 需要在兩種情況下強制創建軟連接,一種是源文件不存在但之後會建立的情況下;另一種是目標連接已存在,需要先取消之前的軟連接,有兩個選項:yes|no group # 設置文件或目錄的屬組 mode # 設置文件或目錄的權限 owner # 設置文件或目錄的屬主 path= # 必選項,定義文件或目錄的路徑 recurse # 遞歸設置文件的屬性,只對目錄有效 src # 要被鏈接到的路徑,只應用與state=link的情況 state # directory:如果目錄不存在,創建目錄;file:即使文件不存在,也不會被創建;link:創建軟連接;hard:創建硬連接;touch:如果文件不存在,則會創 建一個新的文件,如果文件或目錄已存在,則更新其最後修改時間;absent:刪除目錄、文件或者取消鏈接文件
目的:更改指定節點上/tmp/t.sh的權限爲755,屬主和屬組爲root
命令:ansible all -m file -a "dest=/tmp/t.sh mode=755 owner=root group=root"
在webserver組創建/test/fstab.ansible的連接文件
cron模塊:
[root@node1 ~]# ansible-doc -s cron - name: 設置管理節點生成定時任務 action: cron backup #如果設置,創建一個crontab備份 cron_file #如果指定, 使用這個文件cron.d,而不是單個用戶crontab day #日應該運行的工作( 1-31, *, */2, etc ) hour #小時 ( 0-23, *, */2, etc ) job #指明運行的命令是什麼 minute #分鐘( 0-59, *, */2, etc ) month #月( 1-12, *, */2, etc ) name #定時任務描述 reboot #任務在重啓時運行,不建議使用,建議使用special_time special_time #特殊的時間範圍,參數:reboot(重啓時),annually(每年),monthly(每月),weekly(每週),daily(每天),hourly(每小時) state #指定狀態,prsent表示添加定時任務,也是默認設置,absent表示刪除定時任務 user #以哪個用戶的身份執行 weekday #周 ( 0-6 for Sunday-Saturday, *, etc )
目的:在指定節點上定義一個計劃任務,每隔3分鐘到主控端更新一次時間
命令:ansible all -m cron -a 'name="custom job" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate 172.16.254.139"'
設置webServer組的主機沒10分鐘運行一次hello world
刪除定時任務的方法如下所示:只需要設置state爲absent即可
group模塊:
[root@node1 ~]# ansible-doc -s group - name: 添加或刪除組 action: group gid # 設置組的GID號 name= # 管理組的名稱 state # 指定組狀態,默認爲創建,設置值爲absent爲刪除 system # 設置值爲yes,表示爲創建系統組
目的:在所有節點上創建一個組名爲nolinux,gid爲2014的組
命令:ansible all -m group -a 'gid=2014 name=nolinux'
創建一個mysql組,並添加mysql用戶加入到組中
user模塊:
[root@node1 ~]# ansible-doc -s user - name: 管理用戶帳號 action: user comment # 用戶的描述信息 createhome # 是否創建家目錄 force # 在使用`state=absent'是, 行爲與`userdel --force'一致. group # 指定基本組 groups # 指定附加組,如果指定爲('groups=')表示刪除所有組 home # 指定用戶家目錄 login_class #可以設置用戶的登錄類 FreeBSD, OpenBSD and NetBSD系統. move_home # 如果設置爲`home='時, 試圖將用戶主目錄移動到指定的目錄 name= # 指定用戶名 non_unique # 該選項允許改變非唯一的用戶ID值 password # 指定用戶密碼 remove # 在使用 `state=absent'時, 行爲是與 `userdel --remove'一致. shell # 指定默認shell state #設置帳號狀態,不指定爲創建,指定值爲absent表示刪除 system # 當創建一個用戶,設置這個用戶是系統用戶。這個設置不能更改現有用戶。 uid #指定用戶的uid update_password # 更新用戶密碼
目的:在指定節點上創建一個用戶名爲nolinux,組爲nolinux的用戶
命令:ansible all -m user -a 'name=nolinux groups=nolinux state=present'
補充:刪除用戶示例
yum模塊:
[root@node1 ~]# ansible-doc -s yum - name: Manages packages with the `yum' package manager action: yum conf_file # yum的配置文件 disable_gpg_check # 關閉gpg_check disablerepo # 不啓用某個源 enablerepo # 啓用某個源 name= # 指定要安裝的包,如果有多個版本需要指定版本,否則安裝最新的包 state # 安裝(`present'),安裝最新版(`latest'),卸載程序包(`absent')
目的:在指定節點上安裝 lrzsz 服務
命令:ansible all -m yum -a "state=present name=httpd"
setup模塊
收集遠程主機的facts
每個被管理節點在接收並運行管理命令之前,會將自己主機相關信息,如操作系統版本、IP地址等報告給遠程的ansbile主機;
示例:查看172.16.4.101主機狀態信息
[root@node1 ~]# ansible 172.16.4.101 -m setup 172.16.4.101 | success >> { "ansible_facts": { "ansible_all_ipv4_addresses": [ "172.16.4.101" ], "ansible_all_ipv6_addresses": [ "fe80::20c:29ff:fef1:ddb2" ], "ansible_architecture": "x86_64", "ansible_bios_date": "05/20/2014", "ansible_bios_version": "6.00", "ansible_cmdline": { "KEYBOARDTYPE": "pc", "KEYTABLE": "us", "LANG": "en_US.UTF-8", "SYSFONT": "latarcyrheb-sun16", "crashkernel": "auto", "quiet": true, "rd_LVM_LV": "vg0/root", "rd_NO_DM": true, "rd_NO_LUKS": true, "rd_NO_MD": true, "rhgb": true, "ro": true, "root": "/dev/mapper/vg0-root"
service模塊:
[root@node1 ~]# ansible-doc -s service - name: 管理服務 action: service arguments # 向服務傳遞的命令行參數 enabled # 設置服務開機自動啓動,參數爲yes|no name= # 控制服務的名稱 pattern # 定義一個模式,如果通過status指令來查看服務的狀態時,沒有響應,就會通過ps指令在進程中根據該模式進行查找,如果匹配到,則認爲該服務依然在運行 runlevel # 設置服務自啓動級別 sleep # 如果執行了restarted,則在stop和start之間沉睡幾秒鐘 state # 啓動`started' 關閉`stopped' 重新啓動 `restarted' 重載 `reloaded'
目的:啓動指定節點上的 puppet 服務,並讓其開機自啓動
命令:ansible 10.1.1.113 -m service -a 'name=puppet state=restarted enabled=yes'
啓動httpd服務,並設置開機自動啓動
Shell模塊
功能:執行的命令中有管道或者變量
[root@node1 ~]# ansible-doc -s shell - name: Execute commands in nodes. action: shell chdir # 執行之前,先cd到指定目錄在執行命令 creates # 一個文件名,當這個文件存在,則該命令不執行 executable # 切換shell來執行命令,需要使用命令的絕對路徑 free_form= # 執行的命令 removes # 一個文件名,這個文件不存在,則該命令不執行
爲user1用戶設置密碼
script模塊:
[root@node1 ~]# ansible-doc -s script - name: 將本地腳本複製到遠程主機並運行之 action: script creates # 一個文件名,當這個文件存在,則該命令不執行 free_form= # 本地腳本路徑 removes # 一個文件名,這個文件不存在,則該命令不執行
目的:在指定節點上執行/root/test.sh腳本(該腳本是在ansible控制節點server上的)
驗證:
[root@node2 ~]# ll /tmp/script.ansible -rw-r--r-- 1 root root 26 Jun 28 15:21 /tmp/script.ansible [root@node2 ~]# cat /tmp/script.ansible hello ansible from script
ping模塊:
目的:檢查指定節點機器是否還能連通
command模塊:
目的:用於在遠程主機執行命令,缺點:運行的命令中無法使用變量,管道。
[root@node1 ~]# ansible-doc -s command - name: 在遠程節點執行命令 action: command chdir # 在執行命令之前,先切換到該目錄 creates # 一個文件名,當這個文件存在,則該命令不執行 executable # 切換shell來執行命令,需要使用命令的絕對路徑 free_form= #要執行的Linux指令,一般使用Ansible的-a參數代替。 removes #一個文件名,這個文件不存在,則該命令不執行
命令:ansible 10.1.1.113 -m command -a 'hostname'
查看被管理節點的時間,使用-m使用command模塊,-a使用date命令即可
raw模塊:
目的:在10.1.1.113節點上運行hostname命令
命令:ansible 10.1.1.113 -m raw-a 'hostname|tee'
get_url模塊:
目的:將http://10.1.1.116/favicon.ico文件下載到指定節點的/tmp目錄下
命令:ansible 10.1.1.113 -m get_url -a 'url=http://10.1.1.116/favicon.ico dest=/tmp'
synchronize模塊:
目的:將主控方/root/a目錄推送到指定節點的/tmp目錄下
命令:ansible all -m synchronize -a 'src=/root/a dest=/tmp/ compress=yes'
執行效果:
delete=yes 使兩邊的內容一樣(即以推送方爲主)
compress=yes 開啓壓縮,默認爲開啓
--exclude=.git 忽略同步.git結尾的文件
由於模塊,默認都是推送push方式。因此,如果你在使用拉取pull功能的時候,可以參考如下來實現
mode=pull 更改推送模式爲拉取模式
目的:將10.1.1.113節點的/tmp/a目錄拉取到主控節點的/root目錄下
命令:ansible 10.1.1.113 -m synchronize -a 'mode=pull src=/tmp/a dest=/root/'
由於模塊默認啓用了archive參數,該參數默認開啓了recursive, links, perms, times, owner,group和-D參數。如果你將該參數設置爲no,那麼你將停止很多參數,比如會導致如下目的遞歸失敗,導致無法拉取
其它相關的參數解釋:
dest_port=22 # 指定目的主機的ssh端口,ansible配置文件中的 ansible_ssh_port 變量優先級高於該 dest_port 變量 rsync_path # 指定 rsync 命令來在遠程服務器上運行。這個參考rsync命令的--rsync-path參數,--rsync-path=PATH # 指定遠程服務器上的rsync命令所在路徑信息 rsync_timeout # 指定 rsync 操作的 IP 超時時間,和rsync命令的 --timeout 參數效果一樣
以上暫且列舉這些日常運維中經常會用到的一些模塊,更多的模塊信息後期會繼續完善,大家也可以去官網查看
官網地址:http://docs.ansible.com/synchronize_module.html
Yml介紹
Playbook是使用yaml語言定製的,YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其他多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。
Yml語法:
- host: websrvs #定義執行的主機 remote_user: root #定義執行的用戶 tasks: #定義任務 - task1 #定義第一個任務名稱 module_name: module_args #定義使用的模塊,和模塊參數 - task 2 #定義第二個任務名稱
實例1
定義一個yml:對webserver組中的主機,調用group和user模塊創建組和用戶;對dbserver組中的主機調用copy模塊複製文件。
執行yml
實例2
搭建一個apache環境
準備需要複製到被管理主機的httpd.conf配置文件,修改監聽端口爲8080
[root@node1 ~]# mkdir conf [root@node1 ~]# cp /etc/httpd/conf/httpd.conf conf/ [root@node1 ~]# vim conf/httpd.conf Listen 8080
應用之前先停止webserver組中的httpd服務,並卸載
[root@node1 ~]# ansible webserver -a 'service httpd stop' [root@node1 ~]# ansible websrvs -m yum -a 'name=httpd state=absent'
驗證:httpd軟件包已經安裝,服務開機自動啓動,而且也監聽8080端口
[root@node2 ~]# rpm -qa httpd httpd-2.2.15-39.el6.centos.x86_64 [root@node2 ~]# chkconfig --list httpd httpd 0:off1:off2:on3:on4:on5:on6:off [root@node2 ~]# netstat -lntp | grep 8080 tcp 0 0 :::8080 :::* LISTEN 40826/httpd
YAML中的變量
http://ximenfeibing.blog.51cto.com/8809812/1669188