1、ansible簡介node
ansible是新出現的 自動化 運維工具 , 基於Python研發 。 糅合了衆多老牌運維工具的優勢實現了批量操做系統配置、批量程序的部署、批量運行命令等功能。 僅需在管理工做站上安裝 ansible 程序配置被管控主機的 IP 信息,被管控的主機無客戶端。 ansible 應用程序存在於 epel( 第三方社區 ) 源,依賴於不少 python 組件。python
2、ansible特性linux
①模塊化設計,調用特定的模塊來完成特定的任務,自己是核心組件,短小精悍web
②基於python語言實現,由Paramiko、PyYAML和Jinja2三個關鍵模塊實現docker
③部署簡單,不須要在被控制端安裝任何組件shell
④支持自定義模塊功能apache
⑤支持playbook劇本,連續任務按前後設置順序完成vim
⑥指望每一個命令具備冪等性(不會重複執行相同的命令。例如不會重複安裝軟件)安全
3、ansible架構bash
ansible : ansible自身核心模塊
Modules: core modules(自帶模塊)、 custom modules(自定義模塊)
connection plugins:鏈接插件,通常默認基於ssh 協議鏈接
host inventory:主機庫,定義可管控的主機列表
Playbooks:劇本執行多個任務。並不是必需讓節點一次性運行多個任務
Plugins (loh、mail):藉助於插件完成記錄日誌郵件等功能
4、安裝ansible(操做均在主控端)
一、安裝epel源 二、yum install -y ansible
這裏咱們使用ssh key實現 主控端於被控端的鏈接
# ssh-keygen -t rsa -P '' //生成密鑰 # ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.12 //把公鑰分配到被控端主機 # ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.13 # ssh-copy-id -i .ssh/id_rsa.pub root@192.168.10.14
定義 Host Inventory,定義可管控的主機
# tree /etc/ansible/ /etc/ansible/ ├── ansible.cfg #ansible主配置文件 ├── hosts #Host Inventory配置文件 └── roles
#vim /etc/ansible/hosts [webserver] //主機組名 192.168.10.12 192.168.10.13 [dbserver] 192.168.10.13 192.168.10.14
*定義可管控主機的說明
一、[ ]方括號中是組名,用於對系統進行分類,便於對不一樣系統進行個別的管理,一個系統也能夠屬於不一樣的組,好比一臺服務能夠同時屬於webserver組和dbserver組
二、被控主機,能夠用域名(必需能夠DNS解析或更改hosts文件),也能夠用IP
三、若是有主機的SSH端口不是標準的22端口,例如:能夠明確表示爲 192.168.12.12:8021
四、若是不是SSH key,而是使用密碼,則須要設置用戶名和密碼,例如 : 192.168.12.12:8021 ansible_ssh_user=root ansible_ssh_pass=123456
五、一組類似的hostname,可簡寫以下:
[webserver]
www[01:50].example.com
六、ansible_sudo 定義hosts sudo用戶,例如:ansible_sudo=yadmin
ansible_sudo_pass 定義hosts sudo密碼,例如:ansible_sudo_pass=123456
ansible_sudo_exe 定義hosts sudo路徑,例如:ansible_sudo_exe=/usr/bin/sudo
經過上面咱們知道Ansible默認的Inventory文件是/etc/ansible/hosts, 實際上Ansible還支持多個Inventory文件,這樣咱們就能夠方便的管理不一樣業務或者不一樣環境中的機器。
一、首先準備一個文件夾,裏面將存放多個Inventory文件
mkdir /etc/ansible/Inventory
cd /etc/ansible/Inventory
vim docker #定義inventory,格式和上面介紹的同樣
vim hosts
二、修改ansible.cfg文件中的inventory的值,這裏再也不是指向一個文件,而是指向一個目錄
inventory = /etc/ansible/inventory
5、基本使用
ansible <host-pattern> [-m module_name] [-a args] [options]
<host-pattern> : 指定組名,表示控制這個組的主機,all:表示全部的主機
-m module_name :使用哪一個模塊,默認是command
-a args : 傳遞給模塊的參數
在全部主機上執行date命令 # ansible all -m command -a 'date' #由於command是默認是,因此能夠省略,寫成ansible -a 'date' 192.168.10.14 | SUCCESS | rc=0 >> Mon May 2 16:00:52 EDT 2016 192.168.10.13 | SUCCESS | rc=0 >> Mon May 2 16:00:53 EDT 2016 192.168.10.12 | SUCCESS | rc=0 >> Mon May 2 16:00:53 EDT 2016
使用 ping模塊檢查全部主機
[root@c1 ~]# ansible all -m ping 192.168.10.14 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.10.12 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.10.13 | SUCCESS => { "changed": false, "ping": "pong" }
使用raw模塊,支持管道命令
# ansible dbserver -m raw -a "ip addr|grep 'eno16777736'" 192.168.10.14 | SUCCESS | rc=0 >> 2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.168.10.14/24 brd 192.168.10.255 scope global eno16777736 192.168.10.13 | SUCCESS | rc=0 >> 2: eno16777736: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 inet 192.168.10.13/24 brd 192.168.10.255 scope global eno16777736
使用copy模塊,複製文件到被控全部主機
# ansible all -m copy -a 'src=/root/sellsa.txt dest=/root/'
仍是能夠指定屬主,屬組,權限(傳輸完成以後,文件在被控端的屬主和屬組是heboan,權限是0644)
# ansible all -m copy -a 'src=/root/sellsa.txt dest=/root/ owner=heboan group=heboan mode=0644'
使用 cron模塊,爲dbserver組的主機設置定時任務計劃
#ansible dbserver -m cron -a 'name="ntpdate by heboan at 2016-4-28" minute=*/3 hour=* day=* month=* weekday=* job="/usr/sbin/ntpdate s1a.time.edu.cn"'
# ansible dbserver -a 'crontab -l' 192.168.10.13 | SUCCESS | rc=0 >> #Ansible: ntpdate by heboan at 2016-4-28 */3 * * * * /usr/sbin/ntpdate s1a.time.edu.cn 192.168.10.14 | SUCCESS | rc=0 >> #Ansible: ntpdate by heboan at 2016-4-28 */3 * * * * /usr/sbin/ntpdate s1a.time.edu.cn
使用yum模塊安裝軟件
# ansible webserver -m yum -a 'name=httpd state=present'
使用service模塊啓動服務,並開機啓動
# ansible webserver -m service -a 'name=httpd state=started enabled=yes' 192.168.10.12 | SUCCESS => { "changed": true, "enabled": true, "name": "httpd", "state": "started" } 192.168.10.13 | SUCCESS => { "changed": true, "enabled": true, "name": "httpd", "state": "started" }
使用group模塊添加用戶組
# ansible dbserver -m group -a 'name=sellsa gid=1010'
使用user模塊添加用戶
# ansible dbserver -m user -a 'name=sellsa uid=1010 group=sellsa password=123456'
6、更多模塊使用幫助文檔
#ansible-doc -l 列出模塊名及功能描述
#ansible-doc -s <module_name> 輸出模塊使用方法
7、YAML介紹
YAML是一個可讀性高的用來表達資料序列的格式。YAML參考了其餘多種語言,包括:XML、C語言、Python、Perl以及電子郵件格式RFC2822等。Clark Evans在2001年在首次發表了這種語言,另外Ingy döt Net與Oren Ben-Kiki也是這語言的共同設計者。
YAML Ain't Markup Language,即YAML不是XML。不過,在開發的這種語言時,YAML的意思實際上是:"Yet Another Markup Language"(還是一種標記語言)。其特性:
YAML的可讀性好
YAML和腳本語言的交互性好
YAML使用實現語言的數據類型
YAML有一個一致的信息模型
YAML易於實現
YAML能夠基於流來處理
YAML表達能力強,擴展性好
YAML的語法和其餘高階語言相似,而且能夠簡單表達清單、散列表、標量等數據結構。其結構(Structure)經過空格來展現,序列(Sequence)裏的項用"-"來表明,Map裏的鍵值對用":"分隔。下面是一個示例。
name: John Smith
age: 41
gender: Male
spouse:
-name: Jane Smith
age: 37
gender: Female
children:
- name: Jimmy Smith
age: 17
gender: Male
- name: Jenny Smith
age 13
gender: Female
YAML文件擴展名一般爲.yaml,如example.yaml
8、playbooks
playbook是由一個或多個「play」組成的列表。play的主要功能在於將事先並歸爲一組的 主機裝扮成事先經過ansible中的task定義好的角色,從根本上來說,所謂的task就是調用ansible的一個module。將
多個play組織在一個playbook中就可讓它們連同起來按事先安排的機制同唱一臺大戲。
下面是一個簡單的示例
- hosts: webnodes
vars
http_port: 80
max_clients: 256
remote_user: root
tasks:
- name: ensure apache is at lasted version
yum: name=httpd state=latest
- name: ensure apache is running
service: name=httpd state=started
handlers:
- name: restart apache
service: name=httpd state=restarted
playbook基礎組件
一、Hosts和Users
playbook中的每個play的目的都是爲了讓某個或某些主機以某個指定的用戶身份執行任務。hosts用於指定要執行指定任務的主機,其能夠是一個或多個由冒號分隔主機組;remote_user則用於指定遠程主機上的執行任務的用戶。如上面示例中的
- hosts: webnodes
remotes_user: root
不過,remote_user也可用於各task中。也能夠經過指定其經過sudo的方式在遠程主機上執行任務,其可用於play全局或某任務;此外,甚至能夠在sudo時使用sudo_user指定sudo時切換的用戶
- hosts: webnodes
remote_user: heboan
tasks:
- name: test connection
ping:
remote_user: heboan
sudo: yes
二、任務列表和action
play的主體部分是task list。task list中的各任務按次序逐個在hosts中指定的全部主機上執行,即在全部主機上完成第一個任務後再開始第二個。在運行自下而下某playbook時,若是中途發生錯誤,全部已執行任務都將回滾,所以,在更正playbook後從新執行一次便可。
task的目的是使用指定的參數執行模塊,而在模塊參數中可使用變量。模塊執行是冪等的,這意味着屢次執行是安全的,由於其結果均一致。
每一個task都應該有其name,用於playbook的執行結果輸出,建議其內容儘量清晰地描述任務執行步驟。若是未提供name,則action的結果將用於輸出。
定義task的可使用「action: module options」或「module: options」的格式,推薦使用後者以實現向後兼容。若是action一行的內容過多,也中使用在行首使用幾個空白字符進行換行。
tasks:
- name: make sure apache is running
service: name=httpd state=running
在衆多模塊中,只有command和shell模塊僅須要給定一個列表而無需使用「key=value」格式,例如:
tasks:
- name: disable selinux
command: /sbin/setenforce 0
若是命令或腳本的退出碼不爲零,可使用以下方式替代:
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
或者使用ignore_errors來忽略錯誤信息
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
三、handlers
用於當關注的資源發生變化時採起必定的操做
「notify」這個action可用於在每一個play的最後被觸發,這樣能夠避免屢次有改變發生時每次都執行指定的操做,取而代之,僅在全部的變化發生完成後一次性地執行指定操做。在notify中列出的操做稱爲handler,也即notify中調用handler中定義的操做。
- name: template configuration file
template: src=template.j2 dest=/etc/foo.conf
notify:
- restart memcached
- restart apache
handler是task列表,這些task與前述的task並無本質上的不一樣。
handlers:
- name: restart memcached
service: name=memcached state=restarted
- name: restart apache
service: name=apache state=restarted
9、案例-基於playbooks事先web部署
一、提供好Inventory文件
# cat /etc/ansible/hosts 基於祕鑰認證 [webserver] 192.168.88.3 192.168.88.2
二、編輯playbooks劇本
#vim /root/web.yaml - hosts: webserver remote_user: root tasks: - name: install httpd yum: name=httpd state=present - name: start httpd service: name=httpd enabled=yes state=started - name: httpd.conf configure file copy: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf notify: #修改了配置文件須要重啓服務纔會生效,因此這裏要關聯一個重啓操做 - restart httpd handlers: - name: restart httpd #這裏是上面的 restart httpd要執行的動做 service: name=httpd state=restarted
三、準備好配置文件
將web的配置放到指定目錄 src=/root/httpd.conf #這裏我把監聽端口改爲了8080
四、開始部署
# ansible-playbook /root/web.yaml