1. 程式人生 > >10 分鐘搭建一個超好用的 CMDB 系統

10 分鐘搭建一個超好用的 CMDB 系統

CMDB 是什麼,作為 IT 工程師的你想必已經聽說過了,或者已經爛熟了,容我再介紹一下,以防有讀者還不知道。CMDB 的全稱是 Configuration Management Data Base,翻譯下就是配置管理資料庫,它儲存與管理企業 IT 架構中裝置的各種配置資訊,它支撐服務流程的運轉、發揮著配置資訊的價值。在今天,無論是自動化運維、標準化運維、DevOps、甚至是時髦的智慧運維,其實都離開不 CMDB,可以說 CMDB 是運維體系的基石,有了配置資訊資料庫,後面各種標準、流程都可以建立在 CMDB 基礎之上,從而實現真正的標準化、自動化、智慧化運維,節約運維成本的同時,也降低運維流程混亂帶來的操作風險。

今天分享一個開源的 cmdb 系統的搭建過程,通過這一系列搭建的過程你不僅可以獲得一個支援全文檢索、自帶 restful api 的 cmdb 系統,而且還可以學到不少時髦的技術。

後端技術:

  • Python3
  • Django
  • Django REST framework
  • Elasticsearch
  • uwsgi
  • Nginx
  • Docker

前端技術:

  • Vue
  • Element-ui
  • Vue-Router
  • Vuex
  • Axios

先看一下這個 CMDB 系統的容顏,設計上參考了餓了麼內部的 cmdb 系統:

open-cmdb

基本功能有:熱新增刪除表、自定義欄位型別,方便增刪改查的前端介面,強大的搜尋查詢能力(後端使用elasticsearch儲存資料 ) 可以配合 kibana 使用,檢視資料的刪除修改記錄、歷史版本等,還帶有表級許可權管理,開放所有 API。

github 倉庫
後端:https://github.com/open-cmdb/cmdb
前端:https://github.com/open-cmdb/cmdb-web

下面介紹兩種方法搭建此開源 cmdb 系統 ,一個是使用 Docker,適用於 linux 作業系統 ,另一個是不使用 Docker,適用於 windows 和 linux 。最後介紹下 vue 環境的搭建。

1. 使用 Docker

如果你熟悉容器技術,推薦使用此方法,不過最新的 Docker 目前還不支援大多數的 windows 版本,因此如果使用容器,請使用 ubuntu 或 centos 等 Linux 作業系統。首先要安裝 Docker,安裝 Docker 的方法請參考我之前的一篇文章docker容器從入門到痴迷,或直接網上搜索對應作業系統的安裝方法對著做即可,沒有難度。

環境準備:

1、一臺可以訪問網際網路的 linux 伺服器 記憶體最好 >= 4G ,並建立一個具有 sudo 許可權的普通使用者,注意要有 yum 命令,如果沒有可以安裝下
2、一個 cmdb 專用的郵箱,用於傳送密碼和驗證碼,如果使用163、qq等第三方郵箱請在設定裡面開啟POP3/SMTP/IMAP服務並生成授權碼。如果不使用註冊和忘記密碼功能,也可以不準備

一鍵安裝

將下述程式碼儲存到 install_cmdb.py 並執行 sudo python3 install_cmdb.py 即可一鍵安裝。

# -*- coding: utf-8 -*-
import os
import subprocess
import argparse
import time

def base(cmd):
    if subprocess.call(cmd, shell=True):
        raise Exception("{} 執行失敗".format(cmd))

def install_docker():
    base("sudo yum install -y yum-utils device-mapper-persistent-data lvm2")
    base("sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo")
    base("sudo yum makecache fast")
    base("sudo yum -y install docker-ce")
    if(not os.path.exists("/etc/docker")):
        base("mkdir -p /etc/docker")
    with open("/etc/docker/daemon.json", "w") as f:
        f.write('{\n    "registry-mirrors": ["https://9f4w4icn.mirror.aliyuncs.com"] \n}')
    base("sudo systemctl daemon-reload")
    base("sudo systemctl start docker")

