一、自動化工具介紹
1、自動化運維應用場景
- 文件傳輸
- 應用部署
- 配置管理
- 任務流編排
2、常用自動化運維工具
- Ansible:python,Agentless,中小型應用環境
- Saltstack:python,一般需部署agent,執行效率更高
- Puppet:ruby, 功能強大,配置復雜,重型,適合大型環境
- Fabric:python,agentless
- Chef:ruby,國內應用少
- Cfengine
- func
二、Ansible介紹
1、Ansible特性
- 1> 模塊化:調用特定的模塊,完成特定任務
- 2> Paramiko(python對ssh的實現),PyYAML,Jinja2(模板語言)三個關鍵模塊
- 3> 支持自定義模塊
- 4> 基於Python語言實現
- 5> 部署簡單,基於python和SSH(默認已安裝),agentless
- 6> 安全,基於OpenSSH
- 7> 支持playbook編排任務
- 8> 冪等性:一個任務執行1遍和執行n遍效果一樣,不因重復執行帶來意外情況
- 9> 無需代理不依賴PKI(無需ssl)
- 10> 可使用任何編程語言寫模塊
- 11> YAML格式,編排任務,支持豐富的數據結構
- 12> 較強大的多層解決方案
2、Ansible架構
Ansible的作用以及工作結構
1、ansible簡介:
ansible是新出現的自動化運維工具,基於Python開發,
集合了眾多運維工具(puppet、cfengine、chef、func、fabric)的優點,
實現了批量系統配置、批量程序部署、批量運行命令等功能。
ansible是基於模塊工作的,本身沒有批量部署的能力。
真正具有批量部署的是ansible所運行的模塊,ansible只是提供一種框架。
主要包括:
(1)、連接插件connection plugins:負責和被監控端實現通信;
(2)、host inventory:指定操作的主機,是一個配置文件里面定義監控的主機;
(3)、各種模塊核心模塊、command模塊、自定義模塊;
(4)、借助於插件完成記錄日志郵件等功能;
(5)、playbook:劇本執行多個任務時,非必需可以讓節點一次性運行多個任務。
2、ansible的架構:連接其他主機默認使用ssh協議
3、Ansible工作原理
4、Ansible主要組成部分
ANSIBLE PLAYBOOKS:任務劇本(任務集),編排定義Ansible任務集的配置文件,由Ansible順序依次執行,通常是JSON格式的YML文件
INVENTORY:Ansible管理主機的清單 /etc/anaible/hosts
MODULES: Ansible執行命令的功能模塊,多數為內置核心模塊,也可自定義
PLUGINS: 模塊功能的補充,如連接類型插件、循環插件、變量插件、過濾插件等,該功能不常用
API: 供第三方程序調用的應用程序編程接口
ANSIBLE: 組合INVENTORY、API、MODULES、PLUGINS的綠框,可以理解為是ansible命令工具,其為核心執行工具
Ansible命令執行來源:
- 1> USER,普通用戶,即SYSTEM ADMINISTRATOR
- 2> CMDB(配置管理數據庫) API 調用
- 3> PUBLIC/PRIVATE CLOUD API調用 (公有私有雲的API接口調用)
- 4> USER-> Ansible Playbook -> Ansibile
利用ansible實現管理的方式:
- 1> Ad-Hoc 即ansible單條命令,主要用於臨時命令使用場景
- 2> Ansible-playbook 主要用於長期規划好的,大型項目的場景,需要有前期的規划過程
Ansible-playbook(劇本)執行過程
- 將已有編排好的任務集寫入Ansible-Playbook
- 通過ansible-playbook命令分拆任務集至逐條ansible命令,按預定規則逐條執行
Ansible主要操作對象
- HOSTS主機
- NETWORKING網絡設備
注意事項:
- 執行ansible的主機一般稱為主控端,中控,master或堡壘機
- 主控端Python版本需要2.6或以上
- 被控端Python版本小於2.4需要安裝python-simplejson
- 被控端如開啟SELinux需要安裝libselinux-python
- windows不能做為主控端
- ansible不是服務,不會一直啟動,只是需要的時候啟動
三、Ansible安裝
1、rpm包安裝
#安裝epel源 yum install epel-release -y #安裝 yum install ansible
2、編譯安裝
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
3、Git方式
git clone git://github.com/ansible/ansible.git --recursive cd ./ansible source ./hacking/env-setup
4、pip安裝
yum install python-pip python-devel yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel pip install --upgrade pip pip install ansible --upgrade
確認安裝:
ansible --version
四、Ansible配置
1、文件結構
配置文件 /etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性(一般無需修改) /etc/ansible/hosts 主機清單(將被管理的主機放到此文件) /etc/ansible/roles/ 存放角色的目錄 程序 /usr/bin/ansible 主程序,臨時命令執行工具 /usr/bin/ansible-doc 查看配置文檔,模塊功能查看工具 /usr/bin/ansible-galaxy 下載/上傳優秀代碼或Roles模塊的官網平台 /usr/bin/ansible-playbook 定制自動化任務,編排劇本工具 /usr/bin/ansible-pull 遠程執行命令的工具 /usr/bin/ansible-vault 文件加密工具 /usr/bin/ansible-console 基於Console界面與用戶交互的執行工具
2、主機清單inventory
Inventory 主機清單 1> ansible的主要功用在於批量主機操作,為了便捷地使用其中的部分主機,可以在inventory file中將其分組命名 2> 默認的inventory file為/etc/ansible/hosts 3> inventory file可以有多個,且也可以通過Dynamic Inventory來動態生成 /etc/ansible/hosts文件格式 inventory文件遵循INI文件風格,中括號中的字符為組名。 可以將同一個主機同時歸並到多個不同的組中; 此外,當如若目標主機使用了非默認的SSH端口,還可以在主機名稱之后使用冒號加端口號來標明 ntp.magedu.com 不分組,直接加 [webservers] webservers組 www1.magedu.com:2222 可以指定端口 www2.magedu.com [dbservers] db1.magedu.com db2.magedu.com db3.magedu.com 如果主機名稱遵循相似的命名模式,還可以使用列表的方式標識各主機 示例: [websrvs] www[1:100].example.com ip: 1-100 [dbsrvs] db-[a:f].example.com dba-dbff
3、Ansible 配置文件
Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默認) vim /etc/ansible/ansible.cfg [defaults] #inventory = /etc/ansible/hosts # 主機列表配置文件 #library = /usr/share/my_modules/ # 庫文件存放目錄 #remote_tmp = $HOME/.ansible/tmp # 臨時py命令文件存放在遠程主機目錄 #local_tmp = $HOME/.ansible/tmp # 本機的臨時命令執行目錄 #forks = 5 # 默認並發數,同時可以執行5次 #sudo_user = root # 默認sudo 用戶 #ask_sudo_pass = True # 每次執行ansible命令是否詢問ssh密碼 #ask_pass = True # 每次執行ansible命令是否詢問ssh口令 #remote_port = 22 # 遠程主機的端口號(默認22) 建議優化項: host_key_checking = False # 檢查對應服務器的host_key,建議取消注釋 log_path=/var/log/ansible.log # 日志文件,建議取消注釋 module_name = command # 默認模塊
五、Ansible命令
1、Ansible系列命令
Ansible系列命令 ansible ansible-doc ansible-playbook ansible-vault ansible-console ansible-galaxy ansible-pull ansible-doc: 顯示模塊幫助 ansible-doc [options] [module...] -a 顯示所有模塊的文檔 -l, --list 列出可用模塊 -s, --snippet 顯示指定模塊的playbook片段(簡化版,便於查找語法) 示例: ansible-doc -l 列出所有模塊 ansible-doc ping 查看指定模塊幫助用法 ansible-doc -s ping 查看指定模塊幫助用法
2、Ansible命令介紹
ansible通過ssh實現配置管理、應用部署、任務執行等功能,建議配置ansible端能基於密鑰認證的方式聯系各被管理節點 ansible <host-pattern> [-m module_name] [-a args] ansible +被管理的主機(ALL) +模塊 +參數 --version 顯示版本 -m module 指定模塊,默認為command -v 詳細過程 –vv -vvv更詳細 --list-hosts 顯示主機列表,可簡寫 --list -k, --ask-pass 提示輸入ssh連接密碼,默認Key驗證 -C, --check 檢查,並不執行 -T, --timeout=TIMEOUT 執行命令的超時時間,默認10s -u, --user=REMOTE_USER 執行遠程執行的用戶 -b, --become 代替舊版的sudo切換 --become-user=USERNAME 指定sudo的runas用戶,默認為root -K, --ask-become-pass 提示輸入sudo時的口令 ansible all --list 列出所有主機 ping模塊: 探測網絡中被管理主機是否能夠正常使用 走ssh協議 如果對方主機網絡正常,返回pong ansible-doc -s ping 查看ping模塊的語法 檢測所有主機的網絡狀態 1> 默認情況下連接被管理的主機是ssh基於key驗證,如果沒有配置key,權限將會被拒絕 因此需要指定以誰的身份連接,輸入用戶密碼,必須保證被管理主機用戶密碼一致 ansible all -m ping -k 2> 或者實現基於key驗證 將公鑰ssh-copy-id到被管理的主機上 , 實現免密登錄 ansible all -m ping
3、Ansible的主機組
ansible的Host-pattern 匹配主機的列表 All :表示所有Inventory中的所有主機 ansible all –m ping * :通配符 ansible "*" -m ping (*表示所有主機) ansible 192.168.1.* -m ping ansible "*srvs" -m ping 或關系 ":" ansible "websrvs:appsrvs" -m ping ansible “192.168.1.10:192.168.1.20” -m ping 邏輯與 ":&" ansible "websrvs:&dbsrvs" –m ping 在websrvs組並且在dbsrvs組中的主機 邏輯非 ":!" ansible 'websrvs:!dbsrvs' –m ping 在websrvs組,但不在dbsrvs組中的主機 注意:此處為單引號 綜合邏輯 ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping 在websrvs組或者在dbsrvs組,並且在appsrvs組,同時不再ftpsrvs組 websrvs U dbsrvs ∩ appsrvs ∩(!sftpsrvs) 正則表達式 ansible "websrvs:&dbsrvs" –m ping ansible "~(web|db).*\.magedu\.com" –m ping
4、Ansible命令執行過程
ansible命令執行過程 1. 加載自己的配置文件 默認/etc/ansible/ansible.cfg 2. 加載自己對應的模塊文件,如command 3. 通過ansible將模塊或命令生成對應的臨時py文件, 並將該文件傳輸至遠程服務器的對應執行用戶$HOME/.ansible/tmp/ansible-tmp-數字/XXX.PY文件 4. 給文件+x執行 5. 執行並返回結果 6. 刪除臨時py文件,sleep 0退出 執行狀態: 綠色:執行成功並且不需要做改變的操作 黃色:執行成功並且對目標主機做變更 紅色:執行失敗
六、Ansible使用示例
示例 以wang用戶執行ping存活檢測 ansible all -m ping -u wang -k 以wang sudo至root執行ping存活檢測 ansible all -m ping -u wang -k -b 以wang sudo至mage用戶執行ping存活檢測 ansible all -m ping -u wang -k -b --become-user=mage 以wang sudo至root用戶執行ls ansible all -m command -u wang -a 'ls /root' -b --become-user=root -k -K ansible ping模塊測試連接 ansible 192.168.38.126,192.168.38.127 -m ping -k
完整實例:
需求:
- 創建普通用戶,並設置密碼
- 使用普通用戶通過sudo查看root家目錄下面的內容
1、創建普通用戶alex
[root@ansible ~]# ansible all -m shell -a "useradd alex" 192.168.52.130 | CHANGED | rc=0 >> 192.168.52.132 | CHANGED | rc=0 >> 192.168.52.131 | CHANGED | rc=0 >>
2、設置用戶密碼
[root@ansible ~]# ansible all -m shell -a "echo xuequn|passwd alex --stdin" 192.168.52.130 | CHANGED | rc=0 >> Changing password for user alex. passwd: all authentication tokens updated successfully. 192.168.52.132 | CHANGED | rc=0 >> Changing password for user alex. passwd: all authentication tokens updated successfully. 192.168.52.131 | CHANGED | rc=0 >> Changing password for user alex. passwd: all authentication tokens updated successfully.
3、普通用戶alex查看root下的文件
[root@ansible ~]# ansible all -m shell -a "ls /root" -u alex -k SSH password: 192.168.52.130 | FAILED | rc=2 >> ls: cannot open directory /root: Permission deniednon-zero return code 192.168.52.132 | FAILED | rc=2 >> ls: cannot open directory /root: Permission deniednon-zero return code 192.168.52.131 | FAILED | rc=2 >> ls: cannot open directory /root: Permission deniednon-zero return code [root@ansible ~]#
提示沒有權限!
4、sudo切換到root進行執行
[root@ansible ~]# ansible all -m shell -a "ls /root" -u alex -k -b -K SSH password: BECOME password[defaults to SSH password]: 192.168.52.132 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.132 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 } 192.168.52.131 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.131 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 } 192.168.52.130 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.130 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 }
提示alex用戶不存在於sudoers文件中!
5、將alex用戶添加至sudoers文件中,加入wheel組即可。
[root@ansible ~]# ansible all -m shell -a "usermod -a -G wheel alex" 192.168.52.130 | CHANGED | rc=0 >> 192.168.52.131 | CHANGED | rc=0 >> 192.168.52.132 | CHANGED | rc=0 >>
6、驗證是否加入成功
[root@ansible ~]# ansible all -m shell -a "cat /etc/group|grep wheel" 192.168.52.130 | CHANGED | rc=0 >> wheel:x:10:alex 192.168.52.132 | CHANGED | rc=0 >> wheel:x:10:alex 192.168.52.131 | CHANGED | rc=0 >> wheel:x:10:alex
7、通過sudo切換到root用戶執行查看root家目錄的文件
[root@ansible ~]# ansible all -m shell -a "ls /root" -u alex -k -b -K SSH password: BECOME password[defaults to SSH password]: 192.168.52.132 | CHANGED | rc=0 >> anaconda-ks.cfg original-ks.cfg 192.168.52.130 | CHANGED | rc=0 >> anaconda-ks.cfg original-ks.cfg 192.168.52.131 | CHANGED | rc=0 >> anaconda-ks.cfg original-ks.cfg
8、刪除wheel組中的alex用戶
[root@ansible ~]# ansible all -m shell -a "gpasswd -d alex wheel" 192.168.52.130 | CHANGED | rc=0 >> Removing user alex from group wheel 192.168.52.131 | CHANGED | rc=0 >> Removing user alex from group wheel 192.168.52.132 | CHANGED | rc=0 >> Removing user alex from group wheel
9、再次測試alex用戶是否可以通過sudo命令查看root家目錄下的內容
[root@ansible ~]# ansible all -m shell -a "ls /root" -u alex -k -b -K SSH password: BECOME password[defaults to SSH password]: 192.168.52.131 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.131 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 } 192.168.52.132 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.132 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 } 192.168.52.130 | FAILED! => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "module_stderr": "Shared connection to 192.168.52.130 closed.\r\n", "module_stdout": "\r\nalex is not in the sudoers file. This incident will be reported.\r\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1 }