Docker已經成為了現代化應用中的一項必備技術,但是使用Docker進行應用監控和日志管理卻是一項挑戰。隨著Docker網絡功能,如Service Discovery和Load Balancing的不斷增強,我們越來越需要一個完整、穩定,以及高效的應用監控系統。
在本文中,我們將簡單地介紹使用Docker進行應用監控和日志管理的同時給出具體的代碼示例。
利用Prometheus進行應用監控
Prometheus是一款開源,基于Pull模型的服務監測和警告工具,由SoundCloud開發。它使用Go語言編寫,被廣泛應用于微服務方案和云環境中。作為一款監控工具,它可以對Docker的CPU、內存、網絡和磁盤等進行監控,并且還支持多維數據切換、靈活的查詢、報警以及可視化等功能,讓你可以快速做出反應,并快速做出決策。
還有一點需要注意的是,Prometheus需要通過Pull方式的采樣,也就是訪問被監控應用中的/metrics接口獲取監控數據。所以,在啟動被監控應用鏡像時,需要先將可以訪問到Prometheus的IP和端口配置到/metrics接口中。下面是一個簡單的Node.js應用。
const express = require('express')
const app = express()
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.get('/metrics', (req, res) => {
res.send(`
# HELP api_calls_total Total API calls
# TYPE api_calls_total counter
api_calls_total 100
`)
})
app.listen(3000, () => {
console.log('Example app listening on port 3000!')
})
登錄后復制
在該代碼中,我們通過/metrics接口,返回了一個api_calls_total的監控指標。
接著,在官網上下載Prometheus的Docker鏡像,并創建一個docker-compose.yml文件,并且在該文件中,我們獲取該Node.js應用的數據。
version: '3'
services:
node:
image: node:lts
command: node index.js
ports:
- 3000:3000
prometheus:
image: prom/prometheus:v2.25.2
volumes:
- ./prometheus:/etc/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.retention.time=15d'
ports:
- 9090:9090
登錄后復制
該docker-compose.yml文件中,我們定義了兩個服務,一個是運行Node.js應用的Node服務,另一個是用于監控的Prometheus服務。其中,Node服務發布的端口為3000端口,通過端口映射,可以通過docker-compose.yml中的IP和3000端口訪問到該Node應用的/metrics接口。而Prometheus則可以通過9090端口訪問對應的監控指標數據。
最后,在prometheus.yml文件中,我們需要定義要獲取的數據來源。
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node-exporter'
static_configs:
- targets: ['node:9100']
- job_name: 'node-js-app'
static_configs:
- targets: ['node:3000']
登錄后復制
在該文件中,我們定義了要采集的所有的Node.js應用的指標,其中targets參數是Node.js應用的IP地址及其對應端口號。在這里,我們使用的是node和3000端口。
最后,運行docker-compose up命令,即可啟動整個應用及其監控服務,并在Prometheus中查看該會員指標。
利用ElasticSearch和Logstash進行日志管理
在Docker中,應用的日志數據分布在不同的Docker容器中。如果你要在集中的地方對這些日志進行管理,那么可以通過使用ELK中的ElasticSearch和Logstash,將日志中心化管理,以便更輕松地實現計算機資源的監控和分析。
在開始之前,需要先下載Logstash和ElasticSearch的Docker鏡像,并創建一個docker-compose.yml文件。
在該文件中,我們定義了三個服務,其中bls是用來模擬業務日志的API服務,其每次響應后,將記錄一條日志到stdout和日志文件中。logstash服務是由Logstash官方提供的Docker鏡像構建,用于收集、過濾和傳輸日志。ElasticSearch服務用于存儲和檢索日志。
version: '3'
services:
bls:
image: nginx:alpine
volumes:
- ./log:/var/log/nginx
- ./public:/usr/share/nginx/html:ro
ports:
- "8000:80"
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "10"
logstash:
image: logstash:7.10.1
volumes:
- ./logstash/pipeline:/usr/share/logstash/pipeline
environment:
- "ES_HOST=elasticsearch"
depends_on:
- elasticsearch
elasticsearch:
image: elasticsearch:7.10.1
environment:
- "http.host=0.0.0.0"
- "discovery.type=single-node"
volumes:
- ./elasticsearch:/usr/share/elasticsearch/data
登錄后復制
在配置文件中,我們映射了容器內的路徑到宿主機的日志文件系統中。同時通過logging的option,則定義了日志的卷大小和數量,以限制日志的占用存儲。
在配置文件的logstash中,我們定義了一個新的pipeline,其名為nginx_pipeline.conf,該文件用于處理nginx日志的收集、過濾和傳輸。與ELK的工作原理相同,logstash將根據不同的條件,對接收到的日志進行處理,并將其發送到已經創建的 Elasticsearch 集群中。在該配置文件中,我們定義了如下處理邏輯:
input {
file {
path => "/var/log/nginx/access.log"
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
output {
elasticsearch {
hosts => [ "${ES_HOST}:9200" ]
index => "nginx_log_index"
}
}
登錄后復制
在該配置文件中,我們定義了一個name為file的輸入,表示要從本地Log文件中讀取數據。接著,我們引入了使用grok庫來解析符合特定模板的日志的filter。最后,我們定義了輸出,其將數據傳輸到 Elasticsearch 集群的地址,同時將檢索和報告通過環境變量ES_HOST傳遞到容器中。
在最后,如上完成整個ELK的配置后,我們會得到一個高效的日志管理系統,每條日志都將發送到集中的地方,并被整合在一起,可以實現簡便的搜索,過濾和可視化操作。