def create_dir():
    if (not os.path.exists("/var/cmdb/db")):
        base("sudo mkdir -p /var/cmdb/db")
    if (not os.path.exists("/var/cmdb/es")):
        base("sudo mkdir -p /var/cmdb/es")

def run_db_container():
    base("sudo docker run --name cmdb-db -d -e MYSQL_ROOT_PASSWORD=cmdbcmdb -v /var/cmdb/db:/var/lib/mysql mysql:5.7.21")

def run_es_container():
    base("sudo docker run --name cmdb-es -d -v /var/cmdb/es:/usr/share/elasticsearch/data elasticsearch:5.6.8")

def init_db():
    base("sudo docker run -it --rm --link cmdb-db -e ENV=PRO -e DB_HOST=cmdb-db -e DB_PORT=3306 -e DB_USERNAME=root -e DB_PASSWORD=cmdbcmdb -e DB_NAME=cmdb mingmingtang/cmdb init-db")

def run_cmdb_container(site_url, email_host, email_port, email_username, email_password):
    base("sudo docker run -d --name cmdb --link cmdb-db --link cmdb-es -p 80:80 -e ENV=PRO -e SITE_URL={} -e DB_HOST=cmdb-db -e DB_PORT=3306 -e DB_USERNAME=root -e DB_PASSWORD=cmdbcmdb -e DB_NAME=cmdb -e ELASTICSEARCH_HOSTS=cmdb-es -e EMAIL_HOST={} -e EMAIL_PORT={} -e EMAIL_USERNAME={} -e EMAIL_PASSWORD={} mingmingtang/cmdb start".format(site_url, email_host, email_port, email_username, email_password))

def input_para(help):
    value = ""
    while(not value):
        value = raw_input(help)
    return value

if __name__ == '__main__':
    if(os.geteuid() != 0):
        raise("請以root許可權執行")
    site_url = input_para("請輸入網站域名或IP(http://cmdb.xxx.com):")
    email_host = input_para("網站郵箱伺服器(smtp.163.com):")
    email_port = input_para("郵箱伺服器埠(25):")
    email_username = input_para("郵箱使用者名稱([email protected]):")
    email_password = input_para("郵箱密碼|獨立授權碼([email protected]):")

    print("開始安裝docker")
    install_docker()
    print("開始建立目錄")
    create_dir()
    print("開始執行mysql容器")
    run_db_container()
    print("開始執行elasticsearch容器")
    run_es_container()
    print("等待資料庫啟動完成(10s)")
    time.sleep(10)
    print("開始初始化資料庫")
    init_db()
    print("開始執行cmdb")
    run_cmdb_container(site_url, email_host, email_port, email_username, email_password)
    print("完成!")

輸入網站地址和郵箱資訊開始安裝,如下圖所示:
image.png
如果一切順利一會兒後您將看到安裝完成,如果失敗了可能就要調整一些系統引數並刪除已執行的容器重新執行了,不過根據我的安裝經驗,基本不會出錯,容器還是非常方便部署的。

執行

sudo docker ps

將看到三個正在執行的容器,分別是 cmdb,cmdb-es,cmdb-db,如下圖所示

其中 cmdb 執行著 web 伺服器(nginx,uwsgi,django,vue.js),cmdb-es 執行著 Elasticsearch 全文檢索引擎,也儲存你的配置資訊,cmdb-db 執行著 mysql,儲存著 web 伺服器的元資料(django 的知識庫)。

在瀏覽器中輸入"localhost" 盡情的開始享用吧。

2. 不使用 Docker

下面的內容主要是分享給 windows 使用者的,linux 使用者也可以對比操作,沒有問題。使用 Docker 雖然方便部署,但它遮蔽了一些細節,不利於二次開發和問題排查。在不使用 Docker 的情況下,我們不僅要裝軟體,還要安裝依賴,配置環境,雖然麻煩,但是可以學到更多知識,出了問題也可以很快定位,更能加深對專案框架的理解,也是值得的。

(1)安裝 mysql,建立資料庫,配置許可權

