Published on

EKS에서 Pod는 뜨는데 EFS Mount 타임아웃 해결

Authors

서론

EKS에서 워크로드 자체는 Running인데, 볼륨 마운트 단계에서만 멈추거나 MountVolume.SetUp failed / context deadline exceeded / mount.nfs: Connection timed out 같은 메시지가 반복되는 케이스가 있습니다. 특히 EFS는 NFS(2049/TCP) 기반이라, 애플리케이션 트래픽과는 다른 네트워크 경로/보안 규칙/CSI 드라이버 구성에 의해 “Pod는 뜨는데 스토리지만 안 붙는” 현상이 자주 발생합니다.

이 글은 다음 상황을 전제로 합니다.

  • Pod 스케줄링은 정상(노드에 올라감)
  • 컨테이너 이미지 Pull도 정상
  • 하지만 EFS 볼륨 마운트에서 타임아웃/무한 대기

문제의 80%는 (1) EFS Mount Target/서브넷/라우팅, (2) SG/NACL에서 2049 차단, (3) DNS 해석 실패, (4) EFS CSI 드라이버 설정/권한 중 하나입니다.

관련해서 “Pod는 뜨는데 트래픽이 0”인 네트워크 진단 흐름이 도움이 되는 경우가 많습니다: EKS Pod는 뜨는데 트래픽 0 - NetPol·SG·CNI 10분 진단


증상 확인: 이벤트와 노드 로그부터

가장 먼저 Pod 이벤트에서 “어디서 멈추는지” 확인합니다.

kubectl describe pod <pod> -n <ns>
kubectl get events -n <ns> --sort-by=.lastTimestamp | tail -n 50

자주 보이는 메시지:

  • MountVolume.SetUp failed for volume ... : rpc error: code = DeadlineExceeded
  • mount.nfs4: Connection timed out
  • failed to resolve "fs-xxxx.efs.<region>.amazonaws.com"
  • access denied by server while mounting 127.0.0.1:/ (efs-utils/iam 관련)

다음으로 “노드에서 실제 mount 시도”가 어떻게 실패하는지 확인합니다. 관리형 노드(EC2)라면 SSM 또는 SSH로 들어가고, Bottlerocket이면 별도 방식으로 로그를 수집해야 합니다. Bottlerocket 사용 시에는 아래 글의 로그 수집 흐름도 참고하세요.


1) EFS Mount Target이 노드와 같은 VPC/서브넷 경로에 있는가

EFS는 각 AZ별 Mount Target(ENI) 을 만들어 두고, 클라이언트(노드)는 자기 AZ에 있는 Mount Target로 붙는 것이 정석입니다.

체크리스트:

  • EKS 노드가 있는 모든 AZ에 EFS Mount Target이 존재하는가?
  • 노드 서브넷 라우팅 테이블이 EFS Mount Target ENI로 가는 경로를 막고 있지 않은가?
  • 서로 다른 VPC(피어링/Transit Gateway) 구성이라면, NFS 2049 라우팅과 SG 참조가 올바른가?

확인 방법(AWS CLI):

aws efs describe-mount-targets --file-system-id fs-xxxxxxxx
aws efs describe-mount-target-security-groups --mount-target-id fsmt-xxxxxxxx

전형적인 실수

  • 노드는 ap-northeast-2a/2c에 있는데, EFS Mount Target은 2a에만 있음 → 2c 노드에서 mount 타임아웃
  • EFS는 같은 VPC인데, 노드가 있는 프라이빗 서브넷의 NACL이 2049를 막음

해결:

  • 노드가 존재할 수 있는 AZ마다 Mount Target 생성
  • NACL/라우팅 재점검(특히 사설망에서 “허용 규칙을 최소화”하다가 NFS를 빼먹는 경우)

2) Security Group: 2049/TCP 인바운드가 “EFS 쪽”에 열려있는가

EFS 마운트는 클라이언트(노드) → EFS Mount Target(ENI) 방향의 2049/TCP 연결입니다.

즉, 다음이 핵심입니다.

  • EFS Mount Target에 붙은 SG 인바운드에 TCP 2049가 허용되어야 함
  • 소스는 보통 EKS 노드 SG(또는 노드가 사용하는 SG)로 제한

예시(권장):

  • EFS SG Inbound: TCP 2049 Source: sg-eks-nodes
  • EFS SG Outbound: 기본(전체 허용) 또는 필요 범위

주의할 점:

  • “노드 SG에 2049 인바운드를 열었다”는 건 방향이 반대라 의미가 없습니다.
  • EKS에서 Pod SG(Security Groups for Pods) 를 쓰는 경우, 실제 트래픽 소스가 노드 SG가 아니라 Pod SG일 수 있습니다. 이때는 EFS SG 인바운드 소스를 Pod SG로 허용해야 합니다.

빠른 네트워크 레벨 확인(노드에서):

# 노드에서 EFS DNS가 해석된 IP로 2049 연결 테스트
nc -vz fs-xxxx.efs.<region>.amazonaws.com 2049
# 또는
curl -m 2 telnet://fs-xxxx.efs.<region>.amazonaws.com:2049
  • succeeded면 SG/NACL/라우팅은 통과 가능성이 큼
  • timed out면 거의 확실히 SG/NACL/라우팅 문제

3) DNS 문제: EFS 도메인 해석 실패로 “타임아웃처럼” 보이는 경우

EFS는 보통 아래 DNS 이름으로 마운트합니다.

  • fs-xxxx.efs.<region>.amazonaws.com

클러스터 DNS(CoreDNS)나 VPC DNS 설정이 꼬이면 다음처럼 실패합니다.

  • failed to resolve 또는 재시도 끝에 deadline exceeded

확인(디버그 파드):

kubectl run -it --rm dnsutils --image=registry.k8s.io/e2e-test-images/jessie-dnsutils:1.3 --restart=Never -- nslookup fs-xxxx.efs.<region>.amazonaws.com

해결 포인트:

  • VPC의 enableDnsHostnames, enableDnsSupport 활성화
  • CoreDNS가 정상인지, 노드에서 VPC resolver로 나가는 경로가 정상인지
  • DNS가 간헐적으로 실패한다면 NodeLocal DNSCache도 고려

간헐 DNS 실패를 잡는 방법은 이 글도 참고할 만합니다: EKS NodeLocal DNSCache로 DNS 간헐 실패 잡기


4) EFS CSI Driver 설치/버전/애드온 상태 점검

EKS에서 EFS를 PV로 붙이는 표준은 Amazon EFS CSI Driver입니다.

확인:

kubectl get pods -n kube-system | grep efs
kubectl get csidriver | grep efs

일반적으로 다음 컴포넌트가 떠 있어야 합니다.

  • efs-csi-controller (deployment)
  • efs-csi-node (daemonset)

또한 StorageClass와 PV/PVC가 올바른지 확인합니다.

kubectl get sc
kubectl describe sc <efs-sc>

kubectl get pv,pvc -A | grep efs
kubectl describe pvc <pvc> -n <ns>

mountOptions/전송 모드가 문제를 만드는 케이스

간혹 mountOptions에 잘못된 옵션을 넣어 마운트가 지연/실패할 수 있습니다.

예시(StorageClass):

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: efs-sc
provisioner: efs.csi.aws.com
parameters:
  provisioningMode: efs-ap
  fileSystemId: fs-xxxxxxxx
  directoryPerms: "700"
  gidRangeStart: "1000"
  gidRangeEnd: "2000"
  basePath: "/dynamic_provisioning"
mountOptions:
  - tls
reclaimPolicy: Delete
volumeBindingMode: Immediate
  • tls는 efs-utils를 통해 암호화 전송을 사용합니다.
  • 노드 이미지/AMI에 amazon-efs-utils가 없거나 오래되면 문제가 될 수 있습니다(드라이버가 도와주지만 환경에 따라 엣지 케이스 존재).

5) NACL(네트워크 ACL)에서 2049 또는 에페메럴 포트가 막히는 경우

SG는 상태 저장(stateful)이지만, NACL은 상태 비저장(stateless)입니다. 따라서 NACL을 엄격하게 운용하면 다음이 필요합니다.

  • Outbound: 노드 서브넷 → EFS 2049 허용
  • Inbound: EFS → 노드 서브넷 응답 트래픽(에페메럴 포트 범위) 허용

많이 쓰는 에페메럴 포트 범위(환경별 상이):

  • 1024-65535 또는 32768-60999 등

증상은 SG 문제와 거의 동일하게 “타임아웃”으로 나타납니다. SG를 다 열었는데도 계속 타임아웃이면 NACL을 의심하세요.


6) IRSA/IAM 연동(EFS Access Point, IAM authorization) 이슈는 “타임아웃”이 아니라 “권한 오류”로 보이는가

EFS는 두 가지 축이 있습니다.

  • 네트워크(NFS 2049)
  • 권한(Access Point POSIX, IAM authorization + tls)

권한 이슈는 보통 access denied 계열로 떨어지며, 순수 타임아웃과는 결이 다릅니다. 다만 tls + iam 조합에서 efs-utils/STS 호출이 얽히면 원인 파악이 어려울 수 있습니다.

만약 CSI 드라이버가 AWS API를 호출해야 하는데 자격 증명 문제로 막히면, 다음 글의 IRSA/자격증명 진단 방식이 그대로 적용됩니다.

또한 노드/파드에서 IMDS 접근이 401로 막혀 연쇄적으로 인증 문제가 생기는 경우도 있으니, IMDS/IRSA 설정을 점검하세요.


7) 재현 가능한 최소 매니페스트로 빠르게 좁히기

문제를 단순화하기 위해 “EFS 마운트만 하는” 테스트 파드를 만들어 봅니다.

PVC/PV가 이미 있다면: 단순 mount 테스트 Pod

apiVersion: v1
kind: Pod
metadata:
  name: efs-mount-test
  namespace: default
spec:
  containers:
    - name: app
      image: public.ecr.aws/amazonlinux/amazonlinux:2023
      command: ["bash", "-lc", "set -eux; df -h; ls -al /mnt/efs; sleep 3600"]
      volumeMounts:
        - name: efs
          mountPath: /mnt/efs
  volumes:
    - name: efs
      persistentVolumeClaim:
        claimName: <your-pvc>

적용 후 이벤트 확인:

kubectl apply -f efs-mount-test.yaml
kubectl describe pod efs-mount-test
  • 여기서도 타임아웃이면, 앱 문제가 아니라 클러스터/네트워크/스토리지 레이어 문제로 확정됩니다.

10분 컷 체크리스트(우선순위)

  1. kubectl describe pod 이벤트에서 에러 문자열 확보
  2. EFS Mount Target이 노드가 있는 모든 AZ에 있는지 확인
  3. EFS Mount Target SG 인바운드에 TCP 2049 소스를 노드 SG(또는 Pod SG) 로 허용
  4. NACL을 쓰면 2049 + 응답 에페메럴 포트 허용
  5. 디버그 파드로 nslookup fs-xxxx... 확인 (DNS)
  6. 노드에서 nc -vz <efs-dns> 2049로 네트워크 레벨 확인
  7. EFS CSI driver 파드/CSIDriver/StorageClass 상태 점검

결론

“Pod는 되는데 EFS Mount만 타임아웃”은 대부분 NFS 2049 연결이 어디선가 막힌 것입니다. 특히 EFS는 Mount Target이 AZ별로 존재하고, 트래픽 방향이 노드 → EFS라는 점 때문에 SG를 반대로 열어두는 실수가 잦습니다. 위 순서대로 보면 대개 10~20분 내에 원인을 좁힐 수 있고, 네트워크가 정상이라면 그 다음은 DNS/CSI 드라이버/권한(Access Point, IRSA)로 넘어가면 됩니다.

운영 환경에서는 변경 전후로 다음을 꼭 남겨두면 재발 방지에 도움이 됩니다.

  • EFS SG 인바운드 규칙(2049 소스)
  • 노드 서브넷 NACL 규칙
  • 노드가 속한 AZ와 EFS Mount Target 매핑
  • EFS CSI driver 버전 및 애드온 설정