본문 바로가기
DevOps

Argo CD CLI login 트러블슈팅 (ALB/Ingress, gRPC-Web, Windows)

by Rainbound-IT 2025. 8. 29.
반응형

 

 

내부 ALB(HTTP :8080) 뒤의 Argo CD에 Windows에서 CLI로 로그인하려다 context deadline exceeded 를 만난 분들을 위한 실전 메모입니다.
포인트만 요약하면:

  • CLI 플래그: --grpc-web --plaintext (+ 필요시 --skip-test-tls)
  • Ingress 경로: /grpc, /api, / 를 Prefix로 각각 백엔드 argocd-server:80에 포워딩
  • ALB 주석: backend-protocol-version=HTTP1, 헬스체크 /api/version
  • 서버 URL: configs.cm.url 을 외부에서 접속하는 실제 URL
  • 프록시 우회: NO_PROXY 에 ALB 호스트 추가

 


배경 환경

  • Kubernetes: v1.33
  • Argo CD: v3.1.x (서버), Windows CLI v3.1.x
  • 노출 방식: AWS ALB(Ingress), HTTP 포트 8080, 백엔드 Service:80 → Pod:8080
  • 증상:
    • curl http://<ALB>:8080/api/version 은 200 OK
    • POST /grpc 는 즉시 응답(200/40x)
    • 그런데 argocd login … --grpc-web --plaintext 는 context deadline exceeded

가장 빠른 해결(임시): 한 줄

HTTP 환경에서 TLS 사전 테스트를 건너뛰면 바로 풀리는 케이스가 많습니다.