如果你的本機已經安裝 mysql,則不心再安裝,直接建立資料庫,配置許可權即可。

  1. 安裝 mysql

從網官下載最新的 MySQL Community Server [https://dev.mysql.com/downloads/mysql/]
比如我下載的是 mysql-8.0.12-winx64.zip ,這是個免安裝版本,直接解壓到你想安裝的目錄內,並在裡面新建 my.ini 檔案,位置如下圖所示:
image.png

my.ini 的檔案內容如下所示:

[mysqld]
# 設定3306埠
port=3306
# 設定mysql的安裝目錄
basedir=D:\program\mysql\mysql-8.0.12-winx64
# 設定mysql資料庫的資料的存放目錄
datadir=D:\program\mysql\mysql-8.0.12-winx64\data
# 允許最大連線數
max_connections=200
# 允許連線失敗的次數。這是為了防止有人從該主機試圖攻擊資料庫系統
max_connect_errors=10
# 服務端使用的字符集預設為UTF8
character-set-server=utf8
# 建立新表時將使用的預設儲存引擎
default-storage-engine=INNODB
# 預設使用“mysql_native_password”外掛認證
default_authentication_plugin=mysql_native_password
[mysql]
# 設定mysql客戶端預設字符集
default-character-set=utf8
[client]
# 設定mysql客戶端連線服務端時預設使用的埠
port=3306
default-character-set=utf8

請注意下面的路徑設定要正確,

# 設定mysql的安裝目錄
basedir=D:\program\mysql\mysql-8.0.12-winx64
# 設定mysql資料庫的資料的存放目錄
datadir=D:\program\mysql\mysql-8.0.12-winx64\data

如果你想從任意一個命令視窗啟動 mysql,請把 D:\program\mysql\mysql-8.0.12-winx64\bin 加入環境變數。*

這個 my.ini 檔案的編碼一定儲存為 gbk 格式,否則會報錯,我費了好長時間才發現這個問題。

接下來在MySQL安裝目錄的 bin 目錄(D:\program\mysql\mysql-8.0.12-winx64\bin)下以管理員許可權執行命令:mysqld --initialize --console;執行完成後,在輸出資訊中會列印 root 使用者的初始密碼,比如

[Server] A temporary password is generated for [email protected]: rIafvf5f5G,a

表示臨時密碼為 rIafvf5f5G,a ,用於 root 使用者第一次登陸,之後再修改 root 使用者的密碼。

這一步執行後完成初始化操作,並在安裝目錄下生成 data 資料夾,用於存放資料。執行

mysqld --install

完成 mysql 服務的安裝,安裝完成之後,就可以通過命令 net start mysql 啟動 mysql 的服務了。通過命令 net stop mysql 停止服務。通過命令 sc delete mysql /mysqld -remove 解除安裝 mysql 服務。接下來就可以建庫、使用者、分配許可權了。

修改 root 密碼:
在 mysql 安裝目錄的 bin 目錄下執行命令:mysql -u root -p 然後輸入上面的密碼,進入 mysql 環境,執行

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密碼';

注意命令尾的“;”一定要有,這是 mysql 的語法,
管理員 root 的 host 是 localhost,代表僅限 localhost 登入訪問。如果要允許開放其他 ip 登入,則需要新增新的 host。如果要允許所有 ip 訪問,可以直接修改成“%”;

ALTER USER 'root'@'%' IDENTIFIED  BY '遠端登陸密碼';
  1. 建立資料庫,並分配使用者許可權

使用 root 使用者登陸 mysql 並執行

mysql>create database cmdb;

即可建立資料庫 cmdb,但是這個資料庫只能有 root 訪問,如果要使用其他使用者訪問,則先新建使用者,例如讓 aaron 使用者可以完全控制 cmdb

mysql>CREATE USER 'aaron'@'%' IDENTIFIED  BY 'aaron';
Query OK, 0 rows affected (0.48 sec)
mysql> grant all on cmdb.* to  'aaron'@'%';
Query OK, 0 rows affected (0.23 sec)

至此 mysql 已安裝配置完畢。

(2)安裝 Elasticsearch

這一步很簡單,官網下載解壓,進入其 bin 目錄執行如下圖所示的 bat 檔案即可 :

如果執行失敗,說明本機沒有安裝 java,或者沒有正確地配置 java 環境變數,這些操作也非常簡單,網上到處都是,不在此詳述。

(3)執行 cmdb 後端 api 服務、前端 ui

首先準備 Python3 的環境,這個也很簡單,直接官網下載,執行即可,記得把 Python 新增到 Path 變數中。

如果你的電腦裡有多個專案,為防止專案的依賴包版本衝突,建議使用 virtualenv 來為每個專案前建立一個虛擬的 Python 環境,將各自的依賴包裝在自己的虛擬環境裡。

(1)部署後端

執行以下命令,注意命令後面的註釋。

git clone https://github.com/open-cmdb/cmdb.git
cd cmdb
#如建立了虛擬環境,請先啟用
pip install  -r requirements.txt #如果這一步有包安裝失敗,提示卻少 microsoft visual c++ 14.0 的話,請在網站 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 上查詢相應的whl檔案,直接 pip install .whl檔案即可。

接下來修改3個檔案

  1. 修改 apps/mgmt/views.py 檔案,註釋掉 “ from . import initialize ”這一行。
  2. 修改 manage.py
    將 APP_NAME = BASE_DIR.rsplit("/", 1)[-1] 修改為
    APP_NAME = BASE_DIR.rsplit("\", 1)[-1] ,這是因為windows的路徑\ 在python 裡會變成 \。
  3. 修改 cmdb/settings.py 檔案,修改mysql 資料庫的配置資訊如下所示:
DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.mysql',
    'NAME': "cmdb",
    "HOST": "127.0.0.1",
    "PORT": 3306,
    "USER": "aaron",
    "PASSWORD": "aaron"
  }
}

