Ansible簡介和應用自動化基礎實踐javascript
一.引入:html
1.1 如官方定義,Ansible is The simplest way to automate apps and IT infrastructure. 它的設計靈感來自於做者Michael DeHanan喜歡的一本書《安德的遊戲》中的一個通訊工具Ansible,這個工具能夠遠程實時地指揮相距數光年的艦隊做戰。 由此,咱們就能夠猜測到做爲自動化工具的Ansible功能的特色:遠程管理批量的設備以實現應用或IT基礎設施自動化。java
1.2 安裝linux
在CentOS執行以下指令安裝最新版本的Ansiblegit
$ sudo yum install epel-releasegithub
$ sudo yum install ansibleweb
二.簡介docker
2.1 作什麼shell
應用自動化:應用環境安裝,應用部署
配置管理:經過inventory管理運維的主機,端口,和組;經過和配置管理數據庫的交互實現動態inventory和配置管理數據庫更新
Note. 配置管理的活動包括配置項、工做空間管理、版本控制、變動控制、狀態報告、配置審計
持續交互:在devops的部署和運維環節幫助實現每一個sprint的持續交付
管理批量主機/網絡/雲:經過相應模塊和插件管理遠程主機,網絡和雲上的資源
2.2 特色
Agentless,無需在遠程主機安裝任何代理
Free and Open Source Software,Ansible是一個很受歡迎的開源項目,github有不少的擴展模塊和插件等資源
Extensible,可經過編程接口開發模塊和插件
Integrating into Existing DevOps Workflows,可經過獲取CMDB的數據動態生成inventory;經過git,subversion獲取代碼將開發和部署鏈接起來;經過API擴展開發能調用ansible指令和劇本的服務,結合UI實現應用部署的自動調用和可視化管理.
2.3 如何工做
主要基於SSH登陸和操做遠程設備,經過ansible指令調用模塊和插件批量管理inventory中的主機。
三.架構
圖 1
3.1 Inventory
Inventory配置了須要使用anshible管理的主機的組和列表,inventory默認存儲在/etc/ansible/hosts,以下配置了兩個組localhosts和azurehosts,分別增長了兩臺主機
[localhosts]
host1 ansible_ssh_host = 192.168.0.1
[azurehosts]
host2 ansible_ssh_host = **.**.**.**
要確保ansible主機能登陸到遠程主機,須要再本機生成ssh-key,而後copy到遠程主機以實現ssh登陸
ssh-keygen
#需提供登陸用戶的密碼
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.153.129
#測試登陸
ssh root@192.168.153.129
3.2 Modules
Ansible基於對具體功能的模塊的調用來對遠程設備進行操做,以下指令,Ansible調用ping模塊去檢查和遠程全部主機的鏈接情況
$ ansible -m ping all
經常使用模塊可分爲如下幾類
3.2.1 System
file: 操做系統級別模塊, 文件傳輸,拷貝,刪除
yum: 安裝,管理軟件
command:向遠程主機發送linux命令,
shell: 執行批量指令
3.2.2 Third party(Cloud)
第三方平臺,如azure系列模塊
azure_rm_deployment: 部署虛擬機
azure_rm_machines: 管理(開機,關機,檢查狀態 )azure虛擬機
3.2.3 Virtualazation
docker: 用於管理docker
http://docs.ansible.com/ansible/list_of_network_modules.html
3.2.4 Networking
經過調用網絡層管理軟件的指令,實現網絡基本配置(IP,SubNet,Port),網絡互連等
bigip_command(F5),bigip_divice_dns(F5), netconf_config(Netconf)
3.2.5 System Application
git,subversion,appache2_module
3.3 API(Application Programming Interface)
Ansible使用Python開發,應用程序編程接口支持Python,PHP等語言進行plugin,module的開發,能夠開發調用Ansible指令的服務,開發做爲模塊補充功能(Email,look_up)的plugin。
3.4 Plugin
Plugin 是模塊功能的補充,模塊一遍偏向於公用的系統操做的功能,而Plugin偏向於具體運維業務的功能,如查詢,郵件通知等.
3.5 Networking
Ansible的管理對象包括大部分的網絡節點,Ansible網絡層面的模塊幫助用戶實現網絡基礎配置,網絡互連等自動化管理
3.6 CMDB(Configuration Management Database)
Ansible對於遠程對象的管理,是基於inventory中的主機和組的配置,inventory咱們能夠指定特定文件,而不是用默認文件,也能夠從配置管理數據庫中實時地獲取有效的配置更新到ansible主機.
3.6 Cloud
Cloud平臺如azure能夠在azure portal管理雲上的服務和虛擬機,Ansible經過azure系列模塊,即可方便的管理虛擬機,服務,接口等.
https://docs.ansible.com/ansible/guide_azure.html
3.7 Playbooks
咱們能夠執行一條ad-hoc的ansible指令完成一個操做,以下,向azurehosts這個組的主機複製了一個文件夾.
ansible azurehosts -m copy -a "src=/etc/hosts dest=/tmp/hosts"
相比於快速的臨時的指令,在對遠程設備應用部署,環境配置和管理過程當中,咱們須要執行的是一系列的指令,咱們將這些指令編寫在一個.yml文件中,這就是一個playbook,使用
ansible-playbook test.yml –extra-var=」@test.json」
或者
ansible-playbook test.yml –extra-var=」group=azurehost」
就能夠批量執行劇本中的任務,經過–extra-var傳入json或賦值變量做爲參數.
因此,若是說ansible是一個以模塊,Inventory,API和插件爲基礎工具或者引擎,那麼使用Ansible實踐的解決方案的核心就是playbooks.
四.基礎實踐
目標:在多臺linux服務器部署並管理一個NodeJS應用
設備:一臺安裝Ansible的CentOS虛擬機,兩臺CentOS虛擬機,一臺Azure雲虛擬機
4.1 解決方案1:直接在要部署的機器上進行操做
步驟:
(1) 基本環境安裝和設置
1.全局安裝node,NPM
2.打開防火牆目標端口,重啓防火牆
3.安裝node 進程管理工具(PM2)
(2)部署應用
1.檢查應用部署路徑
2.二次部署先,檢查應用運行情況
3.從代碼託管服務器下載代碼,copy到目標路徑
4.根據package.json安裝dependencies
5.使用pm2啓動應用
(3)管理和維護
有小的更新時,單獨上傳代碼並重啓應用,經過pm2查看應用狀態
用xshell登陸在多臺主機,分別執行以上步驟對應的指令
4.2 解決方案2:使用ansible中心機器對兩組主機進行環境安裝和部署
4.2.1 解決方案架構
圖 2
咱們將包含批量指令或模塊調用的playbooks.yml和運行參數playbooks.json託管在gitlab; 將要部署的代碼也放在gitlab;
Ansible機器的用戶使用ansible-playbook執行playbooks完成相應對遠程主機的安裝,部署,和應用啓動等操做
步驟:
1.配置inventory
sudo vi /etc/ansible/hosts
[azureservers]
azurehost0 ansible_ssh_host=*.*.*.*
# azurehost1 ansible_ssh_host=*.*.*.*
[localhosts]
localhost1 ansible_ssh_host=192.168.153.129
localhost2 ansible_ssh_host=192.168.153.132
2.建立source文件夾用於克隆gitlab repo,playbooks, vars.json到本地
3.編寫服務運行環境基本要求,和應用信息(部署目錄,應用名稱等)的參數
4.編寫playbooks,包含配置和部署目標主機的任務列表
4.2.2擴展
1. 編寫Python plugin從cmdb 動態獲取有效的主機列表到ansible機器的inventory
2. 使用playbook_executer API的方式調用執行playbooks
3. 使用Pyphon編寫web API,調用playbook_executer方法,實現可視化的劇本執行
4.2.3playbooks
1.配置遠程主機node/express/pm2運行環境
運行playbook 完成環境配置:
$ ansible-playbook sys_ensure.yml --extra-var="@vars.json"
vars.json
{ "host_group":"all", "app_port":8000, "node_download_url":"http://cdn.npm.taobao.org/dist/node/v8.0.0/node-v8.0.0-linux-x64.tar.xz", "node_package_name":"node-v8.0.0-linux-x64.tar.xz", "download_node_folder_name":"node-v8.0.0-linux-x64", "target_node_folder_name":"nodejs", "node_install_path":"/usr/local/", "usr_local_bin_path":"/usr/local/bin", "installed_node_cmd_path":"/usr/local/nodejs/bin/node", "installed_npm_cmd_path":"/usr/local/nodejs/bin/npm", "pm_tool":"pm2", "node_bin_path":"/usr/local/nodejs/bin" }
sys_ensure.yml
--- - hosts: "{{ host_group }}" gather_facts: no tasks: - name: Check nodejs installation. command: "node -v" register: node_v_result ignore_errors: True - name: Check npm installation. command: "npm -v" register: npm_v_result ignore_errors: True - name: Check wget installation. command: "wget -help" register: wget_result ignore_errors: True - name: Install wget. yum: name: wget state: latest when: wget_result | failed - name: Download nodejs. command: "wget {{ node_download_url }}" when: node_v_result | failed or npm_v_result | failed - name: Decompress nodejs package. command: "tar xf {{ node_package_name }} -C {{ node_install_path }}" when: node_v_result | failed or npm_v_result | failed - name: Rename '{{ download_node_folder_name }}' to '{{ target_node_folder_name }}' command: "mv {{ node_install_path }}{{ download_node_folder_name }} {{ node_install_path }}{{ target_node_folder_name }}" when: node_v_result | failed or npm_v_result | failed - name: Update system PATH, add node cmd. command: "ln -s {{ installed_node_cmd_path }} {{ usr_local_bin_path }}" when: node_v_result | failed or npm_v_result | failed - name: Update system PATH, add npm cmd. command: "ln -s {{ installed_npm_cmd_path }} {{ usr_local_bin_path }}" when: node_v_result | failed or npm_v_result | failed - name: Open the application port. command: "firewall-cmd --zone=public --add-port={{ app_port }}/tcp --permanent" ignore_errors: True - name: Reload firewall command: "firewall-cmd --reload" ignore_errors: True - include: pm2_ensure.yml vars: host_group: localhosts node_bin_path: "/usr/local/nodejs/bin"
pm2_ensure.yml
--- - hosts: "{{ host_group }}" gather_facts: no tasks: - name: check the installation of pm2 command: "{{ node_bin_path }}/pm2 -v" register: pm2_ensure_result ignore_errors: True - name: Install pm2 node module. command: "npm install pm2 -g" when: pm2_ensure_result | failed
2.上傳代碼和啓動應用
運行playbook 完成部署
$ ansible-playbook publish_prepare.yml --extra-var="publish_prepare_vars.json"
$ ansible-playbook publish.yml --extra-var="@vars.json"
vars.json
{ "app_name":"express_hello", "apps_location":"/usr/local/nodejs/apps/express_hello", "node_bin_location":"/usr/local/nodejs/bin", "host_group":"localhosts", "init_file_path":"app/app.js", "local_code_path":"../express_hello/app" }
publish_prepare_vars.json
{ "app_name":"express_hello", "gitlab_repo":"git@gitlab.com:***.git", "dest":"../express_hello", "version":"master" }
publish_prepare.yml
--- - hosts: 127.0.0.1 gather_facts: no tasks: - name: remove local source code file: "path={{ dest }} state=absent" ignore_errors: True connection: local - name: git source code to center ansible host command: "git clone {{ gitlab_repo }} {{ dest }}" connection: local
publish.yml
--- - hosts: "{{ host_group }}" gather_facts: no tasks: - name: stop {{ app_name }} if it is running on server command: "{{ node_bin_location }}/pm2 stop {{ app_name }}" ignore_errors: True - name: ensure express_app folder exists file: "path={{ apps_location }} state=directory" - name: upload source code files to servers copy: "src={{ local_code_path }} dest={{ apps_location }}" - name: install app dependencies according to package.json npm: "path={{ apps_location }}/app" - name: use pm2 to start the app command: "{{ node_bin_location }}/pm2 start {{ apps_location }}/{{ init_file_path }} --name {{ app_name }}" ignore_errors: True