# Rancher Monitoring
## Preface
本篇文章會稍微介紹 Prometheus 和 Alertmanager 在做哪些事情,並實作如何在 Rancher 上將 Kubernetes 的告警發送到指定 E-mail Address。
## ALERTING OVERVIEW
Prometheus 的警報分為兩個部分。Prometheus Server 中的警報規則會向 Alertmanager 發送警報。 然後 Alertmanager 管理這些警報,包括靜音 ( silencing )、抑制 ( inhibition )、聚合 ( aggregation ) 以及透過電子郵件、值班通知系統 ( on-call notification systems ) 和聊天平台等方式發送通知。
設定警報和通知的主要步驟是
* 設定 Prometheus 與 Alertmanager 連接
* 在 Prometheus 中建立警報規則 (Rancher 預設有很多警報規則)
## ALERTMANAGER
Alertmanager 可處理 Prometheus Server 等用戶端應用程式所傳送的警報。它負責對警報進行重複 ( deduplicating )、分組 ( grouping ),並將其路由到正確的接收器整合(如電子郵件、PagerDuty 或 OpsGenie)。 它還負責管理警報的靜音和抑制。
以下介紹 Alertmanager 實作的核心概念 :
### Grouping
分組 ( Grouping ) 將性質相似的警報歸類到一個通知中。當許多系統同時發生故障,數百個警報可能同時響起時,這在較大的故障期間尤其有用。
例如: 當網路分割區發生時,叢集正在執行數十或數百個服務執行個體。一半的服務無法再存取資料庫。Prometheus 中的警報規則被設定為在每個服務無法與資料庫通訊時為其發送警報。結果,數百個警報被發送到 Alertmanager。
作為用戶,我們只希望取得一個頁面,同時也能看到受影響的服務。 因此,可以對 Alertmanager 進行設定,按群集和警報名稱對警報進行分組,這樣就能發送一個簡潔的通知。
警報分組、分組通知的時間以及這些通知的接收者都是透過設定檔中的路由樹 ( routing tree ) 來設定的。
### Inhibition
抑制 ( Inhibition ) 的概念是,如果某些其他警報已經觸發,則抑制某些警報的通知。
例如: 一個警報正在發出,通知整個叢集無法存取。可以對 Alertmanager 進行設定,使其在該特定警報觸發時靜音處理與該群集相關的所有其他警報。這樣就可以防止數百或數千個與實際問題無關的警報觸發通知。
抑制功能可透過 Alertmanager 的設定檔進行設定。
### Silences
靜音是將警報靜音一段時間的直接方法。 靜音是根據匹配器 ( matchers ) 設定的,就像路由樹一樣。會檢查傳入的警報是否與活動靜默的所有等價或正規表示式匹配器相符。如果匹配,則不會為該警報發送通知。
靜默在 Alertmanager 的 Web 介面中進行設定。
### Client behavior
Alertmanager 對其客戶端的行為有特殊要求。這些要求只適用於不使用 Prometheus 發送警報的高階用例。
### High Availability
Alertmanager 支援為高可用性建立叢集的設定。 可以使用 `--cluster-*` 標記進行設定。
重要的是,不要在 Prometheus 及其 Alertmanager 之間進行負載平衡,而是將 Prometheus 指向所有 Alertmanager 的清單。
## 實作
### Prerequest
- SMTP OS: SUSE Linux Enterprise Server 15 SP 5
- Rancher: v2.8.2
- DownStream Cluster: RKE2 v1.27.11
### 0. 自簽 SMTP Server 需要用的憑證
```bash!
# Generate a Certificate Authority Certificate
## Generate a CA certificate private key.
$ openssl genrsa -out ca.key 4096
## Generate the CA certificate.
$ openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=TW/ST=Taiwan/L=Taipei/O=example/OU=lab/CN=smtp.example.com" \
-key ca.key \
-out ca.crt
# Generate a Server Certificate
## Generate a private key.
$ openssl genrsa -out server.key 4096
## Generate a certificate signing request (CSR).
$ openssl req -sha512 -new \
-subj "/C=TW/ST=Taiwan/L=Taipei/O=example/OU=lab/CN=smtp.example.com" \
-key server.key \
-out server.csr
## Generate an x509 v3 extension file.
$ cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1=smtp.example.com
DNS.2=example.com
DNS.3=smtp
EOF
## Use the v3.ext file to generate a certificate for your Harbor host.
$ openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in server.csr \
-out server.crt
```
### 1. 安裝 SMTP Server 並且啟動 TLS
```bash!
# Install Postfix.
$ sudo zypper -n install postfix
# rename to disable
$ sudo mv /etc/sysconfig/postfix /etc/sysconfig/postfix.org
$ sudo nano -l /etc/postfix/main.cf
# line 114: uncomment and specify domain name
mydomain = lab.com
# line 130: uncomment
myorigin = $mydomain
# line 294: uncomment and specify local network
mynetworks = 192.168.11.0/24
# line 451: uncomment to move Maildir
home_mailbox = Maildir/
# line 714: change
inet_interfaces = all
# line 719: add
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
# line 720: specify hostname
myhostname = lab.com
# line 735
# limit a message size if need (example below means 10M limit)
message_size_limit = 10485760
# line 747: change
smtpd_recipient_restrictions = permit_mynetworks, permit_auth_destination, permit_sasl_authenticated, reject
# Configure SSL/TLS to encrypt connections
# line 782: change
smtpd_use_tls = yes
# line 788: specify certificates
smtpd_tls_cert_file = /home/rancher/smtp/server.crt
smtpd_tls_key_file = /home/rancher/smtp/server.key
# line 793: add
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
## enable port 587 (submission) in postfix
$ sudo nano /etc/postfix/master.cf
### line: 24 取消註解
submission inet n - n - - smtpd
# line 25,26,28: uncomment
submission inet n - n - - smtpd
-o syslog_name=postfix/submission
-o smtpd_tls_security_level=encrypt
-o smtpd_sasl_auth_enable=yes
# line 43-45: uncomment
submissions inet n - n - - smtpd
-o syslog_name=postfix/submissions
-o smtpd_tls_wrappermode=yes
# line 64: uncomment
tlsmgr unix - - n 1000? 1 tlsmgr
```
啟動 SMTP Service 並設為開機自動啟動
```
$ sudo systemctl enable --now postfix
```
### 2. 測試 SMTP Server
```bash!
# 本地測試寄信
$ echo "Test Postfix Gmail https://example.com" | mail -s "Postfix Gmail" "<your email address>"
# 在別台機器寄信
$ echo "Test Postfix Gmail 2" | mail -S smtp=192.168.11.85 -s "Postfix Gmail" "andy.wu@suse.com"
# 測試 TLS
$ openssl s_client -starttls smtp -connect smtp.example.com:587
```
### 3. 測試告警發信
#### 3.1. 建立 SMTP 的 TLS Secret
```bash!
$ kubectl create ns cattle-monitoring-system
$ kubectl -n cattle-monitoring-system create secret generic smtp-tls-secret \
--from-file=tls.crt=/home/rancher/smtp/server.crt \
--from-file=tls.key=/home/rancher/smtp/server.key \
--from-file=ca.crt=/home/rancher/smtp/ca.crt
```
- 需準備 CA 憑證、還有 SMTP Server 的憑證和私鑰
#### 3.2. 建立 Rancher Monitoring
1. 點選 Cluster Tools -> 找到 Monitoring 點選 Install