接著在命令視窗繼續執行以下操作:請關注註釋內容。

python manage.py makemigrations 
python manage.py migrate
python manage.py cmdb_create_superuser #這一步建立一可以登陸的管理員使用者
#修改 apps/mgmt/views.py 檔案,取消註釋“ from . import initialize ”
python manage.py runserver #這一步啟動後端的 api 服務

此時一個後端的服務已經啟動了,在瀏覽器中開啟 “127.0.0.1:8000”就可以看到 api 的介面了。

(2)使用 nginx 部署前端並連線後端 api 服務

在命令容器執行以下命令:

git clone https://github.com/open-cmdb/cmdb-web.git

獲取前端的原始碼,然後下載下載 ngnix 壓縮包,並解壓至安裝目錄,修改配置檔案 nginx.conf,新增如下 server 配置:

    server {
        listen 8080;
        server_name localhost;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        root html;
        }
        
        root E:\GitHub\cmdb-web\dist;
        index index.html;
        location / {
        try_files $uri $uri/ @router;
        index index.html;
        }
        
        location @router {
        rewrite ^.*$ /index.html last;
        }

        location ~ /api{
        proxy_pass http://127.0.0.1:8000;
        }
    }

其中以配置

  location ~ /api{
        proxy_pass http://127.0.0.1:8000;
        }

讓前臺發過來中以 api 開頭的 url 請求都轉發至 http://127.0.0.1:8000 進行解析,即第一步部署的 django 專案,這樣就連線了前端和後端。然後我們在 nginx.exe 所在的目錄下啟動 nginx 服務。

接下來在瀏覽器中輸入 127.0.0.1:8080 即可正常訪問本文開始處的 cmdb 系統,您可以嘗試下強大的搜尋功能及增刪改功能。

點選右上方【API 文件】 可以訪問 cmdb 的介面文件,非常方便。

至此係統搭建完畢。如果要用於生產環境,請使用 linux 作業系統,並使用 uwsgi 來驅動 django 專案。

3. Vue 環境搭建

