# 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:///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) 제공