2021年2月3日 星期三

[經驗分享] 無外網情況下以 Docker 部署 LibreNMS

 


LibreNMS 已經是許多客戶找我建置時最需要的軟體系統,在絕大多數情況下我都能快速的安裝完成,再進行設定使用。

但最近遇到的案例比較麻煩,因為他們的網路限制非常嚴格,幾乎要在不能連接到 Internet 的情況下完成安裝,這對於大量採用各種開源軟體套件庫的 LibreNMS 是很不容易的事。






遇到困難

由於沒有網路可以使用,客戶的 Ubuntu Server 18.04 自然也無法直接使用 apt update、apt install 等等指令,所以只能採用預先將各種 deb 安裝包下載至我的電腦,再丟進客戶所提供的 VM 裡進行安裝。

作法是在我的 Proxmox VE 裡開一個 Linux Container (LXC),選擇 Ubuntu Server 18.04,再以指令將相關的軟體安裝包及其相依套件安裝包下載好,相關的指令有兩種方式:


方法一,利用 apt 的 --download-only 參數

# 清理暫存區與下載相依套件
sudo apt clean
sudo apt-get install --download-only gnupg2 ca-certificates lsb-release apt-transport-https curl fping git graphviz imagemagick mtr-tiny nginx-full nmap python-memcache python-mysqldb rrdtool snmp snmpd whois unzip python3-pip mariadb-client mariadb-server php7.4-cli php7.4-curl php7.4-fpm php7.4-gd php7.4-json php7.4-mbstring php7.4-mysql php7.4-snmp php7.4-xml php7.4-zip composer

# 查看下載完成的檔案
ls -l /var/cache/apt/archives/

# 將所有 deb 檔上載到目標 VM 後進行安裝
sudo dpkg -i *.deb



方法二,撰寫 Script 搭配 download 方法

# 將以下內容存為 deb-download.sh
for i in $(apt-cache depends $1 | grep -E 'Depends|Recommends|Suggests' | cut -d ':' -f 2,3 | sed -e s/'<'/''/ -e s/'>'/''/); do sudo apt-get download $i 2>>errors.txt; done

# 寫另一支下載全部套件用 get-debs.sh
./deb/deb-download.sh gnupg2
./deb/deb-download.sh ca-certificates
...以下略

# 執行下載作業
./get-debs.sh

# 將所有 deb 檔上載到目標 VM 後進行安裝
sudo dpkg -i *.deb


然而,在安裝過程中不斷發現各種軟體套件的缺少,補到最後已經補到懷疑人生....


套件相依性地獄再現







變通方案

既然無法改變客戶環境,只好從我們自己做起。

在開源軟體領域裡面最不缺的就是靈活與彈性,Docker 容器技術正是為了解決這一類軟體部署而設計的好方法。


準備環境


首先將 Docker CE 所需要的安裝檔取回:
wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce_20.10.2~3-0~ubuntu-bionic_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce_18.06.3~ce~3-0~ubuntu_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce-rootless-extras_20.10.2~3-0~ubuntu-bionic_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/docker-ce-cli_20.10.2~3-0~ubuntu-bionic_amd64.deb
wget https://download.docker.com/linux/ubuntu/dists/bionic/pool/stable/amd64/containerd.io_1.4.3-1_amd64.deb 

將 Docker CE 相關安裝檔放到目標 VM 上,再以指令一次安裝好:
# 離線安裝 Docker CE
sudo dpkg -i *.deb

接著,我先在自己有安裝 Docker CE 的的電腦拉取已經預先封裝的 LibreNMS Docker image,確認可以使用後,再將它存成打包檔:
# 拉取 LibreNMS Docker image
sudo docker pull jarischaefer/docker-librenms

# 轉存與壓縮 LibreNMS Docker image
sudo docker save jarischaefer/docker-librenms -o /tmp/docker-librenms.tar
gzip /tmp/docker-librenms.tar


將打包出來的 docker-librenms.tar.gz 檔丟到目標 VM 裡,再用指令將它載入 Docker CE 裡:
# 解壓縮 LibreNMS Docker image
gunzip docker-librenms.tar.gz

# 載入 LibreNMS Docker image
sudo docker load -i docker-librenms.tar




啟動系統


以指令先產生一組金鑰,供後面啟動服務使用。
# 產生 APP 金鑰
sudo docker run --rm jarischaefer/docker-librenms generate_key

輸出結果如 base64:Q0+ZV56/5Uwz79vsvS4ZfwQFOty3e9DJEouEy+IXvz8=


請將產生結果記下,接下來可以啟動此 LibreNMS Docker。
# 啟動 LibreNMS 服務
sudo docker run \
 -d \
 -h librenms \
 -p 80:80 \
 -e APP_KEY=base64:Q0+ZV56/5Uwz79vsvS4ZfwQFOty3e9DJEouEy+IXvz8= \
 -e DB_HOST=database \
 -e DB_NAME=librenms \
 -e DB_USER=librenms \
 -e DB_PASS=librenmspwd \
 -e BASE_URL=http://localhost \
 --link librenms-mysql:database \
 -v /data/logs:/opt/librenms/logs \
 -v /data/rrd:/opt/librenms/rrd \
 --name librenms \
 jarischaefer/docker-librenms


第一次成功啟動後,還要做幾項初始化設定的作業。
# 建立 LibreNMS 所需資料庫
sudo docker exec librenms setup_database

# 建立管理者帳戶 (帳密 admin/admin)
sudo docker exec librenms create_admin

# 設定 Docker 開機後自動啟動
sudo systemctl enable docker.service

# 設定 LibreNMS 於 Docker 啟動後自動啟動
sudo docker update --restart=always <容器ID>


做到這裡,即可開啟瀏覽器登入 LibreNMS 使用者界面,恭喜!

折騰我無數個夜晚終於...熱淚盈框








結論

雖然我在使用 LibreNMS 時並不喜歡用 Docker 來做,但有些問題還真的只能靠容器技術協助我們解決。

在本文的 Docker 啟動方式,資料庫是採用同一個 Docker image 裡面的 MySQL 資料庫伺服器來運作。若是要正式上線使用的服務,建議將資料庫服務另外起一個 Docker 運作,或者使用 Docker-Compose 進行啟動與連結,將服務分拆較為理想。


看到這裡可能有朋友會發現,為什麼我用的不是 LibreNMS 官方的 Docker image,而是另外使用 jarischaefer 所打包的 Docker image?



Docker Hub 上的兩種 LibreNMS Docker Image


其實答案不難猜,因為官方的 Docker image 我試了很久,解決很多問題仍然無法讓它運作起來,反而是 jarischaefer 所打包的 Docker image,按照其文件手冊操作最終可以順利運作,而且他把相關參數與建議都寫的很清楚,一目了然。









參考資料