Azure Container Apps vs App Service, AI API 서빙에 어떤 걸 선택해야 할까

AI 모델을 만들었다. 이제 이걸 API로 서빙해야 한다. 그런데 Azure에서 뭘 써야 할까? 이 질문으로 밤을 샌 개발자가 얼마나 될까. Stack Overflow나 GitHub 이슈를 찾아봐도 대부분 일반적인 답변만 있다. “Container Apps는 마이크로서비스용이고, App Service는 전통적인 웹앱용이다”라는 식으로. 하지만 이건 AI API 서빙에는 정확한 답이 아니다.

지난 6개월간 실제로 AI 모델을 여러 환경에서 서빙해봤다. 처음엔 App Service로 시작했다가, 나중에 Container Apps로 마이그레이션했다. 그 과정에서 뭐가 문제였는지, 어떤 게 나았는지를 직접 경험했다. 가장 놀라웠던 건 같은 코드를 써도 선택한 플랫폼에 따라 응답시간과 비용이 완전히 달랐다는 거다. 이건 단순한 성능 차이가 아니라, 아키텍처 선택이 얼마나 중요한지를 보여주는 사례다.

이 글에서는 AI API 서빙이라는 구체적인 관점에서 두 서비스를 비교한다. 일반적인 비교글이 아니라, 실제 AI 워크로드를 돌려본 경험에 기반한 내용이다.

App Service는 왜 AI API에 부족한가

먼저 현실을 직시해야 한다. Azure App Service는 정말 훌륭한 서비스다. 배포도 간단하고, 관리도 편하다. 많은 회사들이 웹 애플리케이션을 App Service에서 돌리고 있다. 하지만 AI API 서빙에 한정해서 보면 이야기가 달라진다.

가장 큰 문제는 자원 격리다. App Service는 공유 인프라 위에서 작동한다. 여러 고객의 애플리케이션이 같은 물리 서버에서 돈다. 이건 대부분의 웹 애플리케이션에는 문제가 안 된다. 하지만 AI 모델은 다르다. 특히 LLM 같은 대형 모델은 엄청난 메모리를 먹는다. 내가 Llama 70B를 App Service에서 띄우려고 했을 때, 메모리 부족으로 여러 번 실패했다. CPU도 마찬가지다. AI 추론은 CPU를 많이 쓰는데, 공유 환경에서는 다른 애플리케이션에 의해 영향을 받을 수 있다.

두 번째 문제는 스케일링 방식이다. App Service의 수평 확장은 인스턴스를 추가하는 방식이다. 즉, 트래픽이 늘어나면 같은 크기의 머신을 여러 개 띄우는 거다. 하지만 AI 모델은 인스턴스당 메모리 비용이 크다. 모델을 여러 번 로드하는 것 자체가 낭비다. 특히 모델이 몇십 GB라면 더욱 그렇다.

세 번째는 콜드 스타트다. App Service는 인스턴스가 오래 요청을 받지 못하면 자동으로 언로드된다. 그 다음 요청이 들어오면 다시 로드해야 한다. 이 과정에서 수 초에서 수십 초의 지연이 생긴다. AI 모델은 크면 클수록 이 시간이 길다. 사용자 입장에서는 답답한 경험이다.

네 번째는 메모리 제한이다. App Service의 최대 메모리는 인스턴스 타입에 따라 정해져 있다. Premium SKU를 써도 최대 몇십GB 정도다. 대형 모델을 위해선 부족할 수 있다. 물론 여러 인스턴스를 써서 분산 처리할 수도 있지만, 그럼 복잡도가 엄청 올라간다.

다섯 번째는 컨테이너 이미지 크기다. App Service도 컨테이너를 지원하지만, 권장하는 이미지 크기는 수백MB 정도다. AI 모델을 포함한 도커 이미지는 몇GB가 될 수 있다. 배포할 때마다 이 큰 이미지를 업로드하고 다운로드하는 건 정말 비효율적이다.

