294 lines
9.4 KiB
Markdown
294 lines
9.4 KiB
Markdown
# rpi-master-node
|
|
작성: AI / 수정: nkey
|
|
|
|
k3s 클러스터에서 **매니페스트(데모/모니터링/AAM)** 를 적용하기 위한 master 노드 레포입니다.
|
|
|
|
- `k3s-manifests/`: 데모/서비스 매니페스트
|
|
- `k3s-monitoring/`: Prometheus/Alertmanager/Loki/Grafana (K8s 배포용)
|
|
- `kube-state-metrics/`: kube-state-metrics 배포
|
|
|
|
## Quickstart
|
|
### Recommended
|
|
```bash
|
|
# clone
|
|
git clone https://nkeystudy.site/gitea/2025-capstone/rpi-master-node.git
|
|
cd rpi-master-node
|
|
|
|
# (옵션) monitoring 네임스페이스가 없다면 생성
|
|
kubectl get ns monitoring >/dev/null 2>&1 || kubectl create ns monitoring
|
|
|
|
# kube-state-metrics
|
|
kubectl apply -f kube-state-metrics/kube-state-metrics.yaml
|
|
|
|
# monitoring stack (ConfigMap → Deploy 순서 권장)
|
|
kubectl apply -f k3s-monitoring/prometheus-config.yml
|
|
kubectl apply -f k3s-monitoring/alertmanager-config.yml
|
|
kubectl apply -f k3s-monitoring/loki-config.yml
|
|
kubectl apply -f k3s-monitoring/grafana-config.yml
|
|
|
|
kubectl apply -f k3s-monitoring/prometheus-deploy.yml
|
|
kubectl apply -f k3s-monitoring/alertmanager-deploy.yml
|
|
kubectl apply -f k3s-monitoring/loki-deploy.yml
|
|
kubectl apply -f k3s-monitoring/grafana-deploy.yml
|
|
|
|
# demo workloads
|
|
kubectl apply -f k3s-manifests/disk-fill-demo.yaml
|
|
kubectl apply -f k3s-manifests/aam-deploy.yaml
|
|
|
|
# verify
|
|
kubectl get svc -n monitoring
|
|
kubectl get svc -n alert-service
|
|
kubectl get svc -n aam
|
|
```
|
|
|
|
## Requirements
|
|
- Runtime/Language: Kubernetes(k3s) + `kubectl`
|
|
- Dependencies: (K8s) ConfigMap/Deployment/Service/Secret(RBAC 포함)
|
|
- Tools: `kubectl`
|
|
|
|
## Configuration
|
|
### Environment Variables
|
|
| Key | Description | Default | Required |
|
|
|---|---|---:|:---:|
|
|
| NODE_ENV | AAM 실행 환경 | `"production"` | |
|
|
| PORT | AAM 컨테이너 포트 | `"9000"` | |
|
|
| DRY_RUN | AAM 동작 플래그 | `"false"` | |
|
|
| USE_SUDO | AAM 동작 플래그 | `"true"` | |
|
|
| SSH_USER | AAM SSH 사용자 | `"pi"` | |
|
|
| SSH_KEY_PATH | AAM SSH 키 경로 | `"/app/.ssh/aam_key"` | |
|
|
| GF_SECURITY_ADMIN_USER | Grafana 관리자 계정 | `"admin"` | |
|
|
| GF_SECURITY_ADMIN_PASSWORD | Grafana 관리자 비밀번호 | `"admin1234"` | |
|
|
|
|
> 위 값들은 매니페스트에 하드코딩되어 있습니다.
|
|
> AAM은 `aam-ssh-key` Secret을 `/app/.ssh`로 마운트합니다.
|
|
|
|
### Ports
|
|
| Service | Port | Description |
|
|
|---|---:|---|
|
|
| prometheus (NodePort) | 30100 → 9090 | Prometheus UI |
|
|
| alertmanager (NodePort) | 30101 → 9093 | Alertmanager UI |
|
|
| loki (NodePort) | 30102 → 3100 | Loki API (promtail push 대상) |
|
|
| grafana (NodePort) | 30103 → 3000 | Grafana UI |
|
|
| disk-fill-demo (NodePort) | 30001 → 8000 | 디스크 채우기 데모 서비스 |
|
|
| aam-service (NodePort) | 30104 → 9000 | AAM 서비스 |
|
|
| kube-state-metrics (ClusterIP) | 8080 | kube-state-metrics metrics |
|
|
| Node-Exporter | 9100 | Prometheus scraping |
|
|
| Promtail | 9080 | Prometheus scraping |
|
|
|
|
## Usage (minimal)
|
|
- 디스크 채우기 데모 배포
|
|
```bash
|
|
kubectl apply -f k3s-manifests/disk-fill-demo.yaml
|
|
```
|
|
|
|
- 모니터링 스택 외부 접근(NodePort) 확인
|
|
```bash
|
|
kubectl get svc -n monitoring
|
|
```
|
|
|
|
- AAM 배포 및 서비스 확인
|
|
```bash
|
|
kubectl apply -f k3s-manifests/aam-deploy.yaml
|
|
kubectl get svc -n aam
|
|
```
|
|
|
|
## (All nodes) node-exporter 설치 (수동)
|
|
> 이 레포에는 node-exporter 설치 스크립트/systemd 유닛이 포함되어 있지 않습니다.
|
|
> Prometheus는 `k3s-monitoring/prometheus-config.yml`의 `job_name: node-exporter` 타겟(포트 **9100**)으로 스크레이프합니다.
|
|
|
|
### 1) 바이너리 다운로드 및 설치 (ARM64)
|
|
```bash
|
|
cd /tmp
|
|
|
|
# node_exporter 다운로드 (ARM64용)
|
|
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-arm64.tar.gz
|
|
|
|
# 압축 해제
|
|
tar xvf node_exporter-1.8.2.linux-arm64.tar.gz
|
|
|
|
# 실행 파일을 표준 경로로 이동
|
|
sudo mv node_exporter-1.8.2.linux-arm64/node_exporter /usr/local/bin/
|
|
|
|
# 설치 폴더 정리(선택)
|
|
rm -rf node_exporter-1.8.2.linux-arm64*
|
|
```
|
|
|
|
### 2) 전용 사용자 생성
|
|
```bash
|
|
sudo useradd --no-create-home --system node_exporter
|
|
sudo chown node_exporter:node_exporter /usr/local/bin/node_exporter
|
|
```
|
|
|
|
### 3) systemd 서비스 생성
|
|
```bash
|
|
sudo nano /etc/systemd/system/node_exporter.service
|
|
```
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Prometheus Node Exporter
|
|
Wants=network-online.target
|
|
After=network-online.target
|
|
|
|
[Service]
|
|
User=node_exporter
|
|
Group=node_exporter
|
|
Type=simple
|
|
ExecStart=/usr/local/bin/node_exporter \
|
|
--web.listen-address=":9100" \
|
|
--collector.filesystem.ignored-mount-points="^/(sys|proc|dev|run)($|/)" \
|
|
--collector.filesystem.ignored-fs-types="^(sysfs|proc|autofs|devpts|tmpfs|devtmpfs|rpc_pipefs|overlay|squashfs)$"
|
|
|
|
Restart=on-failure
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### 4) 서비스 등록 및 실행
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now node_exporter
|
|
|
|
sudo systemctl status node_exporter
|
|
curl http://localhost:9100/metrics | head
|
|
```
|
|
|
|
## (All nodes) promtail 설치 (수동)
|
|
> 이 레포의 Loki(K8s)는 `k3s-monitoring/loki-deploy.yml`에서 NodePort **30102**로 열려 있습니다.
|
|
> 각 노드의 promtail은 해당 Loki로 로그를 push 합니다.
|
|
|
|
### 1) 다운로드 및 설치 (ARM64)
|
|
```bash
|
|
cd /tmp
|
|
PROMTAIL_VERSION="2.9.6"
|
|
|
|
wget https://github.com/grafana/loki/releases/download/v${PROMTAIL_VERSION}/promtail-linux-arm64.zip
|
|
unzip promtail-linux-arm64.zip
|
|
|
|
sudo mv promtail-linux-arm64 /usr/local/bin/promtail
|
|
sudo chmod 755 /usr/local/bin/promtail
|
|
```
|
|
|
|
> promtail 실행 전용 계정(`promtail`)이 필요합니다(계정 생성은 운영 정책에 맞게 진행).
|
|
|
|
### 2) 디렉터리 생성
|
|
```bash
|
|
sudo mkdir -p /etc/promtail
|
|
sudo mkdir -p /var/lib/promtail
|
|
|
|
# (전용 계정 사용 시) 권한 부여
|
|
sudo chown -R promtail:promtail /var/lib/promtail
|
|
sudo chown -R promtail:promtail /etc/promtail
|
|
```
|
|
|
|
### 3) promtail 설정
|
|
```bash
|
|
sudo nano /etc/promtail/config.yml
|
|
```
|
|
|
|
```yaml
|
|
server:
|
|
http_listen_port: 9080
|
|
grpc_listen_port: 0
|
|
|
|
positions:
|
|
filename: /var/lib/promtail/positions.yaml
|
|
|
|
clients:
|
|
# Loki(NodePort 30102)로 push
|
|
- url: http://100.104.27.47:30102/loki/api/v1/push
|
|
|
|
scrape_configs:
|
|
- job_name: varlogs
|
|
static_configs:
|
|
- targets: [localhost]
|
|
labels:
|
|
job: varlogs
|
|
host: <노드 이름>
|
|
__path__: /var/log/*log
|
|
```
|
|
|
|
### 4) systemd 서비스 등록
|
|
```bash
|
|
sudo nano /etc/systemd/system/promtail.service
|
|
```
|
|
|
|
```ini
|
|
[Unit]
|
|
Description=Promtail service
|
|
After=network.target
|
|
|
|
[Service]
|
|
User=promtail
|
|
Group=promtail
|
|
Type=simple
|
|
ExecStart=/usr/local/bin/promtail -config.file=/etc/promtail/config.yml
|
|
Restart=on-failure
|
|
|
|
[Install]
|
|
WantedBy=multi-user.target
|
|
```
|
|
|
|
### 5) 실행/검증
|
|
```bash
|
|
sudo systemctl daemon-reload
|
|
sudo systemctl enable --now promtail
|
|
|
|
sudo systemctl status promtail
|
|
sudo systemctl restart promtail
|
|
```
|
|
|
|
## 설정 파일 설명 (이 레포에 포함된 것만)
|
|
### 데모/서비스 매니페스트 (`k3s-manifests/*`)
|
|
- `k3s-manifests/disk-fill-demo.yaml`
|
|
- `alert-service` 네임스페이스 생성
|
|
- `disk-fill-demo` Deployment + NodePort Service(30001→8000)
|
|
- `nodeSelector: demo-service="true"` 로 **서비스 워커 노드에 스케줄링**되도록 설계
|
|
- `k3s-manifests/aam-deploy.yaml`
|
|
- `aam` 네임스페이스 생성
|
|
- `aam-deployment`(image: `sadew1112/aam:0.1.0`) + NodePort Service(30104→9000)
|
|
- `nodeName: rpi-worker-monitor`로 모니터 워커 노드에 고정
|
|
- `aam-ssh-key` Secret을 `/app/.ssh`로 마운트(읽기 전용, `0400`)
|
|
|
|
### 모니터링 스택 (`k3s-monitoring/*`)
|
|
- `k3s-monitoring/prometheus-config.yml`
|
|
- Prometheus 스크레이프 타겟 정의:
|
|
- `prometheus:9090`
|
|
- `node-exporter`: `100.104.27.47:9100`, `100.77.135.86:9100`, `100.90.177.14:9100`
|
|
- `kube-state-metrics`: `kube-state-metrics.kube-system.svc.cluster.local:8080`
|
|
- Alertmanager 타겟: `alertmanager:9093`
|
|
- 알람 룰 포함(NodeDown/HighCpu/HighMemory/DiskAlmostFull 등)
|
|
- 주의: `DiskAlmostFull`의 expr는 빠른 실험을 위해 `> 0.4`로 설정되어 있어(기본은 85%로 설정) **현재는 40% 사용률 초과에서 알람**이 발생합니다.
|
|
- `k3s-monitoring/prometheus-deploy.yml`
|
|
- Prometheus Deployment + NodePort Service(30100→9090)
|
|
- `nodeName: rpi-worker-monitor`로 고정
|
|
- TSDB 저장소는 `emptyDir`(테스트/데모용)
|
|
- `k3s-monitoring/alertmanager-config.yml`
|
|
- `severity="critical"` 알람을 `n8n-webhook` 리시버로 라우팅
|
|
- Webhook URL: `http://<IP>/n8n/webhook/alert` (`send_resolved: true`)
|
|
- `k3s-monitoring/alertmanager-deploy.yml`
|
|
- Alertmanager Deployment + NodePort Service(30101→9093)
|
|
- `nodeName: rpi-worker-monitor`로 고정
|
|
- `k3s-monitoring/loki-config.yml`
|
|
- Loki 단일 인스턴스 설정(filesystem 기반 저장: `/loki/chunks`, `/loki/index` 등)
|
|
- `auth_enabled: false`(내부 데모 용도)
|
|
- `k3s-monitoring/loki-deploy.yml`
|
|
- Loki Deployment + NodePort Service(30102→3100)
|
|
- 주석대로 **promtail 접근용 NodePort**
|
|
- `nodeName: rpi-worker-monitor`로 고정
|
|
- `k3s-monitoring/grafana-config.yml`
|
|
- Grafana datasource provisioning
|
|
- Prometheus/Loki를 각각 Cluster DNS로 연결
|
|
- `k3s-monitoring/grafana-deploy.yml`
|
|
- Grafana Deployment + NodePort Service(30103→3000)
|
|
- 관리자 계정/비번 임시 설정(`admin` / `admin1234`)
|
|
- 저장소는 `emptyDir`(데모용)
|
|
- `nodeName: rpi-worker-monitor`로 고정
|
|
|
|
### kube-state-metrics (`kube-state-metrics/*`)
|
|
- `kube-state-metrics/kube-state-metrics.yaml`
|
|
- ServiceAccount + ClusterRole/Binding(RBAC)
|
|
- Deployment(image: `registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.0`, port 8080)
|
|
- ClusterIP Service(8080) 제공
|