我想你不會僅僅滿足於將別人的專案下載下來能執行就行了,你肯定想對其進行改造來滿足自己的需求。因此你可能會需要修改前端或後端,後端的修改其實上面部署的已經可以了,你可以直接閱讀 django 專案的原始碼進行修改除錯。如果要修改前端程式碼進行除錯,你就需要搭建 Vue 環境。

你可能會問了,Vue 是個啥?Vue 是一個 javascript 框架,如果說 jQuery,你可能就知道了,使用方法是類似的,在 html 上引入一行 javascript 的檔案,就可以使用框架的特性了。 Vue 是一套用於構建使用者介面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關注檢視層,不僅易於上手,還便於與第三方庫或既有專案整合。另一方面,當與現代化的工具鏈以及各種支援類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。
學習 vue 需要有 html、css、javascript 基礎
新手可以通過 html 上引入 Vue 的 js 檔案來使用 vue,如下所示:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 測試例項 </title>
	<script src="https://cdn.staticfile.org/vue/2.4.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  	<p>{{ message }}</p>
</div>

<script>
    new Vue({
	  el: '#app',
	  data: {
	    message: 'Hello Vue.js!'
	  }
})
</script>
</body>
</html>

但是在較複雜的專案中,還是要使用工具來幫助我們管理專案的層級及檔案之間的依賴關係,這就需要使用 vue 的命令列工具 vue-cli ,vue-cli 需要 npm 工具來安裝,npm 工具整合在 node.js 中,因此需要安裝 node.js。
安裝 node.js 非常簡單,直接官網下載解壓即可使用:
在這裡插入圖片描述

將此路徑新增到環境變數 Path 中,你就可以在任意的命令視窗使用 npm 命令了。
1、安裝 vue-cli

先安裝淘寶映象,大家都知道國內直接使用 npm 的官方映象是非常慢的,這裡推薦使用淘寶 NPM 映象。

npm install -g cnpm --registry=https://registry.npm.taobao.org

執行結果如下:
在這裡插入圖片描述
這樣就可以使用 cnpm 命令來安裝模組了:使用 cnpm 安裝 vue-cli
在這裡插入圖片描述

然後就可以使用 vue init webpack my-project 來建一個專案my-project,這裡需要進行一些配置,預設回車即可,如下圖所示:
在這裡插入圖片描述

等依賴安裝完畢後,進入專案,執行以下命令:

C:\Users\xx>cd my-project
C:\Users\xx\my-project>cnpm install
C:\Users\xx\my-project>cnpm run dev

執行成功後後列印如下資訊:
在這裡插入圖片描述

此時開啟瀏覽器,輸入 http://localhost:8081
在這裡插入圖片描述

如果要把這個頁面部署在 nginx 伺服器上,你還需要 build 來生成靜態資源,如下圖所示:

在這裡插入圖片描述
這時會在 my-project 下生成 dist 目錄,相當於我們寫程式編譯生成的目標檔案。my-project 下的內容如下:

在這裡插入圖片描述
在這裡插入圖片描述

此時已經可以開啟你的 vue 之旅了。

當學會了 Vue 之後,你就可以修改本專案的前端原始碼來滿足自己的需求了,進入 src 目錄,檢視並修改原始碼之後,進入 cmdb_web 的專案目錄,執行

# 安裝依賴,如果慢可換成 cnpm
npm install
# 啟動服務,預設埠為8080,如果被佔用會自動選取一個未被佔用的埠
npm run dev
# 建立靜態檔案,可以放在 nginx 上執行
npm run build
# 檢視建立報告
npm run build --report

即可將生成的 dist 部署到 web 伺服器了。

也許你想這樣實在太麻煩了,自己動手寫一個 cmdb 系統,當然也可以,但是我不推薦這樣做,畢竟你的時間是有限的,自己寫一個要比拿優秀的程式碼來改造要慢得多,當然大神例外,作為一般人我們應該避免重複造輪子,學會站在巨人的肩膀上。開發一個專案最好是找 github 上優秀的開源專案,拿來做修改以滿足自己的需求,這才是正確的做法。

(完)

訂閱請關注微信公眾號 somenzz