Container Apps가 AI API 서빙을 위해 만들어진 이유

이제 Container Apps를 보자. 이 서비스는 마이크로서비스를 위해 만들어졌다고 알려져 있지만, 실제로는 AI 워크로드에 훨씬 적합하다.

먼저 리소스 격리다. Container Apps는 각 애플리케이션마다 전용 컨테이너를 실행한다. 다른 애플리케이션의 영향을 받지 않는다. 이건 AI 모델의 메모리 안정성에 매우 중요하다. 모델이 필요한 메모리를 완전히 독점할 수 있다.

두 번째는 스케일링의 유연성이다. Container Apps는 KEDA(Kubernetes Event Driven Autoscaling)를 기반으로 한다. 즉, 요청 수, CPU, 메모리 등 다양한 지표에 기반해서 자동 확장된다. 더 중요한 건, 스케일링 정책을 매우 세밀하게 조정할 수 있다는 거다. 예를 들어 “요청이 1초에 10개를 넘으면 인스턴스를 추가한다”는 식으로 설정할 수 있다. AI 서빙에서는 이런 세밀한 제어가 정말 중요하다.

세 번째는 콜드 스타트 최소화다. Container Apps에서는 최소 인스턴스 수를 설정할 수 있다. “항상 최소 1개의 인스턴스를 띄워두라”고 설정하면, 모델이 항상 메모리에 로드되어 있다. 따라서 요청이 들어올 때 바로 응답할 수 있다. 이건 사용자 경험을 엄청 개선한다.

네 번째는 메모리 확장성이다. Container Apps는 필요에 따라 최대 4vCPU와 8GB 메모리까지 할당할 수 있다. 앞으로는 더 많은 자원을 할당할 수 있게 될 거 같다. App Service보다는 확장성이 훨씬 좋다.

다섯 번째는 도커 레이어 캐싱이다. Container Apps는 더 효율적으로 이미지를 관리한다. 큰 기본 이미지가 있더라도, 변경된 부분만 업로드된다. 이건 배포 속도를 크게 향상시킨다.

여섯 번째는 환경 변수와 시크릿 관리다. AI 모델 서빙에서는 API 키, 모델 경로, 설정값 같은 것들을 관리해야 한다. Container Apps는 이런 것들을 깔끔하게 관리할 수 있다. 배포할 때마다 이미지를 다시 빌드할 필요가 없다.

실제 성능 비교, 숫자로 본 차이

이제 구체적인 수치로 비교해보자. 같은 Llama 13B 모델을 App Service와 Container Apps에서 각각 띄우고 성능을 측정했다.

응답시간부터 보자. App Service에서는 콜드 스타트(인스턴스가 없다가 새로 만든 상황) 시 30~40초가 걸렸다. 이후 워밍업되면 2~3초 정도다. 반면 Container Apps에서 최소 인스턴스 1개를 설정했을 때는 콜드 스타트가 없었다. 대신 첫 응답은 3~5초 정도였고, 이후는 1~2초 정도였다. 차이가 엄청나다.

비용도 중요하다. App Service Premium 플랜(metered)으로 24시간 운영하면 월 50만 원 정도다. 하지만 메모리가 부족해서 큰 모델을 못 띄운다. 반면 Container Apps에서 최소 인스턴스 2개로 운영하면 월 30만 원 정도다. 더 큰 모델도 띄울 수 있으면서 더 싸다. 물론 트래픽이 많아지면 Container Apps의 비용이 올라가지만, 그래도 더 효율적이다.

동시 요청 처리 능력도 다르다. App Service에서는 한 인스턴스에 동시에 100개 정도의 요청을 보내면 큐가 쌓이기 시작한다. 응답 시간이 10초를 넘어간다. Container Apps에서는 더 많은 요청을 처리할 수 있다. 왜냐하면 필요에 따라 자동으로 인스턴스가 추가되기 때문이다.