argocd login <ALB_DNS>:8080 `
  --username <USER> `
  --password "<PASS>" `
  --grpc-web `
  --plaintext `
  --skip-test-tls
 
 

왜 되나?
CLI는 로그인 전 서버 TLS 여부를 테스트합니다. ALB가 8080(HTTP)에 대한 이 테스트를 애매하게 처리하면 타임아웃이 납니다. --skip-test-tls 로 그 절차를 생략하면 통과합니다.


근본 조치 체크리스트(권장, 플래그 없이도 되게 만들기)

  1. Ingress에 경로 3개를 명시
    • /grpc, /api, / 를 각각 Prefix로 argocd-server:80에 포워딩
  2. ALB 주석 보강
    • alb.ingress.kubernetes.io/backend-protocol: "HTTP"
    • alb.ingress.kubernetes.io/backend-protocol-version: "HTTP1"
    • alb.ingress.kubernetes.io/healthcheck-path: "/api/version"
    • alb.ingress.kubernetes.io/load-balancer-attributes: "idle_timeout.timeout_seconds=120"
  3. 서버의 공식 URL 설정
    • Helm values 의 configs.cm.url 을 http://<ALB_DNS>:8080 으로
    • 서버 로그 첫 줄에 (url: http://<ALB_DNS>:8080, tls: false) 로 보여야 정상
  4. 프록시 우회(Windows)
    • NO_PROXY 에 ALB 호스트, localhost, 127.0.0.1 추가
    $ALB='internal-...elb.amazonaws.com:8080'
    $env:NO_PROXY = @($env:NO_PROXY, ($ALB -split ':')[0], 'localhost','127.0.0.1') -join ','
     
  5. 버전 정렬
    • 서버와 같은 주요 버전의 argocd.exe 사용(v3.1.x ↔ v3.1.x)

Terraform/HCL 예시

Ingress (ALB, 내부)

 
 
resource "kubernetes_ingress_v1" "argocd_ingress" {
  metadata {
    name      = "argocd-ingress"
    namespace = "argocd"
    annotations = {
      "kubernetes.io/ingress.class"                        = "alb"
      "alb.ingress.kubernetes.io/scheme"                   = "internal"
      "alb.ingress.kubernetes.io/target-type"              = "ip"
      "alb.ingress.kubernetes.io/listen-ports"             = jsonencode([{ HTTP = 8080 }])

      "alb.ingress.kubernetes.io/backend-protocol"         = "HTTP"
      "alb.ingress.kubernetes.io/backend-protocol-version" = "HTTP1"
      "alb.ingress.kubernetes.io/healthcheck-path"         = "/api/version"
      "alb.ingress.kubernetes.io/success-codes"            = "200-399"
      "alb.ingress.kubernetes.io/load-balancer-attributes" = "idle_timeout.timeout_seconds=120"

      # 그룹 병합 충돌이 의심되면 전용 그룹으로
      # "alb.ingress.kubernetes.io/group.name"  = "argocd-alone"
      # "alb.ingress.kubernetes.io/group.order" = "1"
    }
  }

  spec {
    rule {
      http {
        path {
          path      = "/grpc"
          path_type = "Prefix"
          backend { service { name = "argocd-server" port { number = 80 } } }
        }
        path {
          path      = "/api"
          path_type = "Prefix"
          backend { service { name = "argocd-server" port { number = 80 } } }
        }
        path {
          path      = "/"
          path_type = "Prefix"
          backend { service { name = "argocd-server" port { number = 80 } } }
        }
      }
    }
  }
}
 

Helm values (서버 URL 포함)

configs:
  params:
    server.insecure: "true"          # HTTP 노출 (내부망)
  cm:
    url: "http://<ALB_DNS>:8080"     # 서버가 스스로 인식할 공식 URL
 
 
 

적용 후에는 반드시:

 
kubectl -n argocd rollout restart deploy/argocd-server
 

진단 루틴(순서대로 확인)

  1. 버전 RPC(익명 호출)
    argocd version --server <ALB_DNS>:8080 --grpc-web --plaintext --loglevel debug

    • 성공이면 gRPC-Web 기본 경로는 OK.

  2. REST 세션(로그인) 바로 테스트
    $body = @{ username="<USER>"; password="<PASS>" } | ConvertTo-Json
    Invoke-RestMethod -Uri "http://<ALB_DNS>:8080/api/session" `
      -Method POST -ContentType "application/json" -Body $body -TimeoutSec 15

    • 여기서 200 + token 이 오면 Ingress/프록시/URL 정합은 OK.
    • 404면 /api 라우팅 누락/충돌, 타임아웃이면 ALB/프록시 이슈.
  3. 토큰으로 CLI 호출(로그인 우회)
    • $TOKEN = "<위에서 받은 token>"
      argocd --server <ALB_DNS>:8080 --auth-token $TOKEN --grpc-web --plaintext app list

      되면 로그인 경로만 문제였던 것.
  4. 서버 로그 동시 확인

    kubectl -n argocd logs deploy/argocd-server --tail=200
    • 시도 시각에 로그가 전혀 없다 → Ingress/ALB에서 아직 막힘

 

 


자주 만난 함정 & 해법

  • $ALB 변수가 비어있어서
     
    lookup --grpc-web: no such host

    → $ALB 제대로 세팅 필요 (host:port, 프로토콜 없이)

  • 그룹 병합 충돌: 같은 ALB 그룹의 다른 Ingress가 /api 를 가로챔
    → 잠시 전용 그룹으로 분리해 테스트
  • 회사 프록시가 gRPC-Web 을 가로채 타임아웃
    → NO_PROXY 에 ALB 호스트 추가, 필요 시 HTTP(S)_PROXY 임시 언셋
  • 포워딩은 되는데 ALB는 안 됨
    → Ingress 경로/주석/URL 불일치. 위 체크리스트대로 정렬하면 해결.
  • 완전 HTTPS로 전환하고 싶다면
    → ALB 443 + 인증서를 붙이고, CLI는 argocd login argocd.example.com --grpc-web
    (자가서명/사설CA면 --insecure)

 


결론

  • HTTP + ALB + gRPC-Web 조합에서는,
    1. 경로 분리(/grpc, /api, /), 2) HTTP1 강제, 3) 서버 URL 정합, 4) 프록시 우회
      이 네 가지만 맞추면 argocd login 은 안정적으로 붙습니다.
  • 급할 땐 --skip-test-tls 로 먼저 살리고, 여유 있을 때 Ingress/values 를 위 가이드대로 정리하세요.
반응형

댓글