1. 막힌 자리번외 — 노드 메모리와 쿠버네티스 메모리를 진행할 때는 노드 한 대를 밖에서 봤다. 메모리 숫자를 내는 자리를 층으로 갈랐다.리눅스 층 — 커널이 센다. /proc/meminfo의 MemTotal·MemAvailable, 지표로는 node-exporter의 node_memory_*. 도로 가져갈 수 있는 것(페이지 캐시)과 없는 것(익명 메모리)으로 갈린다cgroup 층 — 커널이 센다. cgroup 파일의 memory.current·memory.stat, 지표로는 cAdvisor의 container_memory_working_set_bytes. 프로세스 묶음별로 세고, 그 묶음에 상한을 건다쿠버네티스 층 — kubelet이 계산해 적는다. memory.max는 cgroup 파일에 쓰고 a..
1. 막힌 자리11부에서 앱이 제대로 도는지 검증했고, 12부에서는 대시보드를 보면서 파드 스펙을 실측한다. queue와 booking에 메모리와 CPU를 얼마나 줘야 하는지를 부하로 재서 정하는 것이 목표다. 그런데 앱 쪽을 재기 전에 앞이 막혔다. 노트북 한 대에 노드 3대를 올린 클러스터라 자원이 정해져 있다. 지금 파드들에 걸린 requests와 limits가 그 안에서 어떻게 나뉘어 있는지를 모르는 상태였다. 그것을 모른 채 부하를 걸면 앱이 느린 것인지 자리가 없는 것인지 갈리지 않는다. 그래서 12부의 순서가 인프라 대시보드 → 앱 대시보드가 됐다. 이 글은 그중 앞쪽, 인프라 대시보드에서 노드 메모리를 분석하다 막힌 것을 정리한 기록이다.노드 한 대가 이렇게 나뉘어 있다k3s 노드는 3대이..
1. 막힌 자리11부에서 data 네임스페이스의 파드(MySQL·Redis·Kafka)에 NetworkPolicy 를 설계하는 중이다. 방식은 하나다. 일단 전부 막고, 들어와야 하는 것만 다시 연다. 그래서 대상마다 같은 질문에 답하게 된다 — 이 포트에 누가 붙어야 하나. MySQL 3306 은 booking 하나였다. Redis 6379·26379 는 queue 와 booking 이었다. Kafka 9092 에서 답이 나오지 않았다. 브로커가 3대인 것도, 토픽이 5종인 것도, partitions: 4 와 min.insync.replicas: 2 가 무엇을 정하는 값인지도 조회해야 알 수 있었다. 그 설정은 AI 도움을 받아 쓴 것이고, 그때 읽고 넘어갔다고 생각했던 것들이다. 이 글은 그것을 조회..
시리즈 "노트북 홈서버 k3s 구축기" 11부.지난 편까지 = 코드를 머지하면 사람 손 없이 3-4분 뒤 파드가 새 이미지로 돈다. 다만 그 파드 안의 앱을 브라우저에서 끝까지 태워본 적이 없다.11부 = 앱. 어떻게 흐르는지 확인하고(E2E), 남에게 보여줄 시뮬레이터로 다시 만들고, 확인된 동작을 테스트 게이트로 남기고, LAN에 열기 전에 권한·통신을 조인다. 끝에서 이 앱이 돌아가는 판(가상 설정들)을 정리해 부하 실측으로 넘긴다.0. 이어받기이 시리즈는 노트북 한 대에서 시작했다. 1-5부가 물리 기반이고, 클러스터 인프라는 6부부터 쌓였다.편세운 것남긴 상태1-5Proxmox + VM 3대(k3s-1·2·3) + 네트워크·용도별 디스크노드 셋이 클러스터를 받을 준비6k3s 3노드(embedde..
시리즈 "노트북 홈서버 k3s 구축기" 10부.지난 편까지 = GitOps 원본이 데스크탑 GitLab이고, push하면 3초 만에 클러스터에 반영된다. 다만 배포되는 것은 인프라뿐이고 앱 세 종은 이미지가 없어 뜨지 않는다.10부 = CI와 CD. 앞 토막(CI)은 push 한 번으로 검증된 이미지가 레지스트리에 서게 하고, 뒤 토막(CD)은 그 이미지가 노드에서 돌게 하고 무엇이 도는지 git이 적고 있게 한다.0. 이어받기9부에서 GitOps 원본을 데스크탑 GitLab으로 옮겼다. cgv-infra에 push하면 webhook을 타고 3초 만에 클러스터에 반영된다. 그 길로 흐르는 것은 인프라뿐이다. 앱 세 종(queue·booking·frontend)은 Deployment·Service·Ingr..
10부 CI는 완성본만 설명 했다. 이 글은 순서를 뒤집는다.최종본 해부 — stage마다, job마다 무엇이고 왜 그 자리에 있는지여정 — job 실타래마다, 뭐에 막혔고 무슨 작업으로 풀었는지판정 — 그래서 이게 맞는 CI인지최종본 — 지금 무엇이 돌고 있나push 한 번에 이렇게 흐른다.push ─→ check ─→ test ─→ build ─→ scan ─→ publish 4 job (빈칸) 3 job 3 job 3 job (dev 에서만) stage는 벽이다. 한 칸에서 실패가 하나라도 나오면 다음 칸은 실행되지 않는다.job은 "명령 목록 + 그걸 돌릴 이미지"다. 러너가 컨테이너를 띄워 돌리고, 끝나면 버린다. 그래서 모든 job은 두 질문으로 읽힌다 — 무엇..
9부에서 GitLab을 데스크탑에 세우고 작업하는 동안 하루에 몇 번씩 가까이 뭔가가 죽었다.GitLab이 내려가고, Chrome 탭이 비워지고, VS Code가 다시 뜨고, Docker Desktop이 아예 시작을 못 했다.작업 관리자를 열면 메모리가 80퍼센트를 넘어 있었다. 물리 램이 모자란다고 판단하고DDR3 4GB 네 장 중 두 장을 8GB로 바꿀 주문을 넣었다.그런데 원인은 램이 아니었다. 이 글은 그 판단이 왜 틀렸는지, 무엇이 진짜 원인이었는지,어떻게 찾아서 고쳤는지를 순서대로 적은 것이다.원인을 가리려면 무엇이 무엇 위에 있는지부터 알아야 했다. WSL2·배포판·컨테이너·Vmmem이각각 무엇이고 어느 층에 있는지를 갈라 놓고 시작한다.0. 무엇이 안 잡혔나말로 못 하던 것들이 이랬다.Do..
0. 이어받기8부 끝에서 관측 파이프라인은 흐른다. 같은 k3s 프로세스를 kubelet·apiserver 두 job으로 겹쳐 긁던 시리즈 사본을 걷어 거절이 0이 됐고, 파이프라인 자신을 보는 계기판도 Mimir 3축 12패널로 섰다. 계기판은 git에 push하면 ArgoCD가 가져가 Grafana에 앉힌다 — 커밋이 곧 배포다. 1–5부에서 호스트와 노드, 6부에서 클러스터, 7부에서 플랫폼과 GitOps 인계, 8부에서 관측까지 섰다. 남은 길은 앱을 향한다 — 10부 이미지, 11부 앱 배포, 12부 앱 관측, 13부 부하와 스펙 산정, 14부 외부 공개. 지금 비어 있는 자리는 넷이다.push마다 최대 3분을 기다린다. ArgoCD가 GitHub를 주기적으로 다시 읽는 방식이라, 8부에서 계기..
0. 이어받기7부 끝에서 토대와 워크로드가 다 섰다. 노드 세 대가 Ready, 파드 69개, 데이터 디스크 열 장이 전부 Bound. 플랫폼(Calico·MetalLB·Traefik·cert-manager·sealed-secrets·ArgoCD)과 데이터 계층(MySQL·Redis·Kafka), 관측 스택(Mimir·Loki·Tempo·Grafana·Alloy·MinIO)이 올라왔고, 손을 떼고 GitOps에 넘겼다.두 자리가 비어 있다.앱은 아직. queue·booking·frontend의 Deployment·Service는 클러스터에 있는데, 이미지를 받아올 레지스트리가 없어 ImagePullBackOff다. 파드 69개 중 4개가 그 상태고, 레지스트리는 10부에서 세운다.Grafana 안이 백지..
0. 먼저 — 내 네트워크 골목의 구조 홈랩을 진행하던 도중 장애가 발생했다. 데스크탑에서 서버로의 ssh, proxmox web, argocd web이 전부 다운되었다. 그래서 서버가 죽었나 싶어서 닫혀있던 노트북을 열고 root로 진입해보니 pve(내가 만든 proxmox 호스트 - .200)는 잘 살아있었고, pve에서 201,202,203으로도 접근이 잘 되었다. 근데 왜 데스크탑에서 연결이 갑자기 한순간에 다 끊어졌을까. 이 장애는 "안에서는 되는데 밖에서만 안 된다"는 모양이었다. 그래서 원인을 이해하려면, 3부에서 세운 네트워크 구조를 먼저 알아야 한다. 3부에서 깐 배선을 한 장으로 요약하면: 공유기 (TP-Link, 192.168.0.1) ..