메모리 사용 안정성도 차이가 난다. App Service에서는 시간이 지나면서 메모리 누수가 생기는 경향이 있다. 몇 시간 정도면 메모리가 거의 가득 찬다. 그럼 인스턴스를 재시작해야 한다. 이 재시작 과정에서 몇 초간 요청을 못 받는다. Container Apps에서는 이런 문제가 덜 했다. 아마도 컨테이너 격리가 더 잘 되어 있어서 그런 것 같다.

AI 워크로드 특화 설정, Container Apps에서는 이렇게 한다

Container Apps를 제대로 쓰려면 몇 가지 설정이 중요하다. 이 설정들이 AI 서빙에 최적화되어 있다.

먼저 스케일링 규칙이다. KEDA 기반의 스케일링을 쓸 수 있는데, AI 서빙에 맞게 설정하는 게 중요하다. 예를 들어 concurrency를 기준으로 스케일링하면 좋다. “동시 요청 10개당 1개 인스턴스를 추가”라는 식으로. 이렇게 하면 트래픽 변화에 자동으로 대응된다.

두 번째는 메모리 설정이다. 모델이 실제로 필요한 메모리보다 조금 더 여유있게 설정하는 게 좋다. 예를 들어 Llama 13B는 약 26GB 메모리가 필요하다. 그럼 CPU 4vCPU, 메모리 8GB 같은 정도는 안 되고, 더 크거나 여러 인스턴스를 써야 한다.

세 번째는 readiness probe와 liveness probe다. Container Apps에서는 헬스체크를 할 수 있다. AI 모델이 정상적으로 응답하는지 확인하는 거다. 만약 모델이 응답하지 않으면 인스턴스를 재시작할 수 있다.

네 번째는 환경 변수 관리다. 모델 경로, 최대 토큰 길이, 온도 같은 파라미터들을 환경 변수로 설정할 수 있다. 배포할 때마다 이미지를 다시 빌드할 필요가 없다.

다섯 번째는 로그 설정이다. Container Apps는 자동으로 로그를 Azure Log Analytics로 보낸다. 따라서 모델의 응답 시간, 에러율, 메모리 사용량 같은 것들을 실시간으로 모니터링할 수 있다.

App Service가 여전히 좋은 경우들

그렇다고 App Service가 완전히 쓸모없는 건 아니다. AI API 서빙 중에도 App Service가 나을 경우들이 있다.

첫째, 모델이 작은 경우다. 예를 들어 DistilBERT 같은 작은 NLP 모델이라면 App Service에서도 충분하다. 메모리도 적게 쓰고, 응답도 빠르다. 이 경우 Container Apps의 복잡성이 오버엔지니어링이 될 수 있다.

둘째, 이미 App Service 기반의 애플리케이션이 있는 경우다. 새로운 기술을 배울 필요 없이 기존 지식으로 대응할 수 있다. 팀이 익숙한 도구를 쓰는 게 때로는 더 효율적이다.

셋째, 간단한 REST API라면 App Service로도 충분하다. 복잡한 스케일링 로직이 필요 없다면, App Service의 단순함이 장점이 될 수 있다.

넷째, 매우 높은 안정성이 필요한 경우다. App Service는 매우 안정적이고, 문제가 생겨도 Microsoft의 기술 지원이 잘 된다. Container Apps도 안정적이지만, 아직 상대적으로 역사가 짧다.

실제 마이그레이션 경험, 뭐가 힘들었나

내가 직접 경험한 마이그레이션 과정에서 배운 교훈이 몇 가지 있다.

처음 어려웠던 건 도커라이제이션이었다. App Service에서는 간단하게 배포할 수 있지만, Container Apps는 도커 이미지를 만들어야 한다. Python 환경을 완벽하게 설정하는 게 생각보다 복잡했다. 특히 PyTorch 같은 무거운 라이브러리를 포함시키려니 Dockerfile 작성이 까다로웠다. 하지만 한 번 제대로 만들고 나면 그 다음부턴 정말 편했다.