2. 勾選 Customize Helm options brfore install -> Next

3. 展開 Additional Secrets 選單,選擇 smtp-tls-secret

4. Install

5. 安裝成功畫面

#### 3.2. 設定 Alert-manager 告警對象為 E-mail
1. 點選左側選單 Storage -> Secrets -> 選擇 "cattle-monitoring-system" Namespace -> 找到 `alertmanager-rancher-monitoring-alertmanager` 這個 Secret -> 點選 Edit Config

2. 複製並修改以下 alertmanager.yaml 的內容,並再刪除所有原始的值後,貼到對應的 Value 欄位中
```yaml=
global:
resolve_timeout: 5m
route:
group_by: [Alertname]
# Send all notifications to me.
receiver: Mail Alert
group_wait: 30s
group_interval: 5m
repeat_interval: 12h
routes:
- match:
alertname: DemoAlertName
receiver: 'Mail Alert'
receivers:
- name: Mail Alert
email_configs:
- to: <你的 E-mail Address>
from: rancher@lab.com
smarthost: smtp.example.com:587 # Your smtp server address
tls_config:
ca_file: /etc/alertmanager/secrets/smtp-tls-secret/ca.crt
cert_file: /etc/alertmanager/secrets/smtp-tls-secret/tls.crt
key_file: /etc/alertmanager/secrets/smtp-tls-secret/tls.key
headers:
From: rancher@lab.com
Subject: 'Demo ALERT'
```

3. 確認設定檔是否修改成功,點選 Monitoring -> Alert Manager

4. 點選 Status

5. 檢視 Config 內容

6. 打開信箱,看 Alert

> 如果沒有 Alert 的話,可以透過 curl api 發送一個測試的 Alert
> ```!
> $ curl -H 'Content-Type: application/json' -d '[{"labels":{"alertname":"myalert"}}]' http://10.43.130.225:9093/api/v1/alerts
> ```
> `10.43.130.225` 為 Alertmanager Service 的 IP,執行以下命令可以找到
> `$ kubectl -n cattle-monitoring-system get svc -l app=rancher-monitoring-alertmanager`