Files
obsidian/infra/gateway-api.md

4.1 KiB

title, updated, tags
title updated tags
K3s Gateway API 마이그레이션 2026-03-22
k3s
traefik
gateway-api

개요

K3s Ingress → Gateway API 전환 완료 (2026-03-21). Traefik v3.6.9의 Gateway API provider 사용.

Traefik 설정

HelmChartConfig로 Gateway API provider 활성화:

providers:
  kubernetesGateway:
    enabled: true
gateway:
  listeners:
    web:
      namespacePolicy:
        from: All
    websecure:
      port: 8443
      protocol: HTTPS
      certificateRefs:
        - name: wildcard-inouter-com-tls
          namespace: cert-manager
      namespacePolicy:
        from: All

Gateway

  • GatewayClass: traefik (traefik.io/gateway-controller)
  • Gateway: traefik-gateway (kube-system)
  • Listeners: web (HTTP 8000) + websecure (HTTPS 8443)
  • TLS: cert-manager의 wildcard-inouter-com-tls 참조
  • ReferenceGrant: cert-manager → kube-system (Secret 참조 허용)

HTTPRoute 목록

Namespace Name Hosts Port
anvil nginx-anvil anvil.local, gnu.anvil.it.com 80
argocd argocd-server argocd.inouter.com 80 (insecure 모드)
ironclad nginx-ironclad ironclad.local 80
openmemory openmemory-mcp mem0.inouter.com 8765
searxng searxng searxng.inouter.com 8080
tools cloud-api-emulator emul.actions.it.com 3000
tools cloud-api-linode linode.actions.it.com 3001
tools cloud-api-vultr vultr.actions.it.com 3002
tools n8n n8n.inouter.com 5678
tools namecheap-api namecheap-api.anvil.it.com 80
tools nocodb nocodb.inouter.com 8080
tools vultr-api vultr-api.anvil.it.com 80
vault vault-mcp hcv.inouter.com (/mcp) 8080
vault vault-ui hcv.inouter.com (/) 8200

ArgoCD 변경사항

argocd-server를 insecure 모드로 변경 (configmap argocd-cmd-params-cmserver.insecure: "true"). TLS 종료를 Gateway에서 처리.

클러스터 내부 DNS (헤어핀 방지)

Pod에서 외부 도메인(gitea.anvil.it.com 등)에 접근할 때 트래픽이 외부로 나갔다 돌아오는 헤어핀 NAT 문제를 방지하기 위해, CoreDNS rewrite로 서비스 도메인을 Traefik ClusterIP로 직접 해석.

설정

ConfigMap coredns-custom (kube-system)의 hairpin.override:

rewrite name gitea.anvil.it.com traefik.kube-system.svc.cluster.local
rewrite name argocd.inouter.com traefik.kube-system.svc.cluster.local
rewrite name searxng.inouter.com traefik.kube-system.svc.cluster.local
rewrite name mem0.inouter.com traefik.kube-system.svc.cluster.local
rewrite name nocodb.inouter.com traefik.kube-system.svc.cluster.local
rewrite name n8n.inouter.com traefik.kube-system.svc.cluster.local
rewrite name hcv.inouter.com traefik.kube-system.svc.cluster.local
...

동작

  1. Pod이 gitea.anvil.it.com DNS 조회
  2. CoreDNS가 traefik.kube-system.svc.cluster.local로 rewrite
  3. Traefik ClusterIP 반환 → 클러스터 내부에서 처리
  4. Traefik이 HTTPRoute 호스트 매칭으로 백엔드 라우팅

이전 방식과 차이

방식 장점 단점
NodeHosts (IP 직접 등록) 단순 ClusterIP 변경 시 수동 갱신 필요, stale 엔트리 위험
rewrite (현재) ClusterIP 자동 추종 HTTPRoute 추가 시 rewrite 규칙도 추가 필요

장애 사례 (2026-03-22)

NodeHosts에 gitea.anvil.it.com → 10.43.205.207(stale ClusterIP)이 남아있어서 ArgoCD 전체가 Gitea 싱크 실패(Unknown 상태). CoreDNS rewrite 방식으로 교체하여 해결.

유지보수

새 HTTPRoute 추가 시 coredns-custom ConfigMap에 rewrite 규칙 추가 후 CoreDNS 재시작:

kubectl edit configmap coredns-custom -n kube-system
kubectl rollout restart deployment coredns -n kube-system

주의사항

  • Gateway/GatewayClass를 수동 생성하면 Helm upgrade 실패 (ownership metadata 충돌)
  • HelmChartConfig로만 설정할 것
  • namespacePolicy.from: All 필수 (기본값은 Same)
  • ArgoCD가 관리하는 Ingress를 삭제하면 재생성될 수 있으니 Application 확인 필요
  • HTTPRoute 추가 시 coredns-custom hairpin rewrite도 함께 추가할 것