Beats:使用 Autodiscover 监控 Docker 容器
2021年7月14日 | by mebius
当你在容器上运行应用程序时,它们会成为监控系统的移动目标。在实际的容器部署中,我们通常并不知道到底部署多少个容器以及运行的接口是什么样的。这在实际的监控中是非常麻烦的。Autodiscover 允许你跟踪它们并在发生变化时调整设置。 通过定义配置模板,自动发现子系统可以在服务开始运行时对其进行监控。
在今天的展示中,我将使用 Heartbeat 来进行展示。如果你想了解更多关于 Heartbeat 的配置,你可以阅读我之前的文章:
你可以在 heartbeat.yml 配置文件的 heartbeat.autodiscover 部分定义自动发现设置。 要启用自动发现,请指定提供程序列表。
下载测试服务
在今天的练习中,我们将使用一个非常简单的 hello-app 应用来进行展示。我们可以在如下的地址下载这个应用:
docker pull phozzy/hello-app
它的源码位于:https://githtgcodeub.com/phozzy/hello-app
这个应用是一个 go 语言编译的应用。它非常之简单:
main.go
package main
import (
"fmt"
"log"
"net/http"
"os"
)
func main() {
// use PORT environment variable, or default to 8080
port := "8080"
if fromEnv := os.Getenv("PORT"); fromEnv != "" {
port = fromEnv
}
// register hello function to handle all requests
server := http.NewServeMux()
server.HandleFunc("/", hello)
// start the web server on port and accept requests
log.Printf("Server listening on port %s", port)
err := http.ListenAndServe(":"+port, server)
log.Fatal(err)
}
// hello responds to the request with a plain-text "Hello, world" message.
func hello(w http.ResponseWriter, r *http.Request) {
log.Printf("Serving request: %s", r.URL.Path)
host, _ := os.Hostname()
fmt.Fprintf(w, "Hello, GKE!n")
fmt.Fprintf(w, "Version: %sn", os.Getenv("VERSION"))
fmt.Fprintf(w, "Hostname: %sn", host)
}
在默认的情况下,这个应用运行于 8080 口上。从上面的应用中,我们可以看出来它有一个接口 “/”,运行后输出一些文字。
我们通过如下的命令来查看已经下载的 docker image:
$ docker images | grep hello-app
phozzy/hello-app latest ccc079c68c8d 16 months ago 11.5MB
我们使用如下的命令来进行运行:
docker run --name hello-app-1 -p 8888:8080 -d phozzy/hello-app:latest
$ docker run --name hello-app-1 -p 8888:8080 -d phozzy/hello-app:latest
952f433dad61a9991c2f4b5e5bf2da4fe15121990e0f69c1f2509ebe0376ba36
我们可以使用如下的命令来查看 container:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
952f433dad61 phozzy/hello-app:latest "./hello-app" About a minute ago Up About a minute 0.0.0.0:8888->8080/tcp, :::8888->8080/tcp hello-app-1
我们看到一个 conttgcodeainer 已经运行起来了。我们在浏览器中打入如下的地址 http://localhost:8888/hello:
我们可以看到如上的输出。
我们知道如果我们使用 HTTP 协议来监控这个服务时,我们必须很清楚地在 heartbeat.yml 文件中定义出来,比如:
heartbeat.yml
heartbeat.monitors:
- type: http
enabled: true
id: my-monitor
name: My Monitor
urls: ["http://localhost:8888/hello"]
schedule: '@every 10s'
从上面我们可以看出来,我们需要非常明确地告诉 Heartbeat 我们需要对哪个服务的接口进行监控。但是如果是使用 container 的话,那么这个 url 可能是变化的,比如我们可以使用如下的方式来启动这个服务:
docker run --name hello-app-1 -p 1234:8080 -d phozzy/hello-app:latest
在上面,我们把端口地址修改为 1234,那么是不是我们需要重新修正刚才的 heartbeat.yml 文件呢?另外一种情况是,我们假如不使用之前的端口地址 8888,而改为新的端口地址,那么我们是不是也要重新来修改 heartbeat.yml 文件呢?
如果是,那么我们需要不断地修改这个 heartbeat.yml 文件。这样会显得非常之麻烦。如果你使用 Kubernetes 时,通常这些容器都是动态生成的。我们需要一种动态的方法来跟踪这些变化并自动做适当的调整。
使用 Autodiscover 来动态跟踪动态部署
我们首先来创建一个崭新的文件 dynamic-config.yml 文件。它的内容如下:
dynamic-config.yml
heartbeat.autodiscover:
providers:
- type: docker
templates:
- condition:
contains:
docker.container.image: phozzy/hello-app:latest
config:
- type: http
name: "Hello instance ${data.docker.container.name}"
hosts: ["${data.host}:${data.port}/hello"]
schedule: "@every 5s"
output.elasticsearch:
hosts: localhost:9200
在上面,我们创建了一个 type 为 docker 的 provider。根据 Elastic 官方文档,这个 type 也可以是 kubernetes 或 AWS。在今天的练习中,我将使用 docker。我们为 docker 创建了一个 template。一个 template 由 condition 及 config 组成。只要满足条件的,就会使用相应定义的 config。针对我们的情况,我们希望 docker image 里含有phozzy/hello-app:latest。如果这个条件满足,它就会自动地使用在 config 中定义的参数。在上面的 name 及 hosts 中,我们动态地从 docker 中获取一些数据,并配置。在上面的最后,我们把数据传入到 Elasticsearch 中。
我们接下来使用如下的命令来启动 Heartbeat:
./heartbeat -c dynamic_config.ym -e
我们打开 Kibana 中的 Uptime 应用:
我们看到之前启动的一个服务 hello-app-1 的状态是 Up 的。
为了检测我们的 Autodiscover 是否工作,我们来启动另外一个 container:
docker run --name hello-app-2 -p 9999:8080 -d phozzy/hello-app:latest
$ docker run --name hello-app-2 -p 9999:8080 -d phozzy/hello-app:latest
96ebc6f90bdf68308b20c6e58eb6bebaa680e0af7e18ac53f2860f7115de4012
这一次,我们设置的端口地址是 9999,并且 container 的名字为 hello-app2。等服务运行起来后,我们再次来查看 Uptime 应用:
我们可以看到tgcode一个自动增加的监控被生成了。上面显示两个服务都是 Down,这是因为我们的 heartbeat 运行在 host,而我们的服务是运行于 172.17.0.2/3这个内网里。这个可以通过把 Heartbeat 置于和 hello-app 这个服务同一个网络来进行解决。
文章来源于互联网:Beats:使用 Autodiscover 监控 Docker 容器
相关推荐: Elasticsearch:如何在导入时忽略格式错误的数据
有时,你对收到的数据没有太多控制权。 一个用户可以发送一个日期形式的 login 字段,另一个用户发送一个电子邮件地址形式的 login 字段。 默认情况下,尝试将错误的数据类型索引到字段中会引发异常,并拒绝整个文档。 ignore_malformed 参数如…