1、簡介
ansible是新出現的自動化運維工具,基於Python開發,集合了衆多運維工具(puppet、cfengine、chef、func、fabric)的優點,實現了批量系統配置、批量程序部署、批量運行命令等功能。(百度百科)
自動化即是一種思想,也是一種悟,其方法論是相通的【規範--標準--自動化--智能化】在介紹到ansible不得不說這是一個新貴,不管是什麼運維管理工具,其主要目的與要實現的功能是一至的,如果考慮到更多細節問題的話,主要還要看現有環境是否需要一款運維自動化管理工具,需要一款什麼樣的自動化工具纔算得上運維人員的利器。其實大部分自動化工具軟件都可以滿足一般的企業做爲生產環境使用。
ansible的特性:
- 基於Python語言實現,由Paramiko, PyYAML和Jinja2三個關鍵模塊;
- 部署簡單,agentless
- 默認使用SSH協議:
(1) 基於密鑰認證;
(2) 在inventory文件中指定帳號和密碼 - 主從模式:
master: ansible, ssh client
slave: ssh server - 支持自定義模塊:支持各種編程語言
- 支持Playbook
- 基於“模塊”完成各種“任務”
-
安裝:依賴於epel源
配置文件:/etc/ansible/ansible.cfg
Inventory: /etc/ansible/hosts - ansible架構
如何查看模塊幫助:
- ansible-doc -l
- ansible-doc -s MODULE_NAME
ansible執行狀態不同顏色的含義:
- 綠 色代表執行成功,系統沒有發生改變
- 黃 色代表系統狀態發生改變
- 紅 色代表執行失敗,顯示錯誤輸出
- 粉 色代表警告信息
YAML
- 縮進: YAML使用一個固定的縮進風格表示層級結構,每個縮進由兩個空格組成, 不能使用tabs
- 冒號: 以冒號結尾的除外,其他所有冒號後面所有必須有空格
- 短橫線: 表示列表項,使用一個短橫槓加一個空格。多個項使用同樣的縮進級別作爲同一列表
playbook基礎組件
- Hosts:運行執行任務(task)的目標主機
- remote_user:在遠程主機上執行任務的用戶
- tasks:任務列表
- handlers:任務,與tasks不同的是只有在接受到通知時纔會被觸發
- templates:使用模板語言的文本文件,使用jinja2語法
- variables:變量,變量替換{{ variable_name }}
2、安裝
ansible依賴於Python 2.6或更高的版本、paramiko、PyYAML及Jinja2。
2.1 編譯安裝
解決依賴關係
#yum -y install python-jinja2 PyYAML python-paramiko python-babel python-crypto
#tar xf ansible-2.7.9.tar.gz
#cd ansible-2.7.9
#python setup.py build
#python setup.py install
#mkdir /etc/ansible
#cp -r examples/* /etc/ansible
2.2 rpm包安裝
#yum install ansible
注意:不同版本的ansible的功能差異可能較大
2.3 配置文件
/etc/ansible/ansible.cfg
/etc/ansible/hosts
3、常用模塊
command: 命令模塊,默認模塊,用於在遠程主機執行命令
ansible]# ansible web01 -m command -a 'date'
ansible]# ansible all -a 'date' 【可以省略-m command】
-
cron:
ansible]# ansible web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job"' ansible]# ansible web01 -m cron -a 'minute="*/10" job="/bin/echo hello" name="test cron job" state=absent' ansible]# ansible web01 -a 'crontab -l'
-
user:
ansible]# ansible all -m user -a 'name="user11"' ansible]# ansible all -m user -a 'name="user11" state=absent'
-
group:
ansible]# ansible web01 -m group -a 'name=mysql gid=306 system=yes' ansible]# ansible web01 -m user -a 'name=mysql uid=306 system=yes group=mysql'
-
copy:
ansible]# ansible all -m copy -a 'src=/etc/fstab dest=/tmp/fstab.ansible owner=root mode=640' ansible]# ansible all -m copy -a 'content="Hello Ansible" dest=/tmp/test.ansible'
-
file: 設定文件屬性
path=: 指定文件路徑,可以使用name或dest來替代;
創建文件的符號鏈接:
src=: 指明源文件
path=: 指明符號鏈接文件路徑ansible]# ansible all -m file -a 'owner=mysql group=mysql mode=600 path=/tmp/fstab.ansible' ansible]# ansible all -m file -a 'path=/tmp/fstab1.link src=/tmp/fstab.ansible state=link' ansible]# ansible all -m file -a 'owner=mysql group=mysql mode=600 path=/tmp/fstab.link src=/tmp/fstab.ansible state=link'
-
ping: 測試指定主機是否能連接
ansible]# ansible all -m ping -
service: 指定運行狀態
enabled=: 是否開機自動啓動,取值爲true或者false;
name=: 指明服務名稱
state=: 狀態,取值有started, stopped, restarted;ansible]# ansible web -a 'service httpd start' 【啓動httpd服務】 ansible]# ansible web -a 'service httpd status' 【查看服務狀態】 ansible]# ansible web -a 'chkconfig --list httpd' 【查看服務是否能開機啓動】 ansible]# ansible web -m service -a 'enabled=true name=httpd state=started'
-
shell: 在遠程主機上運行命令
ansible]# ansible all -m user -a 'name=user1' ansible]# ansible all -m command -a 'echo 123456 | passwd --stdin user1' 【執行不成功】 ansible]# ansible all -m shell -a 'echo 123456 | passwd --stdin user1' 【有變量或管道時不要使用command模塊了,建議使用shell模塊】
-
script: 將本地腳本複製到遠程主機並運行之;
ansible]# ansible all -m yum -a "name=zsh" ansible]# ansible all -m yum -a "name=zsh state=absent"
- setup: 收集遠程主機的facts
每個被管理節點在接收並運行管理命令之前,會將自己主機相關信息,如操作系統版本、IP地址等報告給遠程的ansible主機;
ansible]# ansible all -m setup
4、playbook
playbook的組成結構:
Inventory 【應用哪些主機】
Modules 【調用哪些模塊】
Ad hoc Commands 【在這個主機上運行哪些命令】
Playbooks
Tasks: 任務,即調用模塊完成的某操作
Variables: 變量
Templates: 模板
Handlers: 處理器,由某事件觸發執行的操作
Roles: 角色
簡單示例1:
- hosts: websrvs
remote_user: root
tasks:
- name: create nginx group
group: name=nginx system=yes gid=208
- name: create nginx user
user: name=nginx uid=208 group=nginx system=yes
- hosts: dbsrvs
remote_user: root
tasks:
- name: copy file to dbsrvs
copy: src=/etc/inittab dest=/tmp/inittab.ans
簡單示例2:
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd package
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/root/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
- name: start httpd service
service: enabled=true name=httpd state=started
簡單示例3:
- hosts: all
remote_user: root
vars:
- username: user10
tasks:
- name: create {{ username }} user
user: name={{ username }}
when: ansible_fqdn == "node2.com"
5、roles
(1) 目錄名同角色名
(2) 目錄結構有固定格式
files: 靜態文件
templates: Jinjia2模板文件
tasks: 至少有main.yml文件,定義各tasks
handlers: 至少有一個main.yml文件,定義各handlers
vars: 至少有一個main.yml文件,定義變量
mate: 定義依賴關係等信息
(3)【調用時在roles目錄之外,通常使用site.yml定義playbook】
site.yml中定義playbook,額外也可以有其它的yml文件
[root@node1 ~]# mkdir -pv ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars} 【創建roles目錄】
[root@node1 ~]# tree ansible_playbooks/
ansible_playbooks/
└── roles
├── dbsrvs
│ ├── files
│ ├── handlers
│ ├── meta
│ ├── tasks
│ ├── templates
│ └── vars
└── websrvs
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
[root@node1 websrvs]# cp /root/conf/httpd.conf files/
[root@node1 websrvs]# vim tasks/main.yml
- name: install httpd package
yum: name=httpd
- name: install configuration file
copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
tags:
- conf
notify:
- restart httpd
- name: start httpd
service: name=httpd state=started
[root@node1 websrvs]# vim handlers/main.yml
- name: restart httpd
service: name=httpd state=restarted
root@node1 websrvs]# vim vars/main.yml
{http_port: 80, maxClients: 100} 【必須是字典格式】
- http_port: 80
- maxClients: 200
[root@node1 ansible_playbooks]# vim site.yml
- hosts: web
remote_user: root
roles:
- websrvs
[root@node1 ansible_playbooks]# ansible-playbook site.yml
[root@node1 ansible_playbooks]# vim site.yml 【代碼多次調用】
- hosts: 192.168.200.202
remote_user: root
roles:
- websrvs
- hosts: 192.168.200.203
remote_user: root
roles:
- dbsrvs
- hosts: 192.168.200.200
remote_user: root
roles:
- websrvs
- dbsrvs
[root@node1 dbsrvs]# cp /etc/my.cnf files/
[root@node1 dbsrvs]# vim tasks/main.yml
- name: install mysql-server package
yum: name=mysql-server state=latest
- name: install configuration file
copy: src=my.cnf dest=/etc/my.cnf
tags:
- myconf
notify:
- restart mysqld
- name: start mysqld service
service: name=mysqld enabled=true state=started
[root@node1 dbsrvs]# vim handlers/main.yml
- name: restart mysqld
service: name=mysqld state=restarted
[root@node1 ansible_playbooks]# ansible-playbook site.yml
6、總結
運維自動化的工作包括:運維工作:系統安裝(物理機、虛擬機)--> 程序包安裝、配置、服務啓動 --> 批量操作 --> 程序發佈 --> 監控
運維自動化也是一個迭代的過程,ansible使用技巧需要與各公司的流程相結合才能更完美的落地,對於前人們的推薦的說法是:幾十臺的設備用ansible管理,幾百臺的設備用saltstack,上千臺則是puppet,其它相關話題就不在此展開了。最後說明一下像有的環境不能提供agent部署,這時就可利用ansible agentless這一點來實現自動化。ansible是一個輕量級的自動化工具,目前支持程序安裝配置、批量操作、程序發佈、監控都有與ansible結合的案例。
常用命令總結:
創建目錄
# ansible -i /u01/ops/ansible/hosts web01 -m file -a "path=/tmp/test state=directory"
創建文件
# ansible -i /u01/ops/ansible/hosts web -m file -a "path=/tmp/test.txt state=touch"
刪除文件
# ansible -i /u01/ops/ansible/hosts web -m file -a "path=/tmp/test.txt state=absent"
創建鏈接
# ansible -i /u01/ops/ansible/hosts web01 -m file -a "src=/etc/fstab dest=/tmp/fstab state=link"
複製文件
# ansible -i /u01/ops/ansible/hosts web02 -u root -m copy -a "src=/u01/syswin.com.sh dest=/tmp mode=755 owner=root group=root backup=yes"
# ansible dbservers -m copy -a 'src=/etc/ansible/memcached-1.4.15.tar.gz dest=/tmp'
# ansible dbservers -a "ls /tmp"
查看遠程文件
# ansible -i /u01/ops/ansible/hosts web01 -u root -m command -a 'ls /tmp' -k
# ansible -i /u01/ops/ansible/hosts web01 -a 'cat /tmp/tmp.txt'
web01 | success | rc=0 >>
abcd 1234
文件不存在--命令執行
# ansible -i /u01/ops/ansible/hosts web01 -a 'creates=/tmp/ccxx.txt ls /home'
遠程服務器服務
# ansible -i /u01/ops/ansible/hosts web01 -m shell -a 'ps -ef |grep rpc'
raw
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=stopped'
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=stopped sleep=3 '
# ansible -i /u01/ops/ansible/hosts web01 -m service -a 'name=httpd state=started sleep=3 enabled=yes'
計劃任務
每3分鐘ls 一下/u01
# ansible -i /u01/ops/ansible/hosts web01 -m cron -a 'name="check home directory" minute=*/3 job="ls -lh /u01"'
軟件安裝
# ansible -i /u01/ops/ansible/hosts web01 -m yum -a 'name=httpd state=installed'
添加用戶
# ansible -i /u01/ops/ansible/hosts web01 -m command -a 'useradd -s /sbin/nologin -M user1'
# ansible -i /u01/ops/ansible/hosts web01 -m command -a 'id user1'
# ansible -i /u01/ops/ansible/hosts web01 -m user -a 'createhome=yes home=/home/user2 password=123456 name=user2 state=present shell=/bin/bash'
刪除用戶
# ansible -i /u01/ops/ansible/hosts web01 -m user -a 'remove=yes state=absent name=user2'
rsync同步
# ansible -i /u01/ops/ansible/hosts web01 -m synchronize -a 'src=./ansible.cfg dest=/tmp/ mode=push delete=yes rsync_path=/usr/bin/rsync rsync_opts="-avz,--exclude=.git"'
常見問題解決方法:
1、ansible-playbook 命令執行過程出現 skipping: no hosts matched 說明沒有此主機,需要檢查hosts文件。
2、執行ansible命令時ERROR,注意引號位置別加錯了