<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>인프라 노트</title><description>쿠버네티스, AWS, 관측성. 인프라를 운영하면서 부딪힌 것들을 정리합니다.</description><link>https://hansteches.com</link><language>ko-kr</language><item><title>Istio 서비스 메시 6주 스터디 — 주차별 실습 기록</title><link>https://hansteches.com/posts/istio-service-mesh-6-week-study</link><guid isPermaLink="true">https://hansteches.com/posts/istio-service-mesh-6-week-study</guid><description>Istio를 실무에 도입하기 전에 6주 동안 스터디하며 로컬 클러스터에 직접 띄워 실습했습니다. KinD와 Bookinfo 예제로 트래픽 라우팅·복원력·mTLS·관찰성·컨트롤 플레인까지, 주차별로 확인한 것들을 정리합니다.</description><pubDate>Fri, 14 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>istio</category><category>service-mesh</category><category>kubernetes</category><category>study</category></item><item><title>Argo CD Degraded — progressDeadlineSeconds 만료</title><link>https://hansteches.com/posts/argocd-degraded-stale-progressdeadline</link><guid isPermaLink="true">https://hansteches.com/posts/argocd-degraded-stale-progressdeadline</guid><description>DESIRED=READY=AVAILABLE인데 콘솔은 ProgressDeadlineExceeded로 Degraded를 표시합니다. 과거에 한 번 타임아웃 난 기록이 안 지워져서 그렇습니다. 파드를 안 건드리고 상태만 재평가시킵니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>argocd</category><category>argo-rollouts</category><category>gitops</category></item><item><title>Docker COPY와 빌드 컨텍스트 — 디렉토리 중첩</title><link>https://hansteches.com/posts/docker-copy-build-context-nested-dir</link><guid isPermaLink="true">https://hansteches.com/posts/docker-copy-build-context-nested-dir</guid><description>빌드 컨텍스트 루트에서 COPY . 를 하니 소스 디렉토리가 한 겹 더 중첩됐습니다. WORKDIR에는 package.json이 없고, 한 겹 아래에 있었습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cicd</category><category>docker</category><category>dockerfile</category><category>jenkins</category><category>ci</category></item><item><title>EKS aws-node ipamd 행(hang) — 파드 ContainerCreating 멈춤</title><link>https://hansteches.com/posts/eks-aws-cni-ipamd-hang-node-replace</link><guid isPermaLink="true">https://hansteches.com/posts/eks-aws-cni-ipamd-hang-node-replace</guid><description>Karpenter가 띄운 새 노드에서 모든 파드가 IP를 못 받았습니다. aws-node는 2/2 Running인데 ipamd 프로세스가 초기화 직후 멈춰 있었습니다. 재시작도 안 먹어서 노드를 갈았습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>eks</category><category>aws-vpc-cni</category><category>karpenter</category><category>troubleshooting</category></item><item><title>Elastic APM Agent vs RUM Agent</title><link>https://hansteches.com/posts/elastic-apm-vs-rum-agent</link><guid isPermaLink="true">https://hansteches.com/posts/elastic-apm-vs-rum-agent</guid><description>APM Agent는 서버 사이드를, RUM Agent는 브라우저 사이드를 봅니다. 백엔드 응답은 빠른데 사용자는 느리다고 할 때, 그 간극이 RUM에만 보입니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>data</category><category>elastic-apm</category><category>rum</category><category>observability</category><category>web-vitals</category></item><item><title>FluxCD 무한 reconcile — ignoreDifferences</title><link>https://hansteches.com/posts/fluxcd-reconcile-loop-ignoredifferences</link><guid isPermaLink="true">https://hansteches.com/posts/fluxcd-reconcile-loop-ignoredifferences</guid><description>FluxCD는 Git 상태로 되돌리고 HPA는 부하에 맞춰 바꾸고, 둘이 같은 replicas 필드를 두고 계속 싸웁니다. ignoreDifferences로 그 필드만 FluxCD 관리에서 뺍니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cicd</category><category>fluxcd</category><category>gitops</category><category>hpa</category><category>kubernetes</category></item><item><title>FluxCD vs ArgoCD — 역할 분리</title><link>https://hansteches.com/posts/fluxcd-vs-argocd-role-split</link><guid isPermaLink="true">https://hansteches.com/posts/fluxcd-vs-argocd-role-split</guid><description>둘 다 GitOps 도구지만 하나는 UI가 아예 없고 하나는 UI가 전부라, 자동으로 반영돼야 하는 인프라는 FluxCD에 두고 사람이 보고 롤백하는 앱은 ArgoCD에 맡겨 층을 나눕니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cicd</category><category>fluxcd</category><category>argocd</category><category>gitops</category><category>kubernetes</category></item><item><title>Git 히스토리의 대용량 파일 제거 — filter-repo</title><link>https://hansteches.com/posts/git-large-file-history-filter-repo</link><guid isPermaLink="true">https://hansteches.com/posts/git-large-file-history-filter-repo</guid><description>2.3GB JSON을 커밋해버렸습니다. 이미 히스토리에 들어간 파일은 .gitignore로 안 지워집니다. 히스토리를 다시 써야 합니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>foundations</category><category>git</category><category>git-filter-repo</category><category>github</category></item><item><title>쿠버네티스 오토스케일링 계층 — HPA · KEDA · Karpenter</title><link>https://hansteches.com/posts/hpa-keda-karpenter-layers</link><guid isPermaLink="true">https://hansteches.com/posts/hpa-keda-karpenter-layers</guid><description>셋 다 스케일링인데 겹치는 게 아니라 층으로 동작합니다. KEDA가 Pod를 늘리라 하고, 자리가 없으면 Karpenter가 노드를 띄웁니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>hpa</category><category>keda</category><category>karpenter</category><category>autoscaling</category></item><item><title>EKS Pod에 IAM 권한 주기 — IRSA vs Pod Identity</title><link>https://hansteches.com/posts/irsa-vs-eks-pod-identity</link><guid isPermaLink="true">https://hansteches.com/posts/irsa-vs-eks-pod-identity</guid><description>둘 다 Pod마다 다른 IAM 권한을 주려는 겁니다. IRSA는 클러스터마다 OIDC를 세팅하고, Pod Identity는 그 과정을 없앴습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>eks</category><category>irsa</category><category>pod-identity</category><category>iam</category></item><item><title>EKS 노드 오토스케일링 — Karpenter vs Cluster Autoscaler</title><link>https://hansteches.com/posts/karpenter-vs-cluster-autoscaler</link><guid isPermaLink="true">https://hansteches.com/posts/karpenter-vs-cluster-autoscaler</guid><description>Cluster Autoscaler는 미리 만든 Node Group을 늘립니다. Karpenter는 Pod 요구사항을 보고 EC2를 그 자리에서 고릅니다. 이 차이가 비용과 속도로 이어집니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>karpenter</category><category>cluster-autoscaler</category><category>eks</category><category>autoscaling</category></item><item><title>Lambda@Edge IAM — 리전 제약</title><link>https://hansteches.com/posts/lambda-edge-iam-region-quirks</link><guid isPermaLink="true">https://hansteches.com/posts/lambda-edge-iam-region-quirks</guid><description>함수는 us-east-1에만 있는데 콘솔이 서울 리전으로도 조회를 던집니다. ListFunctions는 리소스 제한이 안 돼서 Resource &apos;*&apos;가 강제되고, 다 맞아도 안 되면 상위 제약을 봐야 합니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>lambda-edge</category><category>cloudfront</category><category>iam</category><category>aws</category></item><item><title>LiteLLM CPU 병목 — 단일 워커에 묶인 LLM 게이트웨이</title><link>https://hansteches.com/posts/litellm-cpu-capped-single-worker</link><guid isPermaLink="true">https://hansteches.com/posts/litellm-cpu-capped-single-worker</guid><description>VM에 띄운 LiteLLM이 4코어 서버에서 CPU가 한 코어(약 27.6%)에서 천장을 쳤습니다. LiteLLM은 FastAPI 앱이라 워커 하나가 1코어만 씁니다. VM에선 워커를 늘려 임시로 막고, 이후 EKS로 Helm 마이그레이션해 파드 수평 확장으로 정리했습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>ai</category><category>litellm</category><category>uvicorn</category><category>prometheus</category><category>performance</category></item><item><title>LLM 게이트웨이 패턴 — 프록시를 두는 이유</title><link>https://hansteches.com/posts/llm-gateway-pattern-why-proxy</link><guid isPermaLink="true">https://hansteches.com/posts/llm-gateway-pattern-why-proxy</guid><description>서비스마다 OpenAI·Bedrock을 직접 부르면 키가 흩어지고 비용을 못 추적하고 provider를 못 바꿉니다. 프록시 하나를 두면 이게 다 한 곳으로 모입니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>ai</category><category>llm</category><category>gateway</category><category>litellm</category><category>cost</category></item><item><title>nginx Ingress vs ALB Ingress — L7과 L4</title><link>https://hansteches.com/posts/nginx-ingress-vs-alb-ingress-l7-l4</link><guid isPermaLink="true">https://hansteches.com/posts/nginx-ingress-vs-alb-ingress-l7-l4</guid><description>nginx Ingress는 클러스터 안에서 라우팅하고, ALB Ingress는 클러스터 밖 AWS 인프라가 합니다. 그리고 Ingress 스펙 자체가 L7 전용이라 NLB(L4)는 Service로 노출합니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>networking</category><category>ingress</category><category>alb</category><category>nlb</category><category>kubernetes</category></item><item><title>nginx 변수 proxy_pass와 resolver — 일부 요청만 실패하는 DNS 조회</title><link>https://hansteches.com/posts/nginx-resolver-unrelated-dns-servers</link><guid isPermaLink="true">https://hansteches.com/posts/nginx-resolver-unrelated-dns-servers</guid><description>proxy_pass에 변수를 쓰면 nginx가 매 요청마다 resolver로 DNS를 조회합니다. resolver 목록에 그 존을 모르는 서버를 섞어놨더니 일부 요청만 실패했습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>networking</category><category>nginx</category><category>dns</category><category>resolver</category><category>coredns</category></item><item><title>PromQL rate() vs irate() — 평균 증가율과 순간 증가율</title><link>https://hansteches.com/posts/promql-rate-vs-irate</link><guid isPermaLink="true">https://hansteches.com/posts/promql-rate-vs-irate</guid><description>둘 다 Counter의 초당 증가율인데, rate는 범위 전체의 평균, irate는 마지막 두 샘플의 순간값입니다. 알람엔 rate, 실시간 대시보드엔 irate.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>data</category><category>prometheus</category><category>promql</category><category>monitoring</category></item><item><title>Redis SETNX 분산 락 — TTL·소유권·원자적 해제</title><link>https://hansteches.com/posts/redis-setnx-distributed-lock</link><guid isPermaLink="true">https://hansteches.com/posts/redis-setnx-distributed-lock</guid><description>여러 Pod가 같은 스케줄 작업을 중복 실행하지 않게 SETNX로 락을 겁니다. 그런데 TTL 없으면 데드락, 값이 단순하면 남의 락을 풀고, GET·DEL 사이엔 경합이 생깁니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>data</category><category>redis</category><category>distributed-lock</category><category>scheduler</category></item><item><title>rootless Docker — br_netfilter 로드 실패</title><link>https://hansteches.com/posts/rootless-docker-br-netfilter-bridge</link><guid isPermaLink="true">https://hansteches.com/posts/rootless-docker-br-netfilter-bridge</guid><description>root 없이 Docker를 돌리려는데 데몬이 br_netfilter 커널 모듈을 못 올려서 죽었습니다. rootless는 bridge 네트워크를 안 쓰는데 기본 설정이 bridge를 요구합니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>foundations</category><category>docker</category><category>rootless</category><category>linux</category><category>network</category></item><item><title>Spot Jenkins 에이전트 — 부팅마다 git pull</title><link>https://hansteches.com/posts/spot-jenkins-agent-git-pull-on-reboot</link><guid isPermaLink="true">https://hansteches.com/posts/spot-jenkins-agent-git-pull-on-reboot</guid><description>Spot 인스턴스는 언제든 새로 뜹니다. 그때마다 AMI 생성 시점의 옛날 설정을 쓰면 안 됩니다. @reboot에 git pull을 걸어 시작 시점에 최신화합니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cicd</category><category>jenkins</category><category>spot</category><category>ansible</category><category>asg</category></item><item><title>Terraform S3 네이티브 락 — DynamoDB 제거</title><link>https://hansteches.com/posts/terraform-s3-native-locking-drop-dynamodb</link><guid isPermaLink="true">https://hansteches.com/posts/terraform-s3-native-locking-drop-dynamodb</guid><description>state 락 하나 때문에 DynamoDB 테이블을 따로 두고 있었습니다. OpenTofu 1.10 / Terraform 1.11부터 S3 conditional write로 락이 되어서 테이블을 지웠습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>terraform</category><category>opentofu</category><category>s3</category><category>state</category></item><item><title>Vault UI 503 — 서비스 등록 endpoints 비어 있음</title><link>https://hansteches.com/posts/vault-503-service-registration-endpoints-none</link><guid isPermaLink="true">https://hansteches.com/posts/vault-503-service-registration-endpoints-none</guid><description>vault-active 서비스가 Active 파드를 못 찾고 있었습니다. 파드에 vault-active=true 라벨을 붙이는 건 service_registration 설정인데, 그게 빠져 있었습니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>security</category><category>vault</category><category>kubernetes</category><category>raft</category><category>ha</category></item><item><title>Vault KV v1 vs v2 — 경로 차이</title><link>https://hansteches.com/posts/vault-kv-v1-vs-v2</link><guid isPermaLink="true">https://hansteches.com/posts/vault-kv-v1-vs-v2</guid><description>v1로 마운트된 경로에 v2로 접근하면 404가 납니다. v2는 데이터와 메타데이터를 분리해서 실제 HTTP 경로에 /data/가 끼어듭니다.</description><pubDate>Thu, 13 Aug 2026 00:00:00 GMT</pubDate><category>security</category><category>vault</category><category>kv</category><category>secret</category></item><item><title>ARC — 쿠버네티스 위의 GitHub Actions 셀프호스트 러너</title><link>https://hansteches.com/posts/actions-runner-controller-arc-on-kubernetes</link><guid isPermaLink="true">https://hansteches.com/posts/actions-runner-controller-arc-on-kubernetes</guid><description>self-hosted 러너가 개수 고정이라 job이 대기했습니다. ARC로 옮기니 job마다 파드가 뜨고 사라지는데, 통신 방향이 K8s→GitHub 단방향이라 내부망에서도 됩니다.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>cicd</category><category>github-actions</category><category>arc</category><category>kubernetes</category><category>ci</category></item><item><title>PVC Pending의 세 원인 — EBS CSI · IRSA · hostPort</title><link>https://hansteches.com/posts/ebs-csi-irsa-hostport-pvc-pending</link><guid isPermaLink="true">https://hansteches.com/posts/ebs-csi-irsa-hostport-pvc-pending</guid><description>EBS CSI 컨트롤러가 자격증명을 못 얻어 볼륨을 못 만들었습니다. IRSA를 붙였더니 이번엔 컨트롤러 자체가 Pending이 됐고, 원인은 hostPort였습니다.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>security</category><category>ebs-csi</category><category>irsa</category><category>vault</category><category>kubernetes</category></item><item><title>Fluentd OOM — 메모리 버퍼 vs 파일 버퍼</title><link>https://hansteches.com/posts/fluentd-buffer-memory-to-file</link><guid isPermaLink="true">https://hansteches.com/posts/fluentd-buffer-memory-to-file</guid><description>버퍼가 메모리에 무제한으로 쌓이는 구성이었습니다. 파일 버퍼로 바꾸고 상한을 걸었는데, 배포 과정에서 다섯 번 막혔습니다.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>data</category><category>fluentd</category><category>kafka</category><category>elasticsearch</category><category>kubernetes</category></item><item><title>IRSA 크로스 계정 인증 — EKS Pod의 다른 계정 Bedrock 접근</title><link>https://hansteches.com/posts/irsa-cross-account-assume-role-bedrock</link><guid isPermaLink="true">https://hansteches.com/posts/irsa-cross-account-assume-role-bedrock</guid><description>ServiceAccount에 붙이는 role-arn과 앱 설정에 쓰는 role은 서로 다른 계정의 다른 역할입니다. 액세스 키를 걷어내면서 이 구분이 필요했습니다.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>ai</category><category>irsa</category><category>bedrock</category><category>eks</category><category>litellm</category></item><item><title>kube-apiserver 복구 — Calico 순환 의존</title><link>https://hansteches.com/posts/kubespray-cluster-api-server-recovery</link><guid isPermaLink="true">https://hansteches.com/posts/kubespray-cluster-api-server-recovery</guid><description>kubelet이 API 서버를 localhost로 찾고 있었습니다. 거기서 시작해 Calico, CoreDNS, Ingress, FluxCD가 순서대로 무너진 복구 기록.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>kubespray</category><category>calico</category><category>coredns</category><category>troubleshooting</category></item><item><title>terraform-aws-ec2-instance v5→v6 — root_block_device 형식 변경</title><link>https://hansteches.com/posts/terraform-ec2-module-v5-to-v6-breaking-change</link><guid isPermaLink="true">https://hansteches.com/posts/terraform-ec2-module-v5-to-v6-breaking-change</guid><description>Provider는 최신인데 모듈 버전이 그대로라 Unsupported argument가 났습니다. 모듈을 올리니 이번엔 root_block_device 형식이 리스트에서 객체로 바뀌어 있었습니다.</description><pubDate>Wed, 12 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>terraform</category><category>opentofu</category><category>aws</category><category>ec2</category></item><item><title>eBPF 프로세스 exec 감시 — 실제로 걸린 것들</title><link>https://hansteches.com/posts/ebpf-process-exec-watcher-gotchas</link><guid isPermaLink="true">https://hansteches.com/posts/ebpf-process-exec-watcher-gotchas</guid><description>특정 프로그램이 실행되는 순간을 잡는 도구를 만들었습니다. eBPF가 뭔지부터 정리하고, 프로세스 이름이 15자에서 잘리는 것과 타임스탬프가 1970년으로 찍히는 것까지.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>foundations</category><category>ebpf</category><category>linux</category><category>go</category><category>observability</category></item><item><title>AWS 타겟 그룹 Unhealthy 알람 — EventBridge · Lambda</title><link>https://hansteches.com/posts/target-group-health-alarm-eventbridge-lambda</link><guid isPermaLink="true">https://hansteches.com/posts/target-group-health-alarm-eventbridge-lambda</guid><description>AWS 로드밸런서(ALB)의 타겟 그룹이 5분 이상 Unhealthy면 Slack으로 알리는 요구사항. CloudWatch Alarm은 타겟 그룹 개수만큼 알람이 생기는 구조라, EventBridge 폴링 + Lambda 하나로 갔습니다.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>alb</category><category>lambda</category><category>eventbridge</category><category>monitoring</category></item><item><title>EKS Thanos 배포 트러블슈팅 — StorageClass·IRSA 연쇄 오류</title><link>https://hansteches.com/posts/thanos-prometheus-eks-issues</link><guid isPermaLink="true">https://hansteches.com/posts/thanos-prometheus-eks-issues</guid><description>StorageClass 하나 잘못 잡은 게 StatefulSet 재생성으로 번지고, IRSA Trust Policy에 ServiceAccount 하나 빠진 게 컴포넌트마다 Access Denied로 나왔습니다.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>data</category><category>thanos</category><category>prometheus</category><category>eks</category><category>irsa</category><category>helm</category></item><item><title>Traefik Gateway API — 포트 불일치</title><link>https://hansteches.com/posts/traefik-gateway-api-port-mismatch</link><guid isPermaLink="true">https://hansteches.com/posts/traefik-gateway-api-port-mismatch</guid><description>CrashLoopBackOff로 시작해 404, 그다음엔 Gateway가 Accepted로 안 넘어갔습니다. 증상은 셋 다 다른데 막힌 자리는 매번 포트였습니다.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>gateway-api</category><category>traefik</category><category>ncloud</category></item><item><title>Vault Secrets Operator refreshAfter — HMAC 기반 변경 감지</title><link>https://hansteches.com/posts/vso-refreshafter-hmac-secret-data</link><guid isPermaLink="true">https://hansteches.com/posts/vso-refreshafter-hmac-secret-data</guid><description>30초마다 Vault를 읽는데 부하가 문제되지 않았습니다. hmacSecretData가 값이 같으면 Kubernetes Secret을 건드리지 않아서, 진짜 비용이 드는 쪽이 안 돌아갑니다.</description><pubDate>Tue, 11 Aug 2026 00:00:00 GMT</pubDate><category>security</category><category>vault</category><category>vso</category><category>kubernetes</category><category>gitops</category></item><item><title>파드 Pending — volume node affinity 충돌</title><link>https://hansteches.com/posts/volume-node-affinity-conflict</link><guid isPermaLink="true">https://hansteches.com/posts/volume-node-affinity-conflict</guid><description>0/12 nodes are available이 떴는데 노드는 전부 살아 있는 상황. 원인은 EBS 볼륨이 묶여 있는 가용영역이었습니다.</description><pubDate>Mon, 10 Aug 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>scheduling</category><category>ebs</category><category>statefulset</category></item><item><title>브라우저 확장 보안 감사 — isTrusted · CSV 인젝션 · URL 스킴</title><link>https://hansteches.com/posts/browser-extension-security-audit-istrusted-csv-injection</link><guid isPermaLink="true">https://hansteches.com/posts/browser-extension-security-audit-istrusted-csv-injection</guid><description>확장이 AWS를 직접 부르다 보니 악성 페이지가 비용을 유발할 수 있었습니다. 사용자 입력 핸들러에 isTrusted 검사를 걸고, 단어장 CSV 인젝션과 출처 링크 스킴까지 훑었습니다.</description><pubDate>Sat, 08 Aug 2026 00:00:00 GMT</pubDate><category>security</category><category>browser-extension</category><category>security</category><category>xss</category><category>csv-injection</category></item><item><title>번역 프롬프트 엔지니어링의 한계 — 모델 천장</title><link>https://hansteches.com/posts/llm-translation-prompt-engineering-ceiling</link><guid isPermaLink="true">https://hansteches.com/posts/llm-translation-prompt-engineering-ceiling</guid><description>작은 모델로 자막을 번역하니 전문용어를 직역하고 관용구를 문자 그대로 옮겼습니다. 프롬프트 규칙으로 상당 부분 잡혔지만, 고정 예시를 넣었더니 그게 그대로 출력에 새어 나왔습니다.</description><pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate><category>ai</category><category>llm</category><category>prompt-engineering</category><category>translation</category><category>bedrock</category></item><item><title>보안 그룹 규칙 부재 증명 — CloudTrail 교차 검증</title><link>https://hansteches.com/posts/security-group-rule-never-existed-proof-of-absence</link><guid isPermaLink="true">https://hansteches.com/posts/security-group-rule-never-existed-proof-of-absence</guid><description>개발 서버 20대에 Zabbix 에이전트를 일괄 배포하자 3대가 곧바로 host down이 됐습니다. 반사적으로 &apos;오늘 누가 SG를 건드렸나&apos;를 봤지만, 그 규칙은 처음부터 없었습니다. 두 개의 독립된 증거로 &apos;한 번도 없었음&apos;을 증명한 과정.</description><pubDate>Thu, 06 Aug 2026 00:00:00 GMT</pubDate><category>networking</category><category>aws</category><category>security-group</category><category>zabbix</category><category>cloudtrail</category></item><item><title>LLM 자막 번역 — 줄 밀림과 문장 그룹핑</title><link>https://hansteches.com/posts/llm-subtitle-translation-line-shift-sentence-grouping</link><guid isPermaLink="true">https://hansteches.com/posts/llm-subtitle-translation-line-shift-sentence-grouping</guid><description>여러 줄을 한 번에 번역시키면 LLM이 줄 경계를 흐려 번역이 한 줄씩 밀립니다. 그리고 한 문장이 자막 세 조각에 걸치면 조각별 번역은 원리적으로 불가능합니다.</description><pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate><category>projects</category><category>llm</category><category>translation</category><category>bedrock</category><category>chrome-extension</category></item><item><title>Terraform ForceNew — 가용 영역(AZ) 추가에 클러스터 전체 재생성</title><link>https://hansteches.com/posts/terraform-add-one-az-forcenew-full-cluster-replace</link><guid isPermaLink="true">https://hansteches.com/posts/terraform-add-one-az-forcenew-full-cluster-replace</guid><description>클라우드 관리형 쿠버네티스에서 가용 영역(AZ)을 하나 늘리려고 네트워크 모듈에 추가했더니, terraform plan이 클러스터와 노드풀을 전부 replace했습니다. 모듈이 모든 서브넷을 클러스터에 넘겨서, 서브넷 목록 변경이 ForceNew를 건드렸습니다.</description><pubDate>Tue, 04 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>terraform</category><category>kubernetes</category><category>forcenew</category><category>iac</category></item><item><title>유튜브 자막 확보 — 플레이어 요청 가로채기</title><link>https://hansteches.com/posts/youtube-subtitle-capture-player-interception</link><guid isPermaLink="true">https://hansteches.com/posts/youtube-subtitle-capture-player-interception</guid><description>확장에서 유튜브 자막을 직접 부르니 빈 응답이 왔습니다. DOM 스크래핑은 느리고 화면이 움직였고, 결국 플레이어 자신의 요청을 가로채는 방식으로 갔습니다.</description><pubDate>Mon, 03 Aug 2026 00:00:00 GMT</pubDate><category>projects</category><category>chrome-extension</category><category>youtube</category><category>javascript</category></item><item><title>LiteTranslate — 브라우저 확장에서 Bedrock 직접 호출</title><link>https://hansteches.com/posts/litetranslate-serverless-browser-extension-bedrock</link><guid isPermaLink="true">https://hansteches.com/posts/litetranslate-serverless-browser-extension-bedrock</guid><description>유튜브 이중자막 번역·학습 확장을 만들면서 서버를 하나도 두지 않았습니다. 확장이 브라우저에서 직접 AWS를 부르고, 인증은 Cognito, 서명은 WebCrypto로 SigV4를 손수 짰습니다.</description><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><category>projects</category><category>chrome-extension</category><category>bedrock</category><category>cognito</category><category>sigv4</category><category>serverless</category></item><item><title>OpenStack 앱 크리덴셜 — 발급 시점 역할 고정</title><link>https://hansteches.com/posts/openstack-application-credential-role-snapshot</link><guid isPermaLink="true">https://hansteches.com/posts/openstack-application-credential-role-snapshot</guid><description>역할을 추가하고 키를 재발급해도 floating IP 생성이 계속 PolicyNotAuthorized였습니다. OpenStack 앱 크리덴셜은 발급 순간의 역할 목록을 키 안에 그대로 저장해서, 나중에 역할을 바꿔도 반영되지 않습니다.</description><pubDate>Sun, 02 Aug 2026 00:00:00 GMT</pubDate><category>cloud</category><category>openstack</category><category>keystone</category><category>iam</category><category>terraform</category></item><item><title>S3 삭제 감사 로그 유실 — append 동시성과 FIFO SQS</title><link>https://hansteches.com/posts/google-sheets-append-not-concurrency-safe-fifo-sqs</link><guid isPermaLink="true">https://hansteches.com/posts/google-sheets-append-not-concurrency-safe-fifo-sqs</guid><description>S3 라이프사이클로 지워진 파일을 스프레드시트에 기록하는 감사 파이프라인이 32건 중 25건만 남겼습니다. 모든 단계 지표는 32로 깨끗했는데, Lambda 컨테이너 재사용으로 append가 겹쳐 서로 덮었습니다. FIFO SQS에 단일 MessageGroupId로 직렬화해 해결했습니다.</description><pubDate>Thu, 30 Jul 2026 00:00:00 GMT</pubDate><category>cloud</category><category>aws</category><category>lambda</category><category>sqs</category><category>concurrency</category></item><item><title>SigV4 canonical URI 이중 인코딩 — Bedrock 403</title><link>https://hansteches.com/posts/sigv4-canonical-uri-double-encoding-bedrock-403</link><guid isPermaLink="true">https://hansteches.com/posts/sigv4-canonical-uri-double-encoding-bedrock-403</guid><description>브라우저에서 SigV4를 직접 구현해 Bedrock을 부르는데 계속 403이 났습니다. 서명 로직은 맞는 것 같은데, canonical URI를 한 번만 인코딩한 게 문제였습니다.</description><pubDate>Tue, 28 Jul 2026 00:00:00 GMT</pubDate><category>projects</category><category>sigv4</category><category>aws</category><category>bedrock</category><category>webcrypto</category></item><item><title>Langfuse LLM 비용 집계 누락 — 워커 이미지에 포함된 모델 단가</title><link>https://hansteches.com/posts/langfuse-zero-cost-model-prices-baked-in-image</link><guid isPermaLink="true">https://hansteches.com/posts/langfuse-zero-cost-model-prices-baked-in-image</guid><description>새로 나온 모델의 트레이스는 잘 쌓이는데 비용이 $0로 집계됐습니다. Langfuse 워커가 기동 때 이미지에 번들된 기본 단가 JSON으로 DB를 시딩하는데, 배포된 이미지가 그 모델보다 오래돼 단가가 없었습니다.</description><pubDate>Sun, 26 Jul 2026 00:00:00 GMT</pubDate><category>ai</category><category>langfuse</category><category>llm</category><category>observability</category><category>helm</category></item><item><title>Ubuntu 24.04 베이스 이미지 — UID 1000 충돌</title><link>https://hansteches.com/posts/ubuntu-2404-uid-1000-builtin-user-collision</link><guid isPermaLink="true">https://hansteches.com/posts/ubuntu-2404-uid-1000-builtin-user-collision</guid><description>보안 점검으로 베이스 이미지를 24.04로 올렸더니 useradd가 실패했습니다. ubuntu:24.04엔 UID/GID 1000을 이미 차지한 기본 ubuntu 유저가 있어서, 관습적인 useradd -u 1000이 충돌합니다.</description><pubDate>Wed, 22 Jul 2026 00:00:00 GMT</pubDate><category>foundations</category><category>docker</category><category>dockerfile</category><category>ubuntu</category><category>base-image</category></item><item><title>과금 지표 vs 파드 런타임 상태</title><link>https://hansteches.com/posts/billing-metric-not-runtime-truth-pod-stuck</link><guid isPermaLink="true">https://hansteches.com/posts/billing-metric-not-runtime-truth-pod-stuck</guid><description>사용량 로그에 &apos;컨테이너 실행 중&apos;이 찍혀 있어 정상이라 봤는데, 실제 파드는 볼륨을 못 붙여 ContainerCreating에서 멈춰 있었습니다. 그 지표는 요청 시점에 쓰이는 값이지 파드가 떠 있다는 뜻이 아니었습니다.</description><pubDate>Wed, 15 Jul 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>kubernetes</category><category>observability</category><category>ebs</category><category>cloudtrail</category></item><item><title>EKS 서브넷 IP 고갈 — 파드 churn과 WARM_IP_TARGET</title><link>https://hansteches.com/posts/eks-pod-churn-ip-exhaustion-warm-target</link><guid isPermaLink="true">https://hansteches.com/posts/eks-pod-churn-ip-exhaustion-warm-target</guid><description>부하 테스트로 파드를 빠르게 churn하니 서브넷의 사설 IP가 절대적으로 부족해졌습니다. 삭제된 IP가 바로 안 돌아와서 처음엔 회수 시간을 줄이려 했지만, 진짜 문제는 노드가 안 쓰는 IP를 쥐고 있는 것이었습니다.</description><pubDate>Fri, 10 Jul 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>eks</category><category>vpc-cni</category><category>ip</category><category>networking</category></item><item><title>S3 CORS — 와일드카드 한 단계와 presigned POST</title><link>https://hansteches.com/posts/s3-cors-wildcard-single-label-presigned-post</link><guid isPermaLink="true">https://hansteches.com/posts/s3-cors-wildcard-single-label-presigned-post</guid><description>브라우저 업로드가 CORS로 막혔습니다. S3 CORS의 AllowedOrigins 와일드카드는 한 단계 라벨만 매칭해서 두 단계 서브도메인을 못 잡았고, 규칙이 PUT만 허용해서 presigned POST 업로드를 안 덮었습니다.</description><pubDate>Thu, 09 Jul 2026 00:00:00 GMT</pubDate><category>cloud</category><category>aws</category><category>s3</category><category>cors</category><category>presigned-url</category></item><item><title>Docker 격리 규칙에 가려진 iptables ACCEPT — DOCKER-USER 체인</title><link>https://hansteches.com/posts/docker-user-chain-isolation-rule-shadows-accept</link><guid isPermaLink="true">https://hansteches.com/posts/docker-user-chain-isolation-rule-shadows-accept</guid><description>Docker를 최신으로 올린 뒤 컨테이너 포트가 외부에서 전부 타임아웃이었습니다. 직접 넣던 iptables ACCEPT 규칙이 Docker가 새로 추가한 격리 DROP 규칙에 가려져 있었고, DOCKER-USER 체인으로 옮겨 해결했습니다.</description><pubDate>Sat, 04 Jul 2026 00:00:00 GMT</pubDate><category>networking</category><category>docker</category><category>iptables</category><category>nftables</category><category>network</category></item><item><title>cgroup v1 경로 하드코딩 — v2에서 조용히 죽은 격리 로직</title><link>https://hansteches.com/posts/cgroup-v1-path-hardcoded-silent-noop-on-v2</link><guid isPermaLink="true">https://hansteches.com/posts/cgroup-v1-path-hardcoded-silent-noop-on-v2</guid><description>OS를 Ubuntu 22.04로 올린 뒤 컨테이너 생성이 몰릴 때 간헐적으로 실패했습니다. 코드는 그대로였는데, cgroup v1 경로를 하드코딩한 격리 로직이 cgroup v2 환경에서 매번 조용히 no-op이 되고 있었습니다.</description><pubDate>Fri, 03 Jul 2026 00:00:00 GMT</pubDate><category>foundations</category><category>cgroup</category><category>systemd</category><category>linux</category><category>upgrade</category></item><item><title>Docker 29에서 사라진 inspect 최상위 IPAddress 필드</title><link>https://hansteches.com/posts/docker-29-networksettings-ipaddress-removed</link><guid isPermaLink="true">https://hansteches.com/posts/docker-29-networksettings-ipaddress-removed</guid><description>Docker를 29로 올린 뒤 컨테이너 생성이 매번 롤백됐습니다. inspect 응답의 최상위 NetworkSettings.IPAddress 필드가 29부터 제거됐는데, 구버전 클라이언트는 이걸 에러가 아니라 빈 문자열로 받고 있었습니다.</description><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><category>foundations</category><category>docker</category><category>api</category><category>go</category><category>upgrade</category></item><item><title>Postgres initdb 실패 — 볼륨 루트의 lost+found</title><link>https://hansteches.com/posts/postgres-initdb-lost-found-ebs-pvc-root</link><guid isPermaLink="true">https://hansteches.com/posts/postgres-initdb-lost-found-ebs-pvc-root</guid><description>Postgres 파드가 CrashLoopBackOff에 빠졌습니다. 이미지도 권한도 문제가 아니었고, EBS 볼륨을 데이터 디렉토리에 직접 마운트하면서 생긴 lost+found가 initdb의 빈 디렉토리 검사를 통과 못 시켰습니다.</description><pubDate>Thu, 02 Jul 2026 00:00:00 GMT</pubDate><category>data</category><category>postgresql</category><category>kubernetes</category><category>ebs</category><category>initdb</category></item><item><title>RWO PVC 교착 — 삭제 순서와 Multi-Attach</title><link>https://hansteches.com/posts/rwo-pvc-multi-attach-finalizer-delete-order-deadlock</link><guid isPermaLink="true">https://hansteches.com/posts/rwo-pvc-multi-attach-finalizer-delete-order-deadlock</guid><description>야간 백업 Job과 사용자 재시작이 같은 RWO 볼륨을 두고 부딪혀 파드가 몇 시간씩 멈췄습니다. pvc-protection 파이널라이저, Multi-Attach, 그리고 볼륨은 지워졌는데 살아남은 Deployment까지 겹친 문제.</description><pubDate>Tue, 30 Jun 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>kubernetes</category><category>pvc</category><category>multi-attach</category><category>finalizer</category></item><item><title>Kafka Schema Registry — 비즈니스 이벤트 계약</title><link>https://hansteches.com/posts/kafka-schema-registry-event-contract</link><guid isPermaLink="true">https://hansteches.com/posts/kafka-schema-registry-event-contract</guid><description>Schema Registry는 로그 파이프라인이 아니라 서비스 간 비즈니스 이벤트의 스키마를 지킵니다. 호환성 모드를 걸면 깨질 스키마를 배포 시점에 막아, 런타임 장애를 배포 실패로 바꿉니다.</description><pubDate>Sat, 27 Jun 2026 00:00:00 GMT</pubDate><category>data</category><category>kafka</category><category>schema-registry</category><category>avro</category><category>event-driven</category></item><item><title>CronJob JWKS 유실 — 이미지에 없는 도구와 set -e</title><link>https://hansteches.com/posts/cronjob-kubectl-image-no-python-silent-jwks</link><guid isPermaLink="true">https://hansteches.com/posts/cronjob-kubectl-image-no-python-silent-jwks</guid><description>게이트웨이에서 JWT 검증이 kid not found로 실패했습니다. JWKS를 갱신하는 CronJob이 python3으로 문자열을 가공했는데, kubectl 이미지엔 python3이 없었고 set -e가 없어서 스크립트가 빈 값으로 ConfigMap을 덮었습니다.</description><pubDate>Thu, 25 Jun 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>kubernetes</category><category>cronjob</category><category>jwks</category><category>container-image</category></item><item><title>cgroup v1 vs v2 — PSI와 메모리 압력</title><link>https://hansteches.com/posts/cgroup-v1-vs-v2-psi-memory-pressure</link><guid isPermaLink="true">https://hansteches.com/posts/cgroup-v1-vs-v2-psi-memory-pressure</guid><description>쿠버네티스 requests/limits는 cgroup으로 구현됩니다. v1은 리소스별로 트리가 쪼개져 있고, v2는 하나로 통합되면서 PSI가 생겨 OOM으로 죽기 전에 메모리 압력을 감지할 수 있습니다.</description><pubDate>Sat, 20 Jun 2026 00:00:00 GMT</pubDate><category>foundations</category><category>cgroup</category><category>linux</category><category>kubernetes</category><category>psi</category></item><item><title>Jenkins GIT_COMMIT — Git 플러그인의 덮어쓰기</title><link>https://hansteches.com/posts/jenkins-git-commit-env-overwritten-by-git-plugin</link><guid isPermaLink="true">https://hansteches.com/posts/jenkins-git-commit-env-overwritten-by-git-plugin</guid><description>빌드 대상 레포의 커밋 해시를 env.GIT_COMMIT에 넣었는데, 배포 매니페스트엔 늘 jenkinsfile 레포의 해시가 찍혔습니다. Git 플러그인이 GIT_COMMIT을 환경 조회 때마다 다시 계산해 주입하기 때문입니다.</description><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><category>cicd</category><category>jenkins</category><category>pipeline</category><category>git</category><category>groovy</category></item><item><title>package-lock의 resolved가 옛 레지스트리를 가리킴 — npm ci 인증 실패</title><link>https://hansteches.com/posts/package-lock-resolved-points-to-old-registry</link><guid isPermaLink="true">https://hansteches.com/posts/package-lock-resolved-points-to-old-registry</guid><description>.npmrc를 새 레지스트리로 바꿨는데도 npm ci가 401로 실패했습니다. package-lock.json의 resolved URL이 옛 GitHub Packages를 그대로 가리키고 있었고, npm ci는 그 lock을 따라가기 때문이었습니다.</description><pubDate>Thu, 18 Jun 2026 00:00:00 GMT</pubDate><category>cicd</category><category>npm</category><category>package-lock</category><category>registry</category><category>ci</category></item><item><title>호스티드 러너에서 내부 npm 레지스트리 접근 불가 — self-hosted 러너</title><link>https://hansteches.com/posts/hosted-runner-cannot-reach-internal-npm-registry</link><guid isPermaLink="true">https://hansteches.com/posts/hosted-runner-cannot-reach-internal-npm-registry</guid><description>CI에서 install 단계만 계속 타임아웃이었습니다. 내부망 전용 npm 레지스트리를 GitHub의 호스티드 러너가 외부 IP라 소켓 연결조차 못 했고, 그 Job 을 self-hosted 러너로 옮겨 해결했습니다.</description><pubDate>Tue, 16 Jun 2026 00:00:00 GMT</pubDate><category>cicd</category><category>ci</category><category>github-actions</category><category>npm</category><category>network</category></item><item><title>WAF JA4 봇 차단의 한계 — 헤드리스 브라우저</title><link>https://hansteches.com/posts/waf-bot-detection-ja4-limits-ml</link><guid isPermaLink="true">https://hansteches.com/posts/waf-bot-detection-ja4-limits-ml</guid><description>TLS 지문(JA4)으로 봇넷을 자동 차단했는데, 봇이 헤드리스 크롬을 쓰기 시작하니 정상 사용자와 지문이 같아졌습니다. 단일 지문 의존을 버리고 복수 피처 + 이상 탐지로 옮긴 과정.</description><pubDate>Wed, 10 Jun 2026 00:00:00 GMT</pubDate><category>networking</category><category>waf</category><category>ja4</category><category>bot-detection</category><category>security</category></item><item><title>게이트웨이 JWT 검증 — exp 누락</title><link>https://hansteches.com/posts/gateway-jwt-exp-not-validated</link><guid isPermaLink="true">https://hansteches.com/posts/gateway-jwt-exp-not-validated</guid><description>만료된 토큰으로 호출했는데 401이 아니라 200이 왔습니다. 서명 검증은 정상인데 exp 클레임만 무시하고 있었습니다. 탈취된 토큰이 무기한 유효해지는 상황입니다.</description><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><category>security</category><category>jwt</category><category>gateway</category><category>auth</category></item><item><title>Redis ENOTFOUND — 원래 항상 나던 에러</title><link>https://hansteches.com/posts/redis-enotfound-that-was-always-there</link><guid isPermaLink="true">https://hansteches.com/posts/redis-enotfound-that-was-always-there</guid><description>파드가 뜰 때마다 Redis ENOTFOUND가 로그에 찍혔습니다. 그런데 서비스는 멀쩡했습니다. 삭제된 지 몇 달 된 ElastiCache 엔드포인트를 앱이 초기화 때 먼저 찾고 있었습니다.</description><pubDate>Thu, 04 Jun 2026 00:00:00 GMT</pubDate><category>data</category><category>redis</category><category>elasticache</category><category>troubleshooting</category><category>config</category></item><item><title>FailedAttachVolume — 삭제된 EBS 볼륨 복구</title><link>https://hansteches.com/posts/ebs-volume-deleted-failedattachvolume-recovery</link><guid isPermaLink="true">https://hansteches.com/posts/ebs-volume-deleted-failedattachvolume-recovery</guid><description>잘 쓰던 파드가 갑자기 안 떴습니다. PV가 가리키는 EBS 볼륨이 실제로는 삭제돼 있었고, 볼륨은 InvalidVolume.NotFound였습니다. 새 볼륨을 만들어 PV를 재생성해 복구했습니다.</description><pubDate>Tue, 02 Jun 2026 00:00:00 GMT</pubDate><category>kubernetes</category><category>ebs</category><category>persistentvolume</category><category>csi</category><category>kubernetes</category></item><item><title>Keycloak Authorization Code Flow — 왜 2단계인가</title><link>https://hansteches.com/posts/keycloak-authorization-code-flow-why-two-steps</link><guid isPermaLink="true">https://hansteches.com/posts/keycloak-authorization-code-flow-why-two-steps</guid><description>로그인하면 토큰을 바로 주지 않고, 짧은 code를 먼저 주고 서버가 그 code를 토큰으로 교환합니다. 토큰을 URL에 실으면 히스토리·로그·리퍼러로 새기 때문입니다.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><category>security</category><category>keycloak</category><category>oauth2</category><category>oidc</category><category>auth</category></item><item><title>Ubuntu 24.04 rootless Docker — nsenter와 netns</title><link>https://hansteches.com/posts/ubuntu-2404-rootless-docker-nsenter-netns</link><guid isPermaLink="true">https://hansteches.com/posts/ubuntu-2404-rootless-docker-nsenter-netns</guid><description>컨테이너로 작업을 돌리는 서버를 Ubuntu 24.04로 올린 뒤 컨테이너 접속이 깨졌습니다. apparmor의 userns 제한과 rootless docker의 detach-netns가 겹쳐서, nsenter가 엉뚱한 네임스페이스로 들어가고 있었습니다.</description><pubDate>Thu, 28 May 2026 00:00:00 GMT</pubDate><category>foundations</category><category>docker</category><category>rootless</category><category>nsenter</category><category>ubuntu</category><category>network</category></item><item><title>Prometheus 설정 리로드 실패 — 단일 파일 bind mount와 inode</title><link>https://hansteches.com/posts/prometheus-single-file-bind-mount-inode-reload</link><guid isPermaLink="true">https://hansteches.com/posts/prometheus-single-file-bind-mount-inode-reload</guid><description>prometheus.yml을 고치고 rsync로 올린 뒤 /-/reload를 불렀더니 200에 &apos;reloaded successfully&apos;까지 찍혔는데, 실제로는 옛날 설정이 그대로였습니다. 단일 파일 bind mount가 inode를 고정하고, rsync는 새 inode를 만들기 때문입니다.</description><pubDate>Wed, 20 May 2026 00:00:00 GMT</pubDate><category>foundations</category><category>prometheus</category><category>docker</category><category>bind-mount</category><category>inode</category></item><item><title>WebSocket vs HTTP — 소켓으로 몰면 잃는 것</title><link>https://hansteches.com/posts/websocket-vs-http-what-you-give-up</link><guid isPermaLink="true">https://hansteches.com/posts/websocket-vs-http-what-you-give-up</guid><description>실시간이라고 전부 WebSocket으로 옮기면 상태를 갖게 되어 수평 확장이 막히고, CDN·캐시·경로 라우팅 같은 HTTP 인프라를 통째로 잃습니다. 서버가 먼저 말해야 할 때만 소켓을 씁니다.</description><pubDate>Thu, 14 May 2026 00:00:00 GMT</pubDate><category>networking</category><category>websocket</category><category>http</category><category>realtime</category><category>architecture</category></item><item><title>L4 vs L7 로드밸런서 — 패킷을 어디까지 여는가</title><link>https://hansteches.com/posts/l4-vs-l7-load-balancer-how-deep</link><guid isPermaLink="true">https://hansteches.com/posts/l4-vs-l7-load-balancer-how-deep</guid><description>L4와 L7은 역할이 아니라 &apos;결정을 내리려고 패킷을 얼마나 열어보느냐&apos;의 차이입니다. 그 하나로 TLS passthrough 가능 여부, 클라이언트 IP가 어떻게 전달되는지가 전부 갈립니다.</description><pubDate>Fri, 08 May 2026 00:00:00 GMT</pubDate><category>networking</category><category>network</category><category>load-balancer</category><category>l4</category><category>l7</category></item><item><title>Node.js 이벤트 루프 — 큐 우선순위</title><link>https://hansteches.com/posts/nodejs-event-loop-queue-priority</link><guid isPermaLink="true">https://hansteches.com/posts/nodejs-event-loop-queue-priority</guid><description>Node.js가 콜백을 처리하는 순서에는 우선순위가 있습니다. nextTick과 Promise가 setTimeout·setImmediate보다 먼저 비워지고, 이 큐는 OS가 아니라 libuv가 프로세스 안에서 관리합니다.</description><pubDate>Thu, 30 Apr 2026 00:00:00 GMT</pubDate><category>foundations</category><category>nodejs</category><category>event-loop</category><category>libuv</category><category>async</category></item><item><title>서버리스 실시간 매치메이킹 — Cloudflare Functions · Supabase</title><link>https://hansteches.com/posts/serverless-realtime-matchmaking-cloudflare-supabase</link><guid isPermaLink="true">https://hansteches.com/posts/serverless-realtime-matchmaking-cloudflare-supabase</guid><description>실시간 대결 게임인데 상시 서버를 두지 않았습니다. 2초마다 도는 함수가 대기열을 훑어 실력이 비슷한 사람을 붙이고, 대기가 길어지면 매칭 범위를 넓힙니다.</description><pubDate>Wed, 22 Apr 2026 00:00:00 GMT</pubDate><category>projects</category><category>cloudflare</category><category>supabase</category><category>matchmaking</category><category>serverless</category><category>realtime</category></item><item><title>Glicko-2 레이팅 직접 구현</title><link>https://hansteches.com/posts/implementing-glicko2-rating-system</link><guid isPermaLink="true">https://hansteches.com/posts/implementing-glicko2-rating-system</guid><description>추론 대결 게임을 만들면서 순위 시스템이 필요했습니다. Elo 대신 Glicko-2를 골랐습니다. 실력뿐 아니라 &apos;그 실력을 얼마나 믿을 수 있는지&apos;까지 다루기 때문입니다.</description><pubDate>Mon, 20 Apr 2026 00:00:00 GMT</pubDate><category>projects</category><category>glicko2</category><category>rating</category><category>typescript</category><category>game</category></item><item><title>useEffect cleanup과 타이머 — 의존성 배열이 지우는 예약</title><link>https://hansteches.com/posts/react-useeffect-cleanup-timer-dependency</link><guid isPermaLink="true">https://hansteches.com/posts/react-useeffect-cleanup-timer-dependency</guid><description>별이 순서대로 켜져야 하는데 안 켜졌습니다. 애니메이션 useEffect의 cleanup에서 타이머까지 지우고 있었고, 그 effect가 phase마다 다시 돌면서 타이머를 매번 죽였습니다.</description><pubDate>Thu, 26 Mar 2026 00:00:00 GMT</pubDate><category>projects</category><category>react</category><category>useeffect</category><category>javascript</category><category>debugging</category></item><item><title>SFTP vs NFS — 실시간 I/O엔 왜 NFS인가</title><link>https://hansteches.com/posts/sftp-vs-nfs-realtime-io</link><guid isPermaLink="true">https://hansteches.com/posts/sftp-vs-nfs-realtime-io</guid><description>SFTP는 SSH 위의 파일 전송 서브시스템이라 요청-응답마다 왕복이 생기고, NFS는 커널 파일시스템이라 앱이 로컬 디스크처럼 씁니다. 배치 전송엔 SFTP, 실시간 I/O엔 NFS인 이유를 정리합니다.</description><pubDate>Thu, 12 Mar 2026 00:00:00 GMT</pubDate><category>foundations</category><category>sftp</category><category>nfs</category><category>filesystem</category><category>linux</category></item><item><title>대용량 CSV 스트리밍 — StreamingHttpResponse · select_related</title><link>https://hansteches.com/posts/django-streaming-csv-and-select-related</link><guid isPermaLink="true">https://hansteches.com/posts/django-streaming-csv-and-select-related</guid><description>관리 데이터를 CSV로 내보내는 기능인데 데이터가 쌓이니 응답이 느려지고 메모리를 먹었습니다. 응답을 스트리밍으로 바꾸고, ORM의 N+1을 select_related로 잡았습니다.</description><pubDate>Mon, 15 Jan 2024 00:00:00 GMT</pubDate><category>projects</category><category>django</category><category>csv</category><category>orm</category><category>performance</category></item></channel></rss>