본문 바로가기

개발노트/LINUX

testcontainers 사용 시, No such container 오류 메시지와 함께 test 가 실패한다면(feat. ARM)

Java Application 또는 Spring 을 사용하는 Application  에서 테스트 코드에 testcontainers 를 사용하고 있다.

개발 환경은 M1 Mac 이고, 배포 타겟도 AWS 의 graviton EC2 위에 올리는 Elastic Container Service 이다.

M1 Mac 으로 개발하기 전에는 Intel Mac 으로 개발을 했었고, 그 때에도 testcontainers 를 사용하여 테스틐 코드를 작성하며 개발했던 프로젝트가 있었다.

public dockerhub 에의 접근은 limit 이 걸려있으므로, 이를 우회하기 위해 dockerhub 으로 pull 받은 이미지를 그대로 private AWS ECR 에 올려놓고 사용하고 있었다.

testcontainers 를 사용하면 기본적으로 alpine, ryuk 라는 이미지를 받아오고 띄운다.

alpine 이미지는 어디서 쓰는지 정확하게 파악은 못했지만, 처음 테스트 코드를 실행할 때 alpine 이미지를 pulling 하는 로그를 볼 수 있다.

ryuk 는 test 코드 실행을 위해 띄운 container 를 죽이는 역할을 하는 image 이다.

하는 역할도 container 를 종료(죽이기)하는 것을 미뤄보아 아마도 데스노트의 사신인 류크(ryuk)라는 이름을 따온 것 같다.

 

이 이미지들을 예전에 Intel Mac 으로 개발할 때, AMD64 architecture(platform) 으로 이미지를 빌드하여 ECR 에 올려놓고 쓰고 있었고, 최근에 새로운 프로젝트는 M1 Mac 으로 개발하고 있기도 하고 그동안 AWS 에서도 ARM 기반의 인프라가 사용하기에 충분한 준비가 돼있어서 개발 환경 및 production runtime 환경도 ARM 으로 꾸리기로 했다. 비용도 저렴하고.

 

새 프로젝트에서 테스트 코드를 작성하고 testcontainers 가 띄우는 mysql 컨테이너 등이 잘 뜨고, 실행 결과도 Success 인 것을 확인할 수 있었으나, 실제 환경에 배포하기 전에 구축해둔 테스트 코드 실행을 위한 AWS CodeBuild 머신에서 Spring ApplicationContext 를 사용하는 모든 테스트 케이스가 실패하는 문제가 발생했다.

그 때 발생하는 오류 메시지는 "No such container: <container_id>" 였다.

이 오류 메시지 뒤에는 어떤 게 있을까 많은 삽질을 하며 시간을 허비했지만, 결론적으로는 ARM 기반의 ryuk 이미지로 컨테이너가 떠야하는데 AMD 기반의 ryuk 를 pulling 하여 run 하고 있었던 것이 원인이었다.

 

"testcontainers No such container" 라고 구글에 검색해보면, 정보가 많이 나오지 않았다.

그나마 key 가 될 수 있었던 github issue 가 하나 있었는데  처음엔 이를 간과하고 지나쳤다.

그러다 수많은 삽질이 시작됐고, 여러가지 시도를 많이 했었는데 CodeBuild 의 Environment 에서 base image 를 AMD 기반의 image 로 바꾸니 테스트 코드 실행이 성공한 것을 확인하고 나서, 다시 실패했던 때의 logs 를 살펴보니 mysql 이미지를 pulling 받는 로그가 나오지 않고 앞 단계인  ryuk 이미지를 pulling 받고 나서 오류가 발생하고 있다는 것을 확인할 수 있었다.

그래서 ECR 에 어떤 이미지를 pull 받는지 확인해보니, manifest 를 따로 두어 빌드하지 않은 AMD 기반의 ryuk 이미지를 가져오고 있었던 것임을 확인할 수 있었다.

testcontainers.properties 에서 아래와 같이 arm 용으로 빌드해서 ECR 에 올려둔 이미지를 사용하도록 설정을 해주니 문제가 해결됐다.

ryuk.container.image=testcontainers/ryuk-arm64:0.3.1

 

지금 다시 생각해보면, 처음 봤던 github issue 에서 ryuk 가 start 할 수 없는 것이 핵심적인 내용이었는데 로그를 자세히 보지 않았던 것도 있고, ARM 로컬(M1 Mac)에서는 잘 되는데 ARM CodeBuild 에서는 안 됐기 때문에 architecture(platform) 때문일 거라는 생각을 하지못했던 것이 너무 아쉽다.

 

이 과정에서 AWS CodeBuild 에서 빌드하는 것을 local 환경에서도 image 를 이용하여 시뮬레이션해볼 수 있는 방법도 https://dev.to/aws-builders/run-local-graviton2-builds-with-aws-codebuild-agent-1o6h 에서 찾았는데, 이걸 알게된 건 그 와중에 좋은 점이긴 했으나 빨리 해결하지 못해 너무 아쉽다.

 

결론적으로 testcontainers 를 사용하며 No such container 오류 메시지가 뜨며 실패하는 원인은 ryuk 라는 컨테이너가 제대로 실행되지 못했기 때문인 것이 대부분이고, ryuk 라는 컨테이너는 docker platform 이 다른 것이 이유로 실행되지 못할 수가 있다.

BTW, M1 Mac 에서도 AMD 기반의 docker image 를 pulling 하고 있는데, 왜 문제 없이 됐을까를 생각해보면 M1 Mac 에서 사용하고 있는 docker for desktop 에서는 성능에 문제가 있을 수는 있지만 알아서 대부분의 AMD 기반의 image 를 별다른 문제 없이 잘 실행해주고 있기 때문이다.

 

가장 좋은 방법은 public dockerhub 에 있는 docker image 를 기반으로 내부에서 사용하는 ECR 로 올릴 때, docker buildx 를 이용하여 platform 별로 이미지를 생성하고 이에 대한 manifest 도 만들어 push 하는 것이겠다.

반응형