我尝试了一下Sensu-go
建立Sensu-go这篇文章是有关Sensu-go的命令日志,涵盖了使用至目前可用的内容。
经过因为被孩子们缠着要求,在家中搭建了Minecraft服务器,结果却被指责使用困难,所以我决定进行监控。哈哈
世の中には途方もない手間のかかったゴイスー素敵なマップを無償公開されている方々が、しかもたくさんおられて、家庭内サーバでは子供たちがJava版マインクラフトのカスタムマップをNintendo Switchから使えるようプロトコル変換して遊ばせています。
監視には sensu-go を使いました。ドキュメント通りやって、うまくいきました。良いドキュメントと思います。ただ、ググっても解説が少なかったので書き残します。お役に立てば幸いです。
@see https://docs.sensu.io/sensu-go/latest/
監視結果は Slack 通知することにしました。通知は意図でチャネルを変えて3パターン(ops/dev/そのほかと)通知できるそうです。設定は全てYAMLかJSONで記述することができ、git保存も可能です。この辺りの自在感が好ましい監視ソフトです。
引入的环境家庭内サーバは今のところ家庭内LAN (1ギガイーサネット)のみで運用しており、インターネットに出していません。ここは、近所の子が遊び出したら考えることにします。
服务器上的服务与本地主机共存,包括以下内容;
-
- java8 のマイクラサーバ (paper-spigot + 20程度のプラグイン)
-
- dynmapだとかをプロキシする nginx
- ユーザデータの保存だとかLuckpermsなどが使う MySQL8
サーバは Parallels という仮想マシンソフトの上のVMで、OSは ubuntu 20.04、標準ユーザ?は mc です。ホストマシンは Core i7 の MBP(2018くらい) です。
(後ほど必要になりますが、データベースの接続情報やDB名やらは適宜置き換えてご参照くださいませ)
关于观测机制观测的机制在以下链接中有简洁的解释: https://docs.sensu.io/sensu-go/latest/observability-pipeline/
Sensu-go 监测的机制是通过后端与代理之间的发布/订阅式异步消息传递,后端广播主题,代理检查订阅的主题并向后端注册事件。根据事件注册,后端会进行选择、整理和相应处理。
agentの内側が Un*x らしいパイプ処理になっているらしく、値の収集元とagentとのデータ変換を柔軟に実装できる様子でした。
積み残しなお sensu-go の魅力の一つは(sensu と違って RabbitMQ 等の)ミドルウェア不要なことでした。
また Sensu-go 自体の導入やプラグインの導入も統一されたリポジトリと操作で一気通貫なことが簡単でした(DevOpsのツールとしては意外にw)
ただし、今回監視のみなので事足りましたが(我が家、気付いたら再起動するだけですので)、 sensu-go のみですと監視データの蓄積は行わないそうで、記録を残してビジュアル化する場合には追加のセットアップが必要だそうです(fluentdみたいに観測値をDBへ転送・保存し、別途ビジュアル化のツールを使うそうです)。これは後日の課題といたしました。
以下ログ以下是在ssh连接的bash中执行的命令日志。
安装工具和软件源
$ sudo apt update -y
:
$ sudo apt-get install gnupg curl wget unzip -y
:
$ curl -s https://packagecloud.io/install/repositories/sensu/stable/script.deb.sh | sudo bash
:
安装 Sensu Go 后端
$ sudo apt install sensu-go-backend
:
$ sudo curl -L https://docs.sensu.io./sensu-go/latest/files/backend.yml -o /etc/sensu/backend.yml
:
$ sudo systemctl start sensu-backend
$ sudo systemctl enable sensu-backend
:
$ sudo systemctl status sensu-backend
# check active
:
$ sensu-backend init --interactive
? Cluster Admin Username: mc
? Cluster Admin Password: **
? Retype Cluster Admin Password: **
:
$ curl http://localhost:3000
Client sent an API request to the web application port!
安装sensuctl
$ sudo apt install sensu-go-cli
:
$ sensuctl configure
? Authentication method: username/password
? Sensu Backend URL: http://127.0.0.1:8080
? Namespace: default
? Preferred output format: tabular
? Username: mc
? Password: **
安装 Sensu Go 代理
$ sudo apt install sensu-go-agent
:
$ sudo curl -L https://docs.sensu.io/sensu-go/latest/files/agent.yml -o /etc/sensu/agent.yml
:
$ sudo systemctl start sensu-agent
$ sudo systemctl enable sensu-agent
:
$ sudo systemctl status sensu-agent
# check active
:
$ sensuctl entity update mc
? Entity Class: agent
? Subscriptions: system,webserver,database
Updated
$ sensuctl entity list
ID Class OS Subscriptions Last Seen
──── ─────── ─────── ───────────────────────────────────── ───────────────────────────────
mc agent linux system,webserver,database,entity:mc 2021-03-29 18:20:39 +0900 JST
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check"
},
"status": 1,
"output": "You should receive this example event"
}
}' \
http://127.0.0.1:3031/events
# test warning
# warning can resolve by console (namespace -> events then check resolve).
检查nginx的例子
$ sensuctl asset add ncr-devops-platform/nagiosfoundation -r nagiosfoundation
:
$ sensuctl check create nginx_service \
--command 'check_service --name nginx' \
--interval 15 \
--subscriptions webserver \
--runtime-assets nagiosfoundation
$ sudo systemctl stop nginx
$ sensuctl event list
Entity Check Output Status Silenced Timestamp UUID
──────── ──────────────────── ──────────────────────────────────────────────────────────────────────── ──────── ────────── ─────────────────────────────── ──────────────────────────────────────
mc keepalive Keepalive last sent from mc at 2021-03-29 18:32:39 +0900 JST 0 false 2021-03-29 18:32:39 +0900 JST 3b42374e-d856-475b-9ece-eb2bd9d38839
mc nginx_service CheckService CRITICAL - nginx not in a running state (State: inactive) 2 false 2021-03-29 18:32:34 +0900 JST 68ca677a-b8c4-4619-bac9-654a50dd6615
$ sudo systemctl start nginx
$ sensuctl event list
:
查看MySQL的例子我已经安装了MySQL8。如果可以的话,你应该让MySQL使用utf8字符集(而不是utf8mb4)。在Ubuntu 20.04上请注意修改字符集。 🙂
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
$ sudo apt update -y
:
$ sudo apt-get install gnupg curl wget unzip -y
:
$ curl -s https://packagecloud.io/install/repositories/sensu/stable/script.deb.sh | sudo bash
:
安装 Sensu Go 后端
$ sudo apt install sensu-go-backend
:
$ sudo curl -L https://docs.sensu.io./sensu-go/latest/files/backend.yml -o /etc/sensu/backend.yml
:
$ sudo systemctl start sensu-backend
$ sudo systemctl enable sensu-backend
:
$ sudo systemctl status sensu-backend
# check active
:
$ sensu-backend init --interactive
? Cluster Admin Username: mc
? Cluster Admin Password: **
? Retype Cluster Admin Password: **
:
$ curl http://localhost:3000
Client sent an API request to the web application port!
安装sensuctl
$ sudo apt install sensu-go-cli
:
$ sensuctl configure
? Authentication method: username/password
? Sensu Backend URL: http://127.0.0.1:8080
? Namespace: default
? Preferred output format: tabular
? Username: mc
? Password: **
安装 Sensu Go 代理
$ sudo apt install sensu-go-agent
:
$ sudo curl -L https://docs.sensu.io/sensu-go/latest/files/agent.yml -o /etc/sensu/agent.yml
:
$ sudo systemctl start sensu-agent
$ sudo systemctl enable sensu-agent
:
$ sudo systemctl status sensu-agent
# check active
:
$ sensuctl entity update mc
? Entity Class: agent
? Subscriptions: system,webserver,database
Updated
$ sensuctl entity list
ID Class OS Subscriptions Last Seen
──── ─────── ─────── ───────────────────────────────────── ───────────────────────────────
mc agent linux system,webserver,database,entity:mc 2021-03-29 18:20:39 +0900 JST
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check"
},
"status": 1,
"output": "You should receive this example event"
}
}' \
http://127.0.0.1:3031/events
# test warning
# warning can resolve by console (namespace -> events then check resolve).
检查nginx的例子
$ sensuctl asset add ncr-devops-platform/nagiosfoundation -r nagiosfoundation
:
$ sensuctl check create nginx_service \
--command 'check_service --name nginx' \
--interval 15 \
--subscriptions webserver \
--runtime-assets nagiosfoundation
$ sudo systemctl stop nginx
$ sensuctl event list
Entity Check Output Status Silenced Timestamp UUID
──────── ──────────────────── ──────────────────────────────────────────────────────────────────────── ──────── ────────── ─────────────────────────────── ──────────────────────────────────────
mc keepalive Keepalive last sent from mc at 2021-03-29 18:32:39 +0900 JST 0 false 2021-03-29 18:32:39 +0900 JST 3b42374e-d856-475b-9ece-eb2bd9d38839
mc nginx_service CheckService CRITICAL - nginx not in a running state (State: inactive) 2 false 2021-03-29 18:32:34 +0900 JST 68ca677a-b8c4-4619-bac9-654a50dd6615
$ sudo systemctl start nginx
$ sensuctl event list
:
查看MySQL的例子我已经安装了MySQL8。如果可以的话,你应该让MySQL使用utf8字符集(而不是utf8mb4)。在Ubuntu 20.04上请注意修改字符集。 🙂
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
$ sudo apt install sensu-go-backend
:
$ sudo curl -L https://docs.sensu.io./sensu-go/latest/files/backend.yml -o /etc/sensu/backend.yml
:
$ sudo systemctl start sensu-backend
$ sudo systemctl enable sensu-backend
:
$ sudo systemctl status sensu-backend
# check active
:
$ sensu-backend init --interactive
? Cluster Admin Username: mc
? Cluster Admin Password: **
? Retype Cluster Admin Password: **
:
$ curl http://localhost:3000
Client sent an API request to the web application port!
$ sudo apt install sensu-go-cli
:
$ sensuctl configure
? Authentication method: username/password
? Sensu Backend URL: http://127.0.0.1:8080
? Namespace: default
? Preferred output format: tabular
? Username: mc
? Password: **
安装 Sensu Go 代理
$ sudo apt install sensu-go-agent
:
$ sudo curl -L https://docs.sensu.io/sensu-go/latest/files/agent.yml -o /etc/sensu/agent.yml
:
$ sudo systemctl start sensu-agent
$ sudo systemctl enable sensu-agent
:
$ sudo systemctl status sensu-agent
# check active
:
$ sensuctl entity update mc
? Entity Class: agent
? Subscriptions: system,webserver,database
Updated
$ sensuctl entity list
ID Class OS Subscriptions Last Seen
──── ─────── ─────── ───────────────────────────────────── ───────────────────────────────
mc agent linux system,webserver,database,entity:mc 2021-03-29 18:20:39 +0900 JST
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check"
},
"status": 1,
"output": "You should receive this example event"
}
}' \
http://127.0.0.1:3031/events
# test warning
# warning can resolve by console (namespace -> events then check resolve).
检查nginx的例子
$ sensuctl asset add ncr-devops-platform/nagiosfoundation -r nagiosfoundation
:
$ sensuctl check create nginx_service \
--command 'check_service --name nginx' \
--interval 15 \
--subscriptions webserver \
--runtime-assets nagiosfoundation
$ sudo systemctl stop nginx
$ sensuctl event list
Entity Check Output Status Silenced Timestamp UUID
──────── ──────────────────── ──────────────────────────────────────────────────────────────────────── ──────── ────────── ─────────────────────────────── ──────────────────────────────────────
mc keepalive Keepalive last sent from mc at 2021-03-29 18:32:39 +0900 JST 0 false 2021-03-29 18:32:39 +0900 JST 3b42374e-d856-475b-9ece-eb2bd9d38839
mc nginx_service CheckService CRITICAL - nginx not in a running state (State: inactive) 2 false 2021-03-29 18:32:34 +0900 JST 68ca677a-b8c4-4619-bac9-654a50dd6615
$ sudo systemctl start nginx
$ sensuctl event list
:
查看MySQL的例子我已经安装了MySQL8。如果可以的话,你应该让MySQL使用utf8字符集(而不是utf8mb4)。在Ubuntu 20.04上请注意修改字符集。 🙂
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
$ sudo apt install sensu-go-agent
:
$ sudo curl -L https://docs.sensu.io/sensu-go/latest/files/agent.yml -o /etc/sensu/agent.yml
:
$ sudo systemctl start sensu-agent
$ sudo systemctl enable sensu-agent
:
$ sudo systemctl status sensu-agent
# check active
:
$ sensuctl entity update mc
? Entity Class: agent
? Subscriptions: system,webserver,database
Updated
$ sensuctl entity list
ID Class OS Subscriptions Last Seen
──── ─────── ─────── ───────────────────────────────────── ───────────────────────────────
mc agent linux system,webserver,database,entity:mc 2021-03-29 18:20:39 +0900 JST
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check"
},
"status": 1,
"output": "You should receive this example event"
}
}' \
http://127.0.0.1:3031/events
# test warning
# warning can resolve by console (namespace -> events then check resolve).
$ sensuctl asset add ncr-devops-platform/nagiosfoundation -r nagiosfoundation
:
$ sensuctl check create nginx_service \
--command 'check_service --name nginx' \
--interval 15 \
--subscriptions webserver \
--runtime-assets nagiosfoundation
$ sudo systemctl stop nginx
$ sensuctl event list
Entity Check Output Status Silenced Timestamp UUID
──────── ──────────────────── ──────────────────────────────────────────────────────────────────────── ──────── ────────── ─────────────────────────────── ──────────────────────────────────────
mc keepalive Keepalive last sent from mc at 2021-03-29 18:32:39 +0900 JST 0 false 2021-03-29 18:32:39 +0900 JST 3b42374e-d856-475b-9ece-eb2bd9d38839
mc nginx_service CheckService CRITICAL - nginx not in a running state (State: inactive) 2 false 2021-03-29 18:32:34 +0900 JST 68ca677a-b8c4-4619-bac9-654a50dd6615
$ sudo systemctl start nginx
$ sensuctl event list
:
查看MySQL的例子我已经安装了MySQL8。如果可以的话,你应该让MySQL使用utf8字符集(而不是utf8mb4)。在Ubuntu 20.04上请注意修改字符集。 🙂
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
[client]
default-character-set=utf8
[mysql]
default-character-set=utf8
[mysqld]
collation-server = utf8_general_ci
character-set-server = utf8
别忘了重新启动mysqld。
我有一个文件,里面存着连接MySQL的凭证,路径是~/backupDB.cnf。这是一个非常私密的文件。
$ cd ~
$ touch backupDB.cnf
$ chmod o-rw backupDB.cnf
$ vi backupDB.cnf
$ cat backupDB.cnf
[client]
user = (YOUR MYSQL USER)
password = (YOUR MYSQL PASSWD)
host = 127.0.0.1
所以我就这样做了。
啊,是的,这种方法确实有点肮脏…考虑一下你的选择吧…
$ id
uid=1000(mc) gid=1000(mc) groups=1000(mc),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),116(lxd)
$ ps aux|grep sensu|grep -v grep
sensu 4195 4.2 1.5 5456808 126372 ? Ssl 16:42 10:46 /usr/sbin/sensu-backend start -c /etc/sensu/backend.yml
sensu 5507 0.1 0.6 128848 53488 ? Ssl 16:50 0:22 /usr/sbin/sensu-agent start -c /etc/sensu/agent.yml
$ usermod -aG mc sensu
$ id sensu
uid=997(sensu) gid=998(sensu) groups=998(sensu),mc(1000)
$ sudo systemctl restart sensu-backend
$ sudo systemctl restart sensu-agent
安装MySQL插件只是会稍微可爱一些。
$ sensuctl asset add sensu/sensu-ruby-runtime -r ruby-plugins
:
$ sensuctl asset add sensu-plugins/sensu-plugins-mysql:3.2.0 -r mysql-plugins
:
$ sensuctl check create mysql_connections \
--command 'check-mysql-connections.rb --warnnum 50 --critnum 75 --host=127.0.0.1 --ini=/home/mc/backupDB.cnf' \
--interval 15 \
--subscriptions database \
--runtime-assets ruby-plugins,mysql-plugins
$ sensuctl event list
:
使用处理程序发送Slack提醒
我选择逐个联系人发送警报,这会花费稍微多一点的时间。
首先,创建三个 Slack 频道(用于运营、开发和其他事务),然后创建三个 Webhook。
– #Minecraft-服务器-运营
– #Minecraft-服务器-开发
– #Minecraft-服务器-监控
而且… …)
$ sensuctl asset add nixwiz/sensu-go-fatigue-check-filter -r fatigue-filter
:
$ vi sensu-filter-fatigue_check.yaml
$ cat sensu-filter-fatigue_check.yaml
type: EventFilter
api_version: core/v2
metadata:
name: fatigue_check
namespace: default
spec:
action: allow
expressions:
- fatigue_check(event)
runtime_assets:
- fatigue-check-filter
$ sensuctl create -f sensu-filter-fatigue_check.yaml
:
$ sensuctl asset add sensu/sensu-go-has-contact-filter -r contact-filter
:
$ vi sensu-filter-contact.yaml
$ cat sensu-filter-contact.yaml
---
type: EventFilter
api_version: core/v2
metadata:
name: contact_fallback
spec:
action: allow
runtime_assets:
- contact-filter
expressions:
- no_contacts(event)
---
type: EventFilter
api_version: core/v2
metadata:
name: contact_ops
spec:
action: allow
runtime_assets:
- contact-filter
expressions:
- has_contact(event, "ops")
---
type: EventFilter
api_version: core/v2
metadata:
name: contact_dev
spec:
action: allow
runtime_assets:
- contact-filter
expressions:
- has_contact(event, "dev")
$ sensuctl create -f sensu-filter-has_contact.yaml
:
$ sensuctl asset add sensu/sensu-slack-handler -r sensu-slack-handler
:
$ vi sensu-handler-slack.yaml
# be care of slack channels and webhooks.
$ cat sensu-handler-slack.yaml
---
type: Handler
api_version: core/v2
metadata:
name: slack_fallback
spec:
command: sensu-slack-handler --channel "#minecraft-server-monitoring"
env_vars:
- SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T0000/B000/XXXXXXXX
filters:
- is_incident
- not_silenced
- fatigue_check
- contact_fallback
runtime_assets:
- sensu-slack-handler
type: pipe
---
type: Handler
api_version: core/v2
metadata:
name: slack_ops
spec:
command: sensu-slack-handler --channel "#minecraft-server-ops"
env_vars:
- SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T0000/B000/XXXXXXXX
filters:
- is_incident
- not_silenced
- fatigue_check
- contact_ops
runtime_assets:
- sensu-slack-handler
type: pipe
---
type: Handler
api_version: core/v2
metadata:
name: slack_dev
spec:
command: sensu-slack-handler --channel "#minecraft-server-dev"
env_vars:
- SLACK_WEBHOOK_URL=https://hooks.slack.com/services/T0000/B000/XXXXXXXX
filters:
- is_incident
- not_silenced
- fatigue_check
- contact_dev
runtime_assets:
- sensu-slack-handler
type: pipe
---
type: Handler
api_version: core/v2
metadata:
name: slack
namespace: default
spec:
handlers:
- slack_ops
- slack_dev
- slack_fallback
type: set
$ sensuctl create -f sensu-handler-slack.yaml
:
假设我们来测试一下。 .)
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check"
},
"status": 1,
"output": "You should receive this example event in the Slack channel specified by your slack_fallback handler.",
"handlers": ["slack"]
}
}' \
http://127.0.0.1:3031/events
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check",
"labels": {
"contacts": "dev"
}
},
"status": 1,
"output": "You should receive this example event in the Slack channel specified by your slack_dev handler.",
"handlers": ["slack"]
}
}' \
http://127.0.0.1:3031/events
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check",
"labels": {
"contacts": "ops"
}
},
"status": 1,
"output": "You should receive this example event in the Slack channel specified by your slack_ops handler.",
"handlers": ["slack"]
}
}' \
http://127.0.0.1:3031/events
$ curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"check": {
"metadata": {
"name": "example-check",
"labels": {
"contacts": "ops,dev"
}
},
"status": 1,
"output": "You should receive this example event in the Slack channel specified by your ops adn dev handler.",
"handlers": ["slack"]
}
}' \
http://127.0.0.1:3031/events
所以我们可以为代理商创建检查事项。
$ vi sensu-checks.yaml
$ cat sensu-checks.yaml
---
type: CheckConfig
api_version: core/v2
metadata:
created_by: mc
name: nginx_service
namespace: default
annotations:
fatigue_check/occurrences: '1'
fatigue_check/interval: '3600'
fatigue_check/allow_resolution: 'false'
labels:
contacts: ops
spec:
check_hooks: null
command: check_service --name nginx
env_vars: null
handlers:
- slack
high_flap_threshold: 0
interval: 15
low_flap_threshold: 0
output_metric_format: ""
output_metric_handlers: null
proxy_entity_name: ""
publish: true
round_robin: false
runtime_assets:
- nagiosfoundation
secrets: null
stdin: false
subdue: null
subscriptions:
- webserver
timeout: 0
ttl: 0
---
type: CheckConfig
api_version: core/v2
metadata:
created_by: mc
name: mysql_alive
namespace: default
annotations:
fatigue_check/occurrences: '1'
fatigue_check/interval: '3600'
fatigue_check/allow_resolution: 'false'
labels:
contacts: ops
spec:
check_hooks: null
command: check-mysql-alive.rb --database=playerdata --host=127.0.0.1 --ini=/home/mc/backupDB.cnf
env_vars: null
handlers:
- slack
high_flap_threshold: 0
interval: 15
low_flap_threshold: 0
output_metric_format: ""
output_metric_handlers: null
proxy_entity_name: ""
publish: true
round_robin: false
runtime_assets:
- ruby-plugins
- mysql-plugins
secrets: null
stdin: false
subdue: null
subscriptions:
- database
timeout: 0
ttl: 0
---
type: CheckConfig
api_version: core/v2
metadata:
created_by: mc
name: mysql_connections
namespace: default
annotations:
fatigue_check/occurrences: '1'
fatigue_check/interval: '3600'
fatigue_check/allow_resolution: 'false'
labels:
contacts: ops, dev
spec:
check_hooks: null
command: check-mysql-connections.rb --warnnum 50 --critnum 75 --host=127.0.0.1 --ini=/home/mc/backupDB.cnf
env_vars: null
handlers:
- slack
high_flap_threshold: 0
interval: 15
low_flap_threshold: 0
output_metric_format: ""
output_metric_handlers: null
proxy_entity_name: ""
publish: true
round_robin: false
runtime_assets:
- ruby-plugins
- mysql-plugins
secrets: null
stdin: false
subdue: null
subscriptions:
- database
timeout: 0
ttl: 0
$ sensuctl check delete nginx_service
? Are you sure you would like to delete resource 'nginx_service'? Yes
Deleted
$ sensuctl check delete mysql_connections
? Are you sure you would like to delete resource 'mysql_connections'? Yes
Deleted
$ sensuctl create -f sensu-checks.yaml
$ sudo systemctl stop nginx; \
sleep 20; \
sudo systemctl start nginx
结束