본문 바로가기
DevOps

Terraform으로 AWS ALB Ingress 삭제 시 finalizer에 걸려 무한 대기하는 문제 해결기

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

목차

     

    1. 문제 상황

    Terraform으로 AWS ALB Ingress를 생성하고, terraform destroy를 실행했는데 Ingress 리소스에서 삭제가 진행되지 않고 계속 대기하는 상황이 발생했습니다.

    # destroy 시 무한 대기...
    module.alb_ingress.kubernetes_ingress_v1.alb_ingress: Still destroying... [id=app/alb-ingress, 10m elapsed]

    강제 종료 후 수동으로 다음 명령어를 실행하면 삭제가 됩니다.

    kubectl patch ingress alb-ingress -n app -p '{"metadata":{"finalizers":[]}}' --type=merge

    즉, metadata.finalizers가 삭제를 막고 있었던 겁니다.


    2. 원인 분석

    Kubernetes에서 finalizer는 리소스를 삭제하기 전에 반드시 실행되어야 하는 정리 작업을 정의합니다.
    Ingress의 경우, AWS Load Balancer Controller(ALB Controller)가 붙여놓은 finalizer를 컨트롤러가 직접 제거해야 삭제가 완료됩니다.

    Terraform에서 Ingress 삭제 시 finalizer가 남아있는 이유는 보통 다음 경우입니다.

    1. ALB Controller가 설치되어 있지 않거나 비정상 동작
      • 컨트롤러가 없으니 finalizer를 지울 주체가 없음.
    2. IngressClass/컨트롤러 불일치
      • Ingress가 ingressClassName을 잘못 설정하거나 어노테이션만 사용 → 컨트롤러가 이 Ingress를 관리하지 않음.
    3. 컨트롤러 watch-namespace 제한
      • ALB Controller가 해당 네임스페이스를 감시하지 않음.
    4. ALB Group 설정 꼬임
      • 같은 group.name을 쓰는 다른 Ingress가 남아있어 마지막 삭제가 지연됨.

    3. 해결 방법

    (1) ALB Controller 정상 동작 확인

    # 컨트롤러 파드 상태 확인
    kubectl -n kube-system get pods -l app.kubernetes.io/name=aws-load-balancer-controller -o wide
    
    # Ingress 관련 이벤트 로그 확인
    kubectl -n kube-system logs deploy/aws-load-balancer-controller | grep alb-ingress -C2
    • 컨트롤러 파드가 Running 상태여야 하고, 로그에 오류가 없어야 합니다.

    (2) ingressClassName 사용으로 전환

    이전에는 metadata.annotations["kubernetes.io/ingress.class"]를 사용했지만,
    Kubernetes 1.18+에서는 spec.ingressClassName 사용이 권장됩니다.

    resource "kubernetes_ingress_v1" "alb_ingress" {
      metadata {
        name      = "alb-ingress"
        namespace = kubernetes_namespace.app.metadata[0].name
    
        annotations = {
          "alb.ingress.kubernetes.io/scheme"         = "internal"
          "alb.ingress.kubernetes.io/target-type"    = "ip"
          "alb.ingress.kubernetes.io/group.name"     = "shared-alb"
          "alb.ingress.kubernetes.io/listen-ports"   = jsonencode([{ HTTP = 80 }])
          "alb.ingress.kubernetes.io/healthcheck-path" = "/"
        }
      }
    
      spec {
        ingress_class_name = "alb"  # ✅ 권장 방식
        rule {
          http {
            path {
              path      = "/"
              path_type = "Prefix"
              backend {
                service {
                  name = kubernetes_service.service_80.metadata[0].name
                  port { number = 80 }
                }
              }
            }
          }
        }
      }
    
      depends_on = [
        helm_release.aws_load_balancer_controller,
        kubernetes_service.service_80
      ]
    }

    (3) IngressClass 보장

    Helm으로 ALB Controller를 설치하면서 IngressClass를 생성하게 하거나, 직접 생성합니다.

    resource "kubernetes_ingress_class_v1" "alb" {
      metadata {
        name = "alb"
      }
      spec {
        controller = "ingress.k8s.aws/alb"
      }
    }

    (4) ALB Controller IRSA 구성

    Terraform으로 ALB Controller를 설치하고 IRSA를 설정하면 삭제 시 정상적으로 finalizer가 해제됩니다.

    resource "aws_iam_role" "lb_controller" {
      name = "AmazonEKSLoadBalancerControllerRole"
    
      assume_role_policy = jsonencode({
        Version = "2012-10-17",
        Statement = [{
          Effect = "Allow",
          Principal = {
            Federated = data.terraform_remote_state.eks.outputs.oidc_provider_arn
          },
          Action = "sts:AssumeRoleWithWebIdentity",
          Condition = {
            StringEquals = {
              # aud 조건 필수
              "${replace(data.terraform_remote_state.eks.outputs.cluster_oidc_issuer_url, "https://", "")}:aud" = "sts.amazonaws.com",
              "${replace(data.terraform_remote_state.eks.outputs.cluster_oidc_issuer_url, "https://", "")}:sub" = "system:serviceaccount:kube-system:aws-load-balancer-controller"
            }
          }
        }]
      })
    }

    4. 응급 대처 (수동 finalizer 제거)

    만약 이미 걸려서 삭제가 안 된다면 수동으로 finalizer를 제거할 수 있습니다.

    kubectl patch ingress alb-ingress -n app -p '{"metadata":{"finalizers":[]}}' --type=merge

    하지만 이건 임시방편이고, 근본 해결은 ALB Controller가 정상적으로 해당 Ingress를 관리하도록 하는 것입니다.


    5. 마무리

    • ALB Ingress 삭제 시 무한 대기는 대부분 finalizer를 지울 주체(컨트롤러)가 없거나 관리 범위에서 벗어난 경우.
    • Terraform에서는 spec.ingressClassName 사용 + ALB Controller 정상 설치 + IRSA 구성으로 문제 예방 가능.
    • finalizer를 무조건 수동으로 제거하는 습관은 지양하고, 컨트롤러 정상화가 우선.
    반응형

    댓글