๋ผ์ฆ๋ฒ ๋ฆฌํ์ด SSD๋ ๋ฌดํํ์ง ์์ต๋๋ค. AI ํ๋๋ค์ด ๋งค์ด ๋ฐ์ดํฐ๋ฅผ InfluxDB์ ์์ผ๋ฉด ์ธ์ ๊ฐ๋ ์คํ ๋ฆฌ์ง๊ฐ ๊ฝ ์ฐน๋๋ค. ๊ทธ๋์ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก Windows PC์ NFS Cold Storage๋ก ์ฎ๊ธฐ๋ ํฐ์ด๋ง ํ์ดํ๋ผ์ธ์ ๊ตฌํํ๊ธฐ๋ก ํ์ต๋๋ค. ๊ฐ๋จํ ๊ฒ ๊ฐ์๋๋ฐ, K3s CronJob์ด ํด๋ฌ์คํฐ๋ฅผ ๋ง๋น์ํค๊ณ , NFS๊ฐ ์ ๋ น ์ฐ๊ฒฐ์ ๋ง๋ค๊ณ , Python ํ๋ก์ธ์ค๊ฐ ์ปค๋์ ๊ฐํ๋ฒ๋ฆฌ๋ ์ผ๋ค์ด ๊ธฐ๋ค๋ฆฌ๊ณ ์์์ต๋๋ค.
๐ ๋ฐ์ดํฐ ํฐ์ด๋ง ์ค์ฆ: GitHub Wiki โ Proof Tiering | ๋ฐ์ดํฐ ์๋ช ์ฃผ๊ธฐ
๐ ์ ์ฒด ์ค๊ณ โ Windowing ์ ๋ต
์ InfluxDB ๋ฐ์ดํฐ๋ฅผ ์ฃผ๊ธฐ์ ์ผ๋ก ๋น์์ผ ํ๋์ง๋ถํฐ ์ค๋ช ํ๋ฉด, Longhorn ๋ณผ๋ฅจ์ 5Gi๋ก ์ ํ๋ฉ๋๋ค. AI ํ๋๊ฐ ๊ณ์ ๋ฐ์ดํฐ๋ฅผ ์์ผ๋ฉด ์คํ ๋ฆฌ์ง๊ฐ ๊ฐ๋ ์ฐจ ์์คํ ์ด ๋ฉ์ถฅ๋๋ค.
โโโโโ 5์๊ฐ InfluxDB ๋ณด์กด (Hot) โโโโโ | 5์๊ฐ ์ด๊ณผ โ CSV ๋ณํ + Cold ์ด๊ด
Hot Data Cold Data
InfluxDB ์์ฃผ CSV ๋ณํ ํ
Grafana ์ค์๊ฐ ์๊ฐํ โ
NFS Cold Storage ์๊ตฌ ๋ณด์กด โ
5์๊ฐ ์ด๋ด ๋ฐ์ดํฐ๋ InfluxDB์์ ์ค์๊ฐ ์๊ฐํํ๊ณ , 5์๊ฐ์ด ์ง๋ ๋ฐ์ดํฐ๋ CSV๋ก ๋ณํํด Windows PC์ NFS๋ก ์ด๊ด ํ ์ญ์ ํฉ๋๋ค. ์ด ๊ตฌ์กฐ๊ฐ RPO 0์ด๋ฅผ ๋ฌ์ฑํ๋ ํต์ฌ ๋ฉ์ปค๋์ฆ์ ๋๋ค.
๐ฅ Episode 14. K3s CronJob์ด CPU๋ฅผ ํญ์ฃผ์์ผฐ๋ค
์ฒ์์ ์ฟ ๋ฒ๋คํฐ์ค์ค๋ฌ์ด ๋ฐฉ์์ผ๋ก ๊ตฌํํ์ต๋๋ค. K3s kind: CronJob์ผ๋ก ๋งค์๊ฐ InfluxDB ๋ฐ์ดํฐ๋ฅผ CSV๋ก ๋ณํํ๋ ํ๋๋ฅผ ์คํํ๋ ๋ฐฉ์์ด์์ต๋๋ค.
๊ทธ๋ฐ๋ฐ Grafana ์ธํ๋ผ ๋์๋ณด๋์์ ์ด์ํ ๊ฑธ ๋ดค์ต๋๋ค.
Master ๋
ธ๋ Sys Load: 652% โ 1291%
ํ๋ ๋ชฉ๋ก์ ํ์ธํ๋ ์ด๋ฐ ์ํ๋ค์ด ์์ฌ ์์ต๋๋ค.
NAME STATUS
data-tiering-cronjob-29545176-g725b CreateContainerError
data-tiering-cronjob-29545178-dszqq ContainerCreating
data-tiering-cronjob-29545180-v64cr CreateContainerError
์๋ฌ 3์ฐ์:
Error: context deadline exceeded
Error: failed to reserve container name "tiering-worker_..._0":
name "..." is reserved for "3bb74dbc5b6782c..."
Error: stream terminated by RST_STREAM with error code: CANCEL
์ฒ์์ ์คํฌ๋ฆฝํธ ๋ก์ง ๋ฌธ์ ๋ผ๊ณ ์๊ฐํ์ต๋๋ค. ๊ทธ๋ฐ๋ฐ crictl ps -a๋ก ์ปจํ
์ด๋๋ฅผ ํ์ธํ๋ ค ํด๋ ์กฐํ ์์ฒด๊ฐ ๋์ง ์์ต๋๋ค. ์ ๋ น ๋ ์ฝ๋์
๋๋ค.
๊ทผ๋ณธ ์์ธ: CronJob์ ๋ณผ๋ฅจ์ด hostPath: /mnt/safe-edge-nfs๋ก ์ค์ ๋์ด ์์๋๋ฐ, ์ด ๊ฒฝ๋ก๊ฐ Windows NFS ์๋ฒ(WinNFSd)๋ฅผ ๋ง์ดํธํ ๊ฒฝ๋ก์์ต๋๋ค. containerd๊ฐ ์ปจํ
์ด๋๋ฅผ ์์ฑํ ๋ ๋ณผ๋ฅจ ๋ง์ดํธ๋ฅผ ์๋ํ๋ ์๊ฐ, NFS ์๋ต์ด ๋๋ฆฌ๋ฉด context deadline exceeded ํ์์์์ด ๋ฐ์ํฉ๋๋ค.
ํ์์์์ผ๋ก ์ปจํ ์ด๋ ์์ฑ์ ์คํจํ์ง๋ง containerd ๋ด๋ถ DB์ ์ปจํ ์ด๋ ์ด๋ฆ ์์ฝ ๋ ์ฝ๋๊ฐ ๋จ์๋ฒ๋ฆฝ๋๋ค. ์ดํ ์ฌ์๋ํ ๋ ์ด๋ฆ ์ถฉ๋ โ ๋ฌดํ ๋ฐ๋ณต โ CPU ํญ์ฃผ์ ์ฐ์๊ฐ ๋ฐ์ํ ๊ฒ์ ๋๋ค.
[ํ์์์ ๋ฐ์]
โโ ์ปจํ
์ด๋ ์์ฑ ์คํจ
โโ containerd DB์ ์ ๋ น ๋ ์ฝ๋ ์์กด
โโ ์ฌ์๋ ์ ์ด๋ฆ ์ถฉ๋ ๋ฐ๋ณต
โโ CPU 1291% ํญ์ฃผ ๐ด
10๊ฐ์ง ์๋๋ฅผ ๊ฑฐ์ณ ๋ด๋ฆฐ ๊ฒฐ๋ก : CronJob์ ์์ ํ ํฌ๊ธฐํ๊ณ ๋ฆฌ๋ ์ค crontab์ผ๋ก ์ ํํฉ๋๋ค.
[๊ธฐ์กด] K3s CronJob โ ๋งค๋ฒ ์ปจํ
์ด๋ ์์ฑ โ NFS ๋ง์ดํธ ํ์์์ ์ํ
[๋ณ๊ฒฝ] ๋ฆฌ๋
์ค crontab โ ์ด๋ฏธ ๋ ์๋ host์์ Python ์ง์ ์คํ โ ์ปจํ
์ด๋ ์์ฑ ์์
# root ํฌ๋ก ํญ์ ๋ฑ๋ก (๋งค์ ์ ๊ฐ ์คํ)
sudo crontab -e
0 * * * * /home/minsoo/safe-edge-tiering/run_tiering.sh >> /home/minsoo/safe-edge-tiering/tiering.log 2>&1
๐ก ๊ตํ: ์ฟ ๋ฒ๋คํฐ์ค์์ ์ฃผ๊ธฐ์ ์์ ์ ์ ์์ CronJob์ด์ง๋ง, ๋ผ์ฆ๋ฒ ๋ฆฌํ์ด์ฒ๋ผ ๋ฆฌ์์ค๊ฐ ์ ํ์ ์ธ ์ฃ์ง ํ๊ฒฝ์์๋ ๋งค๋ฒ ์ปจํ ์ด๋๋ฅผ ์์ฑํ๋ ์ค๋ฒํค๋๊ฐ ์น๋ช ์ ์ ๋๋ค. ํด๋ผ์ฐ๋ ๋ค์ดํฐ๋ธ ์ ์๋ณด๋ค ํ๊ฒฝ์ ์ ์ฝ์ ๋จผ์ ๊ณ ๋ คํด์ผ ํฉ๋๋ค.
๐ฅ Episode 15. NFS STALE โ ์ฐ๊ฒฐ์ด ์ด์์๋ ์ฒํ๋ ์ ๋ น ๋ง์ดํธ
์ฌ๋ถํ
ํ tiering ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋๋ ๋ฐ์ดํฐ๊ฐ Windows PC๋ก ๊ฐ์ง ์์ต๋๋ค. ๋ฆฌ๋
์ค์์๋ ํ์ผ์ด ์๋ ๊ฒ์ฒ๋ผ ๋ณด์ด๋๋ฐ ์ค์ Windows C:\safe-edge-nfs ํด๋๋ ๋น์ด ์์ต๋๋ค.
minsoo@master:/mnt/safe-edge-nfs $ ls
acoustic_detection_cold_20260305_110742.csv # ํ์ผ์ด ์๋ ๊ฒ์ฒ๋ผ ๋ณด์
minsoo@master:/mnt/safe-edge-nfs $ touch tt.txt
touch: cannot touch 'tt.txt': Permission denied # ์ค์ ๋ก๋ ๋๊ธด ์ํ
WinNFSd ๋ก๊ทธ์๋ STALE ์๋ฌ๊ฐ ๋ฐ๋ณต๋ฉ๋๋ค.
STALE์ด๋: ๋ฆฌ๋ ์ค๊ฐ ์์ ์ ์ฐ๊ฒฐํ๋ NFS File Handle์ด ์ด์์๋ค๊ณ ์ฐฉ๊ฐํ์ง๋ง, ์ค์ ๋ก๋ Windows์์ ์ฐ๊ฒฐ์ด ๋๊ธด ์ํ์ ๋๋ค. WinNFSd๋ ์ฌ์์ ํ ๊ธฐ์กด ์ฐ๊ฒฐ ์ํ๋ฅผ ๋ณต๊ตฌํ๋ Grace Period๋ฅผ ์ง์ํ์ง ์์์, ์ฌ๋ถํ ํ ๋๋ง๋ค ๋ชจ๋ ์ฐ๊ฒฐ์ด STALE์ด ๋ฉ๋๋ค.
์ฆ์ ๋ณต๊ตฌ:
# ์ ๋ น ๋ง์ดํธ ๊ฐ์ ํด์ (-l: lazy unmount, ์๋ต ์์ด๋ ๊ฐ์ ํด์ )
sudo umount -l /mnt/edge-nfs/nfs-complete
# ์๋ก ๋ง์ดํธ
sudo mount -t nfs -o vers=3,nolock \
10.10.10.100:/C/safe-edge-nfs /mnt/edge-nfs/nfs-complete
๊ทผ๋ณธ ํด๊ฒฐ โ run_tiering.sh์ ์๋ ์ฌ์ฐ๊ฒฐ ๋ก์ง ๋ด์ฅ:
#!/bin/bash
# ๋งค ์คํ๋ง๋ค ๊ธฐ์กด ๋ง์ดํธ ๊ฐ์ ํด์ ํ ์๋ก ์ฐ๊ฒฐ
sudo umount -l /mnt/edge-nfs/nfs-complete 2>/dev/null
sudo timeout 5 mount -t nfs -o vers=3,nolock \
10.10.10.100:/C/safe-edge-nfs /mnt/edge-nfs/nfs-complete
NFS_STATUS=$?
๐ก ๊ตํ:
umount -l์ STALE ๋ง์ดํธ์ ๋ง๋ฅ ํด๊ฒฐ์ฌ์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ “์คํฌ๋ฆฝํธ ์คํ ์ ํญ์ ๋ง์ดํธ๋ฅผ ๊ฐฑ์ ”ํ๋ ๋ฐฉ์ด ๋ก์ง์ด ์ด์ ์๋ํ์ ํต์ฌ์ ๋๋ค.
๐ฅ Episode 16. stat์ NFS ๋๊น์ ๊ฐ์ง ๋ชปํ๋ค โ ์ปค๋ ๋ ๋ฒจ ๋ธ๋กํน
NFS๊ฐ ๋๊ฒผ๋์ง Python ์ฝ๋์์ ๊ฒ์ฆํ๋ ํจ์๋ฅผ ๋ง๋ค์์ต๋๋ค.
# 1์ฐจ ์๋: stat์ผ๋ก ๊ฒ์ฆ
def check_nfs_alive(mount_path):
result = subprocess.run(['timeout', '3', 'stat', mount_path], ...)
return result.returncode == 0 # NFS ๋๊ฒจ๋ True ๋ฐํ โ ๋ฌธ์ !
NFS๊ฐ ๋๊ธด ์ํ์์๋ stat์ True๋ฅผ ๋ฐํํฉ๋๋ค. stat์ ์ค์ NFS ์๋ฒ์ I/O ์์ฒญ์ ๋ณด๋ด์ง ์๊ณ ๋ฆฌ๋
์ค ๋ก์ปฌ ์บ์๋ฅผ ์ฝ๊ธฐ ๋๋ฌธ์
๋๋ค.
touch๋ก ๋ฐ๊ฟ๋ดค๋๋ ์ด๋ฒ์ ์คํฌ๋ฆฝํธ๊ฐ ์์ ๋ฉ์ถฅ๋๋ค.
๐ NFS ๋ง์ดํธ ์ํ ๊ฒ์ฆ ์ค... โ ์ฌ๊ธฐ์ ์์ํ ๋ฉ์ถค
touch๋ ์ค์ ํ์ผ์ ์์ฑํ๋ฏ๋ก NFS ์๋ฒ์ I/O ์์ฒญ์ ๋ณด๋
๋๋ค. NFS๊ฐ ๊บผ์ง ์ํ์์๋ ์ปค๋์ด ์๋ต์ ๋ฌดํ ๋๊ธฐํ๋ **D-State(์ธ์ธํฐ๋ฝํฐ๋ธ ์ฌ๋ฆฝ)**์ ๋น ์ง๋๋ค. subprocess.run(timeout=3) ๊ฐ์ ์ ํ๋ฆฌ์ผ์ด์
๋ ๋ฒจ ํ์์์์ผ๋ก๋ ์ปค๋์ด ์ก๊ณ ์๋ ํ๋ก์ธ์ค๋ฅผ ์ค๋จ์ํฌ ์ ์์ต๋๋ค.
์ต์ข ํด๊ฒฐ: ๊ฒ์ฆ ์ฑ ์์ shell ์คํฌ๋ฆฝํธ ํ ๊ณณ์ ์ง์ค์ํค๊ณ , ํ๊ฒฝ๋ณ์๋ก ์ ๋ฌํฉ๋๋ค.
# run_tiering.sh
sudo timeout 5 mount -t nfs ... /mnt/edge-nfs/nfs-complete
NFS_STATUS=$?
# NFS ์ํ๋ฅผ ํ๊ฒฝ๋ณ์๋ก Python์ ์ ๋ฌ
NFS_CONNECTED=$NFS_STATUS python3 /home/minsoo/scripts/tiering_host.py
# tiering_host.py โ Python ๋ด๋ถ์์ NFS I/O ์์ ๊ธ์ง
nfs_connected = os.environ.get('NFS_CONNECTED', '1') == '0'
if nfs_connected:
move_buffer_to_nfs(NFS_READY, NFS_COMPLETE) # Forward
else:
print("NFS ๋จ์ โ nfs-ready ๋ฒํผ์ ๋ณด๊ด ์ค") # Store
| ์ํฉ | mount ๊ฒฐ๊ณผ | Python ํ๋จ | ๊ฒฐ๊ณผ |
|---|---|---|---|
| NFS ์ ์ | ์ฑ๊ณต (0) | nfs_connected=True | nfs-complete๋ก ์ ์ก โ |
| NFS ๋๊น | timeout (124) | nfs_connected=False | nfs-ready ๋ฒํผ์ ๋ณด๊ด โ |
๐ก ๊ตํ:
stat์ NFS ์ฐ๊ฒฐ ๊ฒ์ฆ ์๋จ์ด ์๋๋๋ค. NFS I/O๋ ์ปค๋ ๋ ๋ฒจ์์ ๋ธ๋กํน๋๋ฏ๋ก Python ํ์์์์ผ๋ก ๋ง์ ์ ์์ต๋๋ค. ๊ฒ์ฆ ์ฑ ์์ ํ ๊ณณ(shell)์์๋ง ์ง๊ฒ ํ๊ณ ๊ฒฐ๊ณผ๋ฅผ ํ๊ฒฝ๋ณ์๋ก ์ ๋ฌํ๋ ๊ฒ์ด ๊ฐ์ฅ ์์ ํฉ๋๋ค.
๐ฅ Episode 17. ์ฌ๋ถํ ํ KUBECONFIG ๊ถํ ์ด๊ธฐํ โ ์๋ฌ ์์ฅ
์ฌ๋ถํ ์ ๊น์ง ์ ์ ๋์ํ๋ ์ฌ์ง ๋ฐฑ์ ์คํฌ๋ฆฝํธ๊ฐ ์ฌ๋ถํ ์ดํ ์ด๋ฐ ๋ฉ์์ง๋ฅผ ๋ด๊ณ ์ฆ์ ์ข ๋ฃ๋ฉ๋๋ค.
โ ๏ธ ์คํ ์ค์ธ AI ํ๋๋ฅผ ์ฐพ์ ์ ์์ต๋๋ค
ํ๋๋ ์ค์ ๋ก ๋ฉ์ฉกํ ๋๊ณ ์๋๋ฐ “ํ๋ ์์”์ด๋ผ๊ณ ํฉ๋๋ค.
์์ธ: ์คํฌ๋ฆฝํธ๊ฐ kubectl ๋ช
๋ น์ด๋ฅผ ์คํํ๊ธฐ ์ํด ์ด ๊ฒฝ๋ก๋ฅผ ์ฐธ์กฐํ๊ณ ์์์ต๋๋ค.
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
K3s๋ ๋ณด์ ์ ์ฑ
์ ์ฌ๋ถํ
ํ ๋๋ง๋ค ์ด ํ์ผ์ ๊ถํ์ 600(root ์ ์ฉ)์ผ๋ก ์ด๊ธฐํํฉ๋๋ค. ์ผ๋ฐ ์ฌ์ฉ์ ๊ณ์ (minsoo)์ผ๋ก ์คํฌ๋ฆฝํธ๋ฅผ ์คํํ๋ฉด Permission Denied๊ฐ ๋ฐ์ํ๊ณ , kubectl get pod๊ฐ ์๋ฌด ๊ฒฐ๊ณผ๋ ๋ฐํํ์ง ๋ชปํด “ํ๋ ์์”์ผ๋ก ํ๋จํ๋ ๊ฒ์ด์์ต๋๋ค.
ํด๊ฒฐ: ๊ฐ์ธ ์ ์ฉ kubeconfig ๊ฒฝ๋ก๋ก ๋ณ๊ฒฝํฉ๋๋ค.
# ๋ณ๊ฒฝ ์ (์ฌ๋ถํ
ํ root ์ ์ฉ์ผ๋ก ์ด๊ธฐํ๋จ)
export KUBECONFIG=/etc/rancher/k3s/k3s.yaml
# ๋ณ๊ฒฝ ํ (minsoo ๊ณ์ ์์ , ์ฌ๋ถํ
ํ์๋ ๊ถํ ์ ์ง)
export KUBECONFIG=/home/minsoo/.kube/config
๐ก ๊ตํ: “ํ๋ ์์” ๊ฐ์ ๋ก์ง ์๋ฌ ๋ฉ์์ง๊ฐ ์ค์ ๋ก๋ ๊ถํ ๋ฌธ์ ์ผ ์ ์์ต๋๋ค. ์ฌ๋ถํ ํ์๋ง ๋ฐ์ํ๋ ๋ฒ๊ทธ๋ ํ์ผ ๊ถํ, ํ๊ฒฝ๋ณ์, ์๋น์ค ๊ธฐ๋ ์์๋ฅผ ๋จผ์ ์์ฌํ์ธ์.
โ Store-and-Forward ํ์ดํ๋ผ์ธ ์์ฑ
๋ชจ๋ ํธ๋ฌ๋ธ์ํ ์ ๊ฑฐ์น ์ต์ข ๊ตฌ์กฐ์ ๋๋ค.
InfluxDB (Hot, Worker2)
โ run_tiering.sh โ ๋งค์ ์ ๊ฐ
โผ
nfs-ready (๋ก์ปฌ ๋ฒํผ)
โ
โโโ NFS ์ ์ โ nfs-complete (NFS ๋ง์ดํธ) โ Cold Storage โ
โโโ NFS ๋๊น โ ์ฌ๊ธฐ์ ๋๊ธฐ (Store)
โโโ NFS ๋ณต๊ตฌ ์ ์๋ ์ ์ก (Forward) โ
AI ํ๋ ์ค๋
์ท โ run_photo_tiering.sh (10๋ถ๋ง๋ค) โ Cold Storage/photos โ
NFS๊ฐ ๋๊ฒจ๋ ๋ก์ปฌ ๋ฒํผ์ ๋ฐ์ดํฐ๋ฅผ ๋ณด๊ดํ๊ณ , ๋ณต๊ตฌ๋๋ฉด ์๋์ผ๋ก ์ ์กํฉ๋๋ค. ์ฌ๊ณ ๊ฐ ๋์ ๋คํธ์ํฌ๊ฐ ๋๊ธฐ๋ ๋ฐ๋ก ๊ทธ ์๊ฐ์๋ ๋ฐ์ดํฐ๋ ๋ณด์กด๋ฉ๋๋ค.
๐ ๋ค์ ํธ: 6ํธ โ Failover ์ค์ฆ: ๋์ ์ ๋ฝ์๋ค, ์์คํ ์ ์ด์๋จ์๋ค
๐ ํฐ์ด๋ง ์ค์ฆ ์ ์ฒด: GitHub Wiki โ Proof Tiering