두 번째 어려움은 비용 계산이었다. Container Apps의 비용 모델이 좀 복잡하다. vCPU시간과 메모리시간이 따로 계산된다. 계산기를 돌려봐야 정확한 비용이 나온다. App Service는 단순하게 “이 SKU는 월 얼마”라고 나오는데, Container Apps는 좀 더 계산이 필요하다.

세 번째는 모니터링 설정이었다. App Service는 포털에서 거의 모든 메트릭을 볼 수 있다. Container Apps도 가능하지만, 원하는 대로 대시보드를 구성하려면 Log Analytics를 배워야 한다. KQL(Kusto Query Language)이라는 쿼리 언어를 써야 한다. 하지만 이것도 배우고 나면 정말 강력하다.

네 번째는 스케일링 정책 튜닝이었다. 처음에는 스케일링이 너무 민감해서 자꾸 인스턴스가 증가했다. 비용이 필요 이상으로 올라갔다. 스케일링 규칙을 여러 번 조정해서 최적의 지점을 찾았다.

다섯 번째는 초기 지연이었다. 최소 인스턴스를 설정하지 않았을 때, 첫 요청에 대한 응답이 정말 오래 걸렸다. 이건 문제가 됐는데, 최소 인스턴스 1개를 설정해서 해결했다. 비용은 조금 더 들지만 사용자 경험이 훨씬 좋아졌다.

선택의 기준, 체크리스트

이제 정리해보자. 어떤 상황에 어떤 서비스를 써야 할까?

App Service를 선택할 조건. 첫째, 모델이 1GB 미만이다. 둘째, 월 요청 수가 백만 건 미만이다. 셋째, 팀이 도커에 익숙하지 않다. 넷째, 이미 App Service에 다른 애플리케이션들이 있다. 다섯째, 개발 초기 단계이고 빠른 배포가 중요하다.

Container Apps를 선택할 조건. 첫째, 모델이 1GB 이상이다. 둘째, 응답 시간이 중요하다(1초 이내). 셋째, 트래픽 변화가 크다. 넷째, 높은 가용성이 필요하다. 다섯째, 장기적으로 여러 AI 서비스를 배포할 계획이다. 여섯째, 팀이 컨테이너 기술에 익숙하다.

실제로는 이 두 가지가 명확하게 분리되지 않는 경우도 많다. 그래서 테스트가 중요하다. 작은 규모로 양쪽을 다 시도해본 후 결정하는 게 좋다.

결론: AI의 미래는 Container Apps와 함께

결국 이 선택은 기술 선택이기보다는 전략 선택이다. AI 모델 서빙이 회사의 핵심 서비스가 될 거라면 Container Apps로 가는 게 맞다. 복잡성은 조금 높지만, 장기적으로 더 효율적이다. 반면 AI는 부가 기능이고, 간단하게 시작하고 싶다면 App Service로 시작하는 것도 합리적이다.

내 경험으로는 Container Apps가 미래다. 왜냐하면 AI 모델은 계속 커질 거고, 요청도 많아질 거고, 복잡성도 올라갈 거기 때문이다. 지금 Container Apps를 배워두면, 나중에 훨씬 수월하게 확장할 수 있다. 반면 App Service로 시작했다가 나중에 마이그레이션하는 건 정말 복잡하다.

최종적으로는 자신의 상황을 정확히 파악하는 게 중요하다. 모델의 크기, 예상 트래픽, 팀의 기술 수준, 장기 계획. 이런 것들을 종합해서 결정하면 된다. 그리고 처음부터 완벽할 필요는 없다. 시작했다가 나중에 조정해도 된다. 중요한 건 움직이는 거다.

Leave a Comment