0. 지금까지 세운 것, 그리고 이 편이 여는 것앞 두 편은 닫는 작업이었다. 클러스터를 이루는 VM 세 대를 집 사설망에서 떼어 격리망으로 옮기고(13-1), 그 안의 통신과 권한을 실제 쓰는 범위로 줄였다(13-2). 이 편은 처음으로 여는 작업이고, 새로 내는 통로가 그 구조 어디에 붙는지가 설계의 전부다. 그래서 지금 무엇이 어떻게 닫혀 있는지부터 한 장으로 잡는다. 지금의 구성 인터넷 │ vpn.subinhong.dev → 집 공인 IP (DDNS 가 추적한다) ▼ 공유기 포트포워딩 1개 — 51820..
0. 앞 편에서 이어지는 자리앞 편에서 노드를 사설망에서 떼어 격리망(10.0.0.x)으로 옮겼다. 바깥으로 나가는 통로는 방화벽 VM 하나뿐이고, 관리 접근은 등록된 키를 가진 기기만 터널로 들어온다. 그것은 클러스터 바깥의 경계다. 다음 편에서 클러스터 내부의 대기열 웹 서비스를 https로 공개하면 443 은 열 수밖에 없고, 그 문으로 정상 방문자처럼 들어와 그 뒤의 앱을 치는 것은 이 경계가 막지 못한다. 파드 하나가 잡히는 순간부터는 클러스터 안에 통제가 하나도 없다.바깥 경계 — 앞 편에서 끝났다 인터넷 → 공유기 → 방화벽 VM → 격리망 │안쪽 경계 — 이 편 ▼ 파드 사이 통신 ..
13-2부에서 API 서버 권한을 좁히며, 그 판정이 실제로 어떻게 도는지를 이 클러스터 실물로 확인하며 정리한 기록이다. 본편은 조치만 다루고, 원리는 여기에 둔다.클러스터로의 모든 요청은 API 서버 하나로 간다클러스터의 상태 — 파드 목록, Deployment, Secret, NetworkPolicy — 는 etcd 에만 있다. 그리고 etcd 에 읽고 쓰는 것은 API 서버 하나뿐이다. 파드를 만들려면 etcd 에 그 기록이 들어가야 하고, 그것을 할 수 있는 주체가 API 서버밖에 없어서 사람이든 ArgoCD 든 kubelet 이든 전부 API 서버에 요청을 보낸다. kubectl 은 그 API 서버에 HTTP 요청을 보내는 클라이언트다. kubectl get pods -n app 에 -v=6(..
0. 여기까지 온 길, 그리고 이 편이 하는 것11부까지 — 서비스를 세우고, 그 상태를 볼 수단까지 붙였다.1-5부 노트북 한 대에 Proxmox · VM 세 대 · 노드 설정6-8부 디스크 · k3s 클러스터 · LGTM 관측 스택 (Loki·Grafana·Tempo·Mimir)9-11부 GitOps(ArgoCD) · CI/CD(GitLab) · 앱 배포와 대시보드 → 예매 서비스(queue·booking·frontend)가 클러스터에서 돌고, 지표·로그·트레이스가 한 화면에서 이어진다 12부 — 그 서비스에 부하를 걸어 배포 스펙을 실측으로 정했다. 판을 스물한 번 돌려 계수 열 개를 뽑았고(확정/초 = 정원 ÷ 체류 · booking 1코어 = 38건..
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은 두 질문으로 읽힌다 — 무엇..