인터넷 차단 노드에 Fluent Bit 배포 (Helm + ECR Pull Through Cache 활용)

신동수·2026년 3월 27일

AWS

목록 보기
34/34

EKS 환경에서 CloudWatch Observability 를 사용하여 특정 로그를 Cloudwatch 로 전송하고 있었다. 하지만 해당 기능은 비용으로 인해 사용하지 않고, 동일하게 가져가기 위해서 Flunet-Bit 만 구성하여 배포해야 했다.

하지만 DB 노드는 보안 정책으로 인터넷이 완전히 차단된 상태였고, 레지스트리(cr.fluentbit.io)에서 이미지를 가져오지 못하는 문제가 발생했다.
이로 인해 DB 노드에서만 Fluent Bit Pod가 ImagePullBackOff 상태에 빠지게 되었고,
로그 수집이 되지 않는 이슈가 발생하였다.

본 포스팅에서는 해당 문제를 해결하기 위해 AWS ECR의 Pull Through Cache 기능을 활용한 과정을 정리한다.

ECR Pull Through Cache?

ECR Pull Through Cache는 Amazon Elastic Container Registry (ECR)의 기능 중 하나로, 외부 컨테이너 레지스트리의 이미지를 ECR을 통해 자동으로 가져와 캐싱(cache) 해주는 기능이다.

동작 방식
Pull Through Cache는 단순 복사가 아니라 요청 기반 캐싱 구조
사용자가 ECR 경로로 이미지 Pull 요청
ECR에 해당 이미지가 없으면 외부 레지스트리(예: Docker Hub, Quay 등)에서 가져옴
가져온 이미지를 ECR에 저장 (캐싱)후 요청부터는 외부가 아니라 ECR에서 바로 제공

사용 이유

  1. 인터넷 없는 환경 (가장 중요)
    Private Subnet
    DB 노드 (Outbound 차단)
    보안 환경

  2. 속도 개선
    매번 외부에서 Pull 안 함
    ECR에서 빠르게 다운로드

  3. 안정성 확보
    Docker Hub rate limit 영향 없음
    외부 레지스트리 장애 영향 감소

  4. 보안 및 통제
    외부 이미지 직접 접근 차단
    ECR + IAM으로 접근 제어 가능

문제 상황

serviceAccount:
  create: true
  name: fluent-bit

# CHART 0.56.0
image:
  repository: cr.fluentbit.io/fluent/fluent-bit
  tag: 4.2.3
# fluent-bit 버전 확인
helm  search repo fluent/fluent-bit
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
fluent/fluent-bit       0.56.0          4.2.3           Fast and lightweight log processor and forwarde...

# 설치
helm upgrade --install fluent-bit fluent/fluent-bit -f values.yaml -n fluent-bit --create-namespace --version 0.56.0

위 yaml 로 모든 노드에 배포를 하게 된다면 DB 노드는 인터넷에 완전히 차단된 환경이라 해당 레지스트리에 접근하는 것이 불가하다.
아래와 같이 ErrImagePull 이란 상태가 되며 DB 노드에만 배포가 실패가 되는 것을 볼 수 있으며, describe 로 확인 시 Image 의 Pull 이 실패가 된 것을 볼 수 있다.

AP Node Group : 10.0.20.0/24, 10.0.30.0/24
DB Node Grouo : 10.0.40.0/24, 10.0.50.0/24

Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  3m7s                 default-scheduler  Successfully assigned fluent-bit/fluent-bit-kscg2 to ip-10-0-40-27.ap-northeast-2.compute.internal
  Warning  Failed     2m37s                kubelet            Failed to pull image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to pull and unpack image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed toresolve reference "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to do request: Head "https://cr.fluentbit.io/v2/fluent/fluent-bit/manifests/4.2.3": dial tcp 54.179.124.27:443: i/o timeout
  Warning  Failed     111s                 kubelet            Failed to pull image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to resolve reference "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to do request: Head "https://cr.fluentbit.io/v2/fluent/fluent-bit/manifests/4.2.3": dial tcp 54.179.124.27:443: i/o timeout
  Warning  Failed     58s (x3 over 2m37s)  kubelet            Error: ErrImagePull
  Warning  Failed     58s                  kubelet            Failed to pull image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to resolve reference "cr.fluentbit.io/fluent/fluent-bit:4.2.3": failed to do request: Head "https://cr.fluentbit.io/v2/fluent/fluent-bit/manifests/4.2.3": dial tcp 52.76.90.69:443: i/o timeout
  Normal   BackOff    20s (x5 over 2m36s)  kubelet            Back-off pulling image "cr.fluentbit.io/fluent/fluent-bit:4.2.3"
  Warning  Failed     20s (x5 over 2m36s)  kubelet            Error: ImagePullBackOff
  Normal   Pulling    6s (x4 over 3m7s)    kubelet            Pulling image "cr.fluentbit.io/fluent/fluent-bit:4.2.3"

ECR 및 IAM 정책 설정

작성자의 경우 ECR 은 공통으로 사용하는 계정에 위치하여 ECR 에서 생성한 레지스트리에 대한 권한을 추가해야한다.
IAM 같은 경우 외부 레지스트리에서 이미지를 한 번 가져와야 하여 Pull 권한이 있는 IAM Role 또는 IAM User 로 진행을 하였다.

참고 : 업스트림 레지스트리와 ECR 레지스트리를 동기화

IAM Policy

작성자는 EC2 에서 아래의 권한을 부여했다.

# EC2 에서 필요한 Policy
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "ecr:GetAuthorizationToken",
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "ecr:BatchCheckLayerAvailability",
                "ecr:BatchGetImage",
                "ecr:GetDownloadUrlForLayer",
                "ecr:BatchImportUpstreamImage"
            ],
            "Resource": "arn:aws:ecr:ap-northeast-2:<ACCOUNT>:repository/docker-hub/*"
        }
    ]
}

ECR Policy

ECR 은 다른 계정에 있어 정책은 아래와 같이 추가한다.

# 생성한 ECR 의 Policy
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPull",
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::<ACCOUN>:role/<YOUR_NODE_ROLE>",
          "arn:aws:iam::<ACCOUN>:role/<YOUR_EC2_ROLE>",
        ]
      },
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchImportUpstreamImage"
      ]
    }
  ]
}

ECR 구성

작성자 기준 fluent-bit 가 필요하여 아래와 같이 레지스트리를 생성 후 pull through cache 를 적용을 진행하였다.

보안 암호를 사용한 인증이 필요한 업스트림 레지스트리의 경우 보안 인증 정보를 AWS Secrets Manager 보안 암호에 필수로 저장해야 한다.

또한, 캐시 네임스페이스의 접두사는 docker-hub 로 두었으며, 업스트림 네임스페이스에선 특정 접두사를 통해 더 상세한 설정이 가능하다.
참고 : 풀스루 캐시 규칙 생성

확인

설정이 끝났다면 아래와 같이 레지스트리에 대해 Docker 클라이언트를 인증을 진행하며, 이미지를 가져오기 위해서는 ECR 에 우선으로 이미지가 있어야 한다.

# 인증
aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin <ACCOUNT>.dkr.ecr.ap-northeast-2.amazonaws.com
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

# 이미지 Pull
# 가져올 이미지를 1회 Pull 해줘야 노드에서도 ECR 에 올라간 Image 를 가져올 수 있다.
docker pull <ACCOUNT>.dkr.ecr.ap-northeast-2.amazonaws.com/docker-hub/fluent/fluent-bit:4.2.3
4.2.3: Pulling from docker-hub/fluent/fluent-bit
ce49d46500be: Pull complete
...중략...
a7bffe15054f: Pull complete
Digest: sha256:a5761fa961cb22dd0875883a4d446b1acd99d4935d77358aa9f50ee177e44fe2
Status: Downloaded newer image for <ACCOUNT>.dkr.ecr.ap-northeast-2.amazonaws.com/docker-hub/fluent/fluent-bit:4.2.3
<ACCOUNT>.dkr.ecr.ap-northeast-2.amazonaws.com/docker-hub/fluent/fluent-bit:4.2.3

아래와 같이 명시된 버전의 이미지를 가져올 수 있다.

# 기존 helm의 values.yaml 수정
# 기존
image:
  # repository: cr.fluentbit.io/fluent/fluent-bit # 외부 레지스트리
  tag: 4.2.3
  
# 변경
image:
  repository: <ACCOUNT>.dkr.ecr.ap-northeast-2.amazonaws.com/docker-hub/fluent/fluent-bit # 사용자 AWS 계정의 ECR URI
  tag: 4.2.3

# 재설치
helm uninstall fluent-bit -n fluent-bit
helm upgrade --install fluent-bit fluent/fluent-bit -f values.yaml -n fluent-bit --create-namespace --version 0.56.0

각 서브넷에 위치한 AP, DB 노드 모두 이미지를 가져온 후 배포를 완료할 수 있다.

마무리

인터넷이 차단된 환경에서는 외부 컨테이너 이미지를 사용하는 것이 어렵지만, ECR Pull Through Cache를 활용하면 이를 효과적으로 해결할 수 있다.
특히 EKS 환경에서 노드별 네트워크 제약이 있는 경우 해당 방식은 운영 안정성을 높이는 데 매우 유용하다.
향후에는 Private Registry 미러링 전략이나 이미지 사전 동기화 방식과도 비교해보면 좋을 것 같다.

profile
조금씩 성장하는 DevOps 엔지니어가 되겠습니다. 😄

0개의 댓글