Ansible - 簡介和應用自動化基礎實踐

Ansible簡介和應用自動化基礎實踐javascript

一.引入:html

1.1  如官方定義,Ansible is The simplest way to automate apps and IT infrastructure.  它的設計靈感來自於做者Michael DeHanan喜歡的一本書《安德的遊戲》中的一個通訊工具Ansible,這個工具能夠遠程實時地指揮相距數光年的艦隊做戰。 由此,咱們就能夠猜測到做爲自動化工具的Ansible功能的特色:遠程管理批量的設備以實現應用或IT基礎設施自動化。java

https://docs.ansible.com/node

 

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
相關文章
相關標籤/搜索