3-1. 컨테이너 기본 개념¶
컨테이너(container)는 모델 서빙 API를 같은 조건으로 실행하기 위한 배포 단위입니다. 3-1에서는 컨테이너를 운영 인프라 심화 주제로 다루지 않고, 평가 때 확인한 모델 파일, 패키지, 설정값이 서빙 환경에서도 재현되는지 확인하는 관점으로 설명합니다.
이 문서를 읽을 때는 다음 기준을 중심으로 확인합니다.
- 실행 조건 재현: Python 버전, 패키지, 모델 파일, 설정값이 함께 묶이는지 확인
- 이미지(image)와 컨테이너 구분: 배포 대상 산출물과 실제 실행 상태를 분리해서 확인
- Linux kernel 기반: Linux container가 host kernel과 kernel 기능에 의존한다는 점을 확인
- hierarchy 관점: file tree, image layer, namespace, cgroup이 어떻게 실행 단위를 만드는지 확인
- 설정값 추적:
MODEL_VERSION,MODEL_THRESHOLD, 모델 경로가 의도한 값인지 확인 - 한계 인식: 컨테이너가 특성(feature), 전처리, 예측 클래스(class) 기준 일치를 자동 보장하지는 않음
3장의 상황으로 보면 컨테이너는 “API를 실행하는 포장”이 아니라, 2장에서 평가한 기준선 모델과 설정을 같은 조건으로 실행하기 위한 확인 단위입니다. chapter_02_baseline.pkl을 사용한다고 생각했는데 컨테이너 안에서는 다른 모델 경로나 다른 MODEL_THRESHOLD가 적용되면, API는 정상 응답해도 2장의 평가 결과와 연결하기 어렵습니다.
3-1-1. 컨테이너가 필요한 이유¶
AI 모델 평가는 노트북이나 로컬 스크립트에서 끝나지 않습니다. 실제 서비스에서는 모델 파일, Python 패키지, API 서버, 설정값, 로그 경로가 함께 실행되어야 합니다. 이 중 하나라도 개발 환경과 운영 환경에서 달라지면 같은 모델을 사용하더라도 다른 결과가 나올 수 있습니다.
컨테이너는 실행 환경을 하나의 배포 단위로 묶는 방법입니다. 모델 서빙 API를 실행할 때 필요한 코드, 패키지, 설정, 모델 산출물(model artifact)을 이미지에 포함하고, 그 이미지를 컨테이너로 실행합니다. 운영 관점에서는 컨테이너가 “모델 품질을 높이는 도구”라기보다 “같은 조건으로 실행하고 검증할 수 있게 만드는 도구”입니다.
Docker 공식 문서는 컨테이너를 애플리케이션과 실행 의존성을 함께 패키징해 실행하는 방식으로 설명합니다. AI 서비스에서 이 설명은 특히 중요합니다. 모델 API는 Python 코드만으로 동작하지 않고, 모델 산출물, 라이브러리 버전, 설정값, 실행 명령, 로그 경로가 함께 맞아야 합니다. 따라서 컨테이너는 모델 품질을 직접 보장하지는 않지만, 품질 확인을 반복 가능한 조건으로 묶어 주는 장치입니다.
실행 환경 차이는 같은 모델 artifact의 예측 결과나 실행 안정성을 바꿀 수 있습니다. 예를 들어 로컬 스크립트에서는 특정 Python 버전과 scikit-learn 버전으로 모델이 정상 동작했는데, 서빙 서버에는 다른 버전의 패키지가 설치되어 있다면 예측 결과나 실행 오류가 달라질 수 있습니다. 컨테이너는 이런 차이를 줄이기 위해 사용됩니다. 이 저장소의 Dockerfile은 python:3.11-slim을 기준 이미지(base image)로 사용하고, uv sync --frozen으로 실행 의존성을 고정합니다.
| 확인 항목 | 운영 관점 |
|---|---|
| Python 버전 | 학습 환경과 서빙 환경 차이로 인한 오류를 감소 |
| 패키지 버전 | scikit-learn, model server, API wrapper 등 실행 의존성을 고정 |
| 모델 파일 위치 | API가 의도한 모델 artifact를 읽는지 확인 |
| 환경 변수 | MODEL_VERSION, MODEL_THRESHOLD가 의도와 같은지 확인 |
| 실행 포트 | 서비스가 노출되는 포트와 문서가 일치하는지 확인 |
컨테이너는 모델 품질을 직접 보장하지 않습니다. 결측값(missing value)이 많은 데이터가 들어오면 같은 컨테이너를 사용해도 점수(score)와 예측(prediction) 분포는 흔들릴 수 있습니다. 그러나 같은 모델과 같은 설정을 반복 실행할 수 있기 때문에, 품질 확인 결과를 재현하고 배포 후 문제를 추적하는 데 중요합니다.
2장에서 만든 기준선(baseline) 모델을 예로 들면, 컨테이너에서 확인해야 할 것은 지표(metric) 개선이 아닙니다. artifacts/models/chapter_02_baseline.pkl을 의도한 경로에서 읽고, threshold=0.5, model_version=v1 같은 설정을 API 응답과 로그에서 확인할 수 있는지입니다. 이 정보가 확인되지 않으면 API 응답의 prediction이 평가 때의 판단 기준에서 나온 것인지 설명하기 어렵습니다.
흔한 오해는 “컨테이너로 배포했으니 학습 환경과 서빙 환경이 완전히 같다”는 것입니다. 컨테이너는 실행 환경을 고정하는 데 도움을 주지만, 학습 때 사용한 특성 목록, 전처리 방식, 예측 클래스 기준, 임계값(threshold)이 서빙 코드와 일치하는지는 별도로 확인해야 합니다. 이 문제는 “학습 기준과 서빙 기준의 불일치”이며, 3-5와 3-8에서 runtime 책임과 요청 계약으로 다시 확인합니다.
3-1-2. 이미지와 컨테이너의 차이¶
이미지는 실행에 필요한 파일과 설정을 담은 정적인 산출물입니다. 컨테이너는 그 이미지를 실제로 실행한 인스턴스입니다. 같은 이미지를 여러 번 실행하면 여러 컨테이너가 생길 수 있습니다.
QA가 이 차이를 이해해야 하는 이유는 배포 대상과 실행 상태가 다르기 때문입니다. 이미지에는 어떤 코드와 모델이 포함되었는지 확인해야 하고, 컨테이너에서는 실제로 실행 중인 프로세스가 올바른 설정으로 동작하는지 확인해야 합니다.
| 구분 | 의미 | 운영 확인 포인트 |
|---|---|---|
| 이미지 | 실행 파일, 패키지, 모델 파일을 담은 빌드 결과 | 어떤 모델 파일과 설정이 포함되었는지 확인 |
| 컨테이너 | 이미지가 실행된 프로세스 | 상태 확인(health check), API 응답, 로그를 확인 |
| 태그(tag) | 이미지 버전 식별자 | 배포 대상 이미지가 의도한 버전인지 확인 |
컨테이너 이미지는 태그뿐 아니라 포함된 모델 산출물과 설정값까지 확인해야 합니다. 예를 들어 ai-quality-serving:v1이라는 이미지를 만들었다고 하겠습니다. 이 이미지가 실제로 어떤 모델 산출물을 포함하는지, MODEL_VERSION이 어떤 값으로 설정되는지 확인해야 합니다. 그런 다음 컨테이너를 실행하고 /health와 /predict 응답에서 동일한 정보가 노출되는지 확인합니다.
Docker 확인은 빌드 성공에서 끝나지 않습니다. Dockerfile이 어떤 파일을 이미지에 넣는지 확인하고, 그 이미지가 컨테이너로 실행된 뒤 실제 API 응답에서 같은 설정이 보이는지까지 이어져야 합니다.
| 흐름 | 운영 확인 |
|---|---|
| Dockerfile | 코드, 설정, 모델 산출물을 이미지에 넣도록 정의되어 있는가 |
| Image | 빌드된 산출물이 의도한 모델 파일과 기본 설정을 포함하는가 |
| Container | 실행 중 환경 변수와 모델 경로가 의도와 같은가 |
| API response | /health, /predict에서 model_version, threshold, request_id가 확인되는가 |
이 흐름을 따라가면 “이미지가 만들어졌다”와 “평가 기준이 실행 중 API 응답에 반영되었다”를 구분할 수 있습니다. QA 보고서에는 어느 단계까지 직접 확인했는지 남겨야 합니다. Dockerfile inspection만 했다면 의도된 설정 흐름을 확인한 것이고, /predict live 응답까지 확인해야 실행 중 설정값을 검증했다고 쓸 수 있습니다.
이 차이를 모르면 “빌드한 이미지가 맞다”와 “현재 실행 중인 컨테이너가 맞다”를 혼동하기 쉽습니다. QA는 이미지의 포함물과 컨테이너의 실행 상태를 둘 다 확인해야 합니다.
이미지 태그(image tag)도 중요합니다. latest 태그만 사용하면 실제로 어떤 코드와 모델이 배포되었는지 추적하기 어렵습니다. 실습에서는 단순화를 위해 로컬 이미지(local image)를 사용하지만, 실무에서는 이미지 태그, 모델 버전(model_version), git commit, 데이터셋 버전(dataset version)을 함께 기록해야 배포 이력을 설명할 수 있습니다.
3-1-3. 컨테이너는 Linux kernel 기반 기술¶
Linux container는 host kernel을 공유하는 실행 방식입니다. 컨테이너는 가상 머신처럼 컨테이너마다 별도 kernel을 띄우지 않습니다. 대신 Linux kernel이 제공하는 namespace, cgroup, mount, capability, seccomp, overlay filesystem 같은 기능을 조합해 “분리되어 보이는 실행 환경”을 만듭니다. 그래서 컨테이너를 이해할 때는 먼저 “image는 파일 묶음이고, container는 host kernel 위에서 실행되는 process”라는 기준을 잡아야 합니다.
Docker Engine 설치 문서는 Docker Engine을 Linux에 설치하는 대상으로 설명하고, Windows와 macOS에서는 Docker Desktop을 통해 Docker Engine을 사용한다고 설명합니다. Docker multi-platform build 문서도 container가 host kernel을 공유하므로 실행되는 코드가 host의 architecture와 호환되어야 한다고 설명합니다. 이 관점은 “container가 OS 전체를 들고 다닌다”는 오해를 막아 줍니다.
macOS와 Windows에서 Linux container를 완전히 native하게 바로 실행하기 어려운 이유는 kernel이 다르기 때문입니다. Linux container image 안의 user space는 Linux syscall, Linux filesystem semantics, Linux process model을 기대합니다. 그러나 macOS는 Darwin/XNU kernel을 사용하고 Windows는 Windows NT kernel을 사용하므로, Linux namespace와 cgroup을 그대로 제공하지 않습니다. Container runtime은 kernel을 가상화하지 않기 때문에, Linux container를 실행하려면 결국 Linux kernel이 필요합니다.
Docker Desktop은 이 차이를 숨겨 주는 개발 도구입니다. macOS에서는 Docker Desktop의 Virtual Machine Manager가 Linux VM을 실행하고, 그 안에서 Linux container를 구동합니다. Windows에서는 WSL 2 backend가 Microsoft가 제공하는 full Linux kernel 위에서 Linux container 실행 환경을 제공합니다. Windows container도 존재하지만, 그것은 Windows kernel과 Windows base image를 대상으로 하는 별도 세계이며 Linux container image와 같은 실행 단위가 아닙니다.
운영 관점에서는 “내 Mac이나 Windows에서 Docker가 실행됐다”와 “운영 Kubernetes cluster에서 같은 Linux container가 실행된다”를 구분해야 합니다. 로컬 Docker Desktop의 VM resource, file sharing, CPU architecture, image platform이 운영 환경과 다르면 빌드와 실행은 성공해도 성능, 파일 경로, 권한, network 동작이 달라질 수 있습니다. 따라서 3장에서는 Docker 명령어 자체보다 base image, image platform, model artifact, environment, health, log가 운영 Linux 환경에서 같은 의미를 갖는지 확인합니다.
| 실행 환경 | Linux container 실행 방식 | 운영 확인 포인트 |
|---|---|---|
| Linux server | host Linux kernel 위에서 Docker Engine/container runtime이 직접 실행 | kernel 기능, image platform, resource limit, log path 확인 |
| macOS 개발 장비 | Docker Desktop이 Linux VM을 실행하고 그 안에서 container 실행 | VM resource, file sharing, architecture 차이 확인 |
| Windows 개발 장비 | Docker Desktop WSL 2 backend 또는 Hyper-V Linux VM에서 container 실행 | WSL 2 mode, Windows container mode 혼동 방지 |
| Windows container | Windows kernel과 Windows base image를 사용하는 별도 container | Linux image와 호환된다고 가정하지 않음 |
이 절에서 가능한 판단은 “container는 OS를 통째로 가상화한 것이 아니다”입니다. 수강생은 Linux container가 Linux kernel 기능 위에서 실행된다는 사실을 알고, local Docker Desktop 결과와 운영 Kubernetes 결과 사이에 VM, platform, filesystem sharing 차이가 있을 수 있음을 보고서 제한 사항으로 남길 수 있어야 합니다.
3-1-4. 컨테이너를 구성하는 hierarchy¶
컨테이너는 하나의 기술이라기보다 여러 hierarchy가 합쳐진 실행 단위입니다. 파일시스템 트리, 이미지 레이어, 프로세스 트리, 네트워크 관점, 리소스 제한 계층이 한 컨테이너 안에서 함께 작동합니다. 운영에서 컨테이너를 본다는 것은 이 계층들이 모두 같은 모델 버전, 같은 설정, 같은 로그 경로를 가리키는지 확인한다는 뜻입니다.
일반 파일시스템은 디렉터리 트리와 inode 같은 메타데이터를 통해 파일 위치, 권한, 소유자, 실제 데이터 블록을 관리합니다. 컨테이너는 이 구조를 새로 발명하지 않습니다. host kernel과 파일시스템 위에서 컨테이너마다 다른 파일시스템 관점을 보여 주고, 그 관점 위에서 애플리케이션 프로세스를 실행합니다.
컨테이너 runtime은 image layer, writable layer, mount namespace, PID namespace, network namespace, cgroup을 조합합니다. 그래서 컨테이너 안에서 /app/artifacts/models/chapter_02_baseline.pkl이 보인다고 해도, 그것이 이미지에 포함된 파일인지, volume으로 mount된 파일인지, 실행 중 덮어쓴 파일인지는 별도로 확인해야 합니다. 이 구분이 모델 version 추적과 장애 분석의 출발점입니다.
운영자는 hierarchy를 다음 질문으로 바꿔 읽어야 합니다. 이 표는 컨테이너 내부 구현을 외우기 위한 표가 아니라, 모델 서빙 장애와 품질 추적에서 어디를 확인해야 하는지 분리하기 위한 표입니다.
| hierarchy | 운영에서 묻는 질문 | 모델 서빙에서의 의미 |
|---|---|---|
| File tree와 inode | 파일 위치, 권한, 소유자, mount 대상이 맞는가 | 모델 파일과 설정 파일을 실제로 읽을 수 있는지 확인 |
| Image layer | 어떤 코드, dependency, 모델 산출물이 image에 들어갔는가 | 배포 산출물의 내용과 모델 version 추적 |
| Writable layer | 실행 중 생성한 파일이 영구 저장되는가 | 예측 로그와 실패 샘플 보존 여부 |
| Namespace | 파일시스템, process, network view가 컨테이너별로 분리되는가 | 경로, port, process 상태 확인 |
| Cgroup | CPU, memory, process 제한과 OOM 상태를 볼 수 있는가 | latency 증가와 반복 restart 원인 확인 |
| Kubernetes hierarchy | Container가 Pod, Service, KServe resource와 어떻게 연결되는가 | endpoint와 runtime 상태 추적 |
이 hierarchy 관점은 Kubernetes와 KServe로 넘어갈 때 더 중요해집니다. 컨테이너는 Pod 안에서 실행되고, Pod는 Deployment나 KServe InferenceService가 관리하며, Service와 ingress는 네트워크 접근 경로를 만듭니다. 따라서 “컨테이너 하나가 잘 떴다”가 아니라 image layer, runtime 설정, Pod 상태, Service 경로, 로그 수집 경로가 같은 모델 버전과 threshold를 가리키는지 확인해야 합니다.
3-1-5. Layered filesystem과 writable layer¶
이미지 레이어는 컨테이너가 어떤 파일과 실행 의존성을 갖는지 설명하는 핵심 구조입니다. FROM, COPY, RUN 같은 Dockerfile 명령은 base image 위에 읽기 전용 layer를 순서대로 만들고, 컨테이너 실행 시에는 그 위에 쓰기 가능한 얇은 layer가 붙습니다. 이 구조 때문에 같은 Dockerfile이라도 어떤 파일을 어느 시점에 복사했는지, 어떤 dependency를 어느 layer에서 설치했는지가 운영 추적에 영향을 줍니다.
컨테이너는 여러 layer를 하나의 merged view로 보여 줍니다. 아래 layer에 있는 파일을 수정하면 파일 전체 또는 필요한 metadata가 위쪽 writable layer로 복사된 뒤 변경되고, 파일 삭제는 실제 아래 layer를 지우는 것이 아니라 위쪽 layer에 삭제 표시를 남기는 방식으로 처리됩니다. 그래서 컨테이너 내부에서 파일이 보이거나 사라졌다는 사실만으로 image 자체가 바뀌었다고 판단하면 안 됩니다.
AI 서빙에서는 모델 artifact와 로그 파일의 위치가 특히 중요합니다. 모델 파일은 image에 포함될 수도 있고, 실행 시 volume이나 object storage에서 주입될 수도 있습니다. 예측 이벤트 로그는 컨테이너 내부 writable layer에만 쓰면 재시작이나 replica 교체 때 사라질 수 있습니다. 4장에서 prediction distribution이나 score distribution을 비교하려면, 로그가 컨테이너 수명과 분리된 경로에 남아야 합니다.
Dockerfile을 읽을 때는 layer가 무엇을 고정하고 무엇을 runtime에 남기는지 확인해야 합니다. 아래 표의 항목을 확인하면 “이미지에 포함된 것”과 “컨테이너 실행 중 주입되거나 생성되는 것”을 분리할 수 있습니다.
| 확인 항목 | Dockerfile/실행 파일에서 보는 위치 | 운영 해석 |
|---|---|---|
| Base image | FROM python:3.11-slim |
Python runtime 기준 |
| Dependency layer | RUN uv sync --frozen |
dependency version 고정 |
| Model artifact | COPY artifacts/models/... 또는 mount |
모델 산출물 포함 방식 |
| Writable output | log path, artifact path | 재시작 후 증거 보존 여부 |
| Image identity | tag, digest, git commit | 실제 배포 산출물 추적 |
이 절에서 가능한 판단은 “모델 품질이 좋다”가 아니라 “모델 서빙 image가 어떤 파일과 dependency를 담고 있으며, 실행 중 생성되는 증거가 보존될 수 있는가”입니다. 이 판단이 있어야 뒤에서 MLflow 모델 URI, Argo CD manifest, KServe runtime을 같은 배포 후보로 연결할 수 있습니다.
3-1-6. Namespace 격리와 cgroup 제한¶
격리는 컨테이너가 가상 머신처럼 완전히 별도의 운영체제를 띄운다는 뜻이 아닙니다. 컨테이너는 host kernel을 공유하면서 namespace와 cgroup을 통해 파일시스템, process, network, resource 관점을 분리합니다. 따라서 운영에서는 “격리되어 있으니 안전하다”가 아니라, 어떤 관점이 분리되고 어떤 리소스가 제한되는지 확인해야 합니다.
Namespace는 컨테이너마다 다른 실행 관점을 만듭니다. mount namespace는 컨테이너 안에서 보이는 파일시스템 tree와 volume mount를 분리하고, PID namespace는 process tree를 분리해 컨테이너 안의 serving process를 PID 1처럼 보이게 합니다. network namespace는 port와 network interface 관점을 분리하므로, Dockerfile의 EXPOSE, compose의 ports, Kubernetes Service port가 서로 맞아야 외부 요청이 의도한 API로 들어갑니다.
Cgroup은 resource 사용량을 계층적으로 제한하고 관측합니다. CPU 제한이 너무 낮으면 latency가 증가할 수 있고, memory 제한이 너무 낮으면 모델 로딩이나 batch 요청 중 OOM kill이 발생할 수 있습니다. 컨테이너가 반복 restart되는 상황에서는 모델 코드만 보지 말고 exit code, restart count, OOM 여부, memory limit, readiness 상태를 함께 확인해야 합니다.
격리와 리소스 제한은 품질 지표와도 연결됩니다. 같은 모델이라도 컨테이너가 자주 재시작되거나 준비되지 않은 상태에서 요청을 받으면 latency, 실패율, prediction log 누락이 발생합니다. 운영 품질 보고서에는 모델 metric뿐 아니라 serving runtime이 안정적으로 요청을 처리했는지에 대한 증거가 필요합니다.
| 계층 | 확인 대상 | 문제가 있을 때 나타나는 현상 |
|---|---|---|
| Mount namespace | 모델 경로, 설정 mount, read-only mount | 모델 파일 mismatch, 설정 덮어쓰기 |
| PID namespace | serving process, PID 1, exit code | 서버가 죽었는데 container 상태 해석 혼동 |
| Network namespace | container port, service port, health endpoint | health check 실패, 요청 routing 실패 |
| Cgroup | CPU, memory, OOM, restart count | latency 증가, 반복 restart, 로그 누락 |
| Security context | non-root user, capability, read-only filesystem | 불필요한 권한과 운영 리스크 증가 |
이 절에서 가능한 판단은 “컨테이너가 격리된다”는 일반론이 아닙니다. 수강생은 컨테이너가 어떤 파일을 보고, 어떤 process를 실행하며, 어떤 port로 요청을 받고, 어떤 resource 제한 안에서 동작하는지 확인해야 합니다. 이 확인이 있어야 KServe 배포 후 Pod 상태와 endpoint 장애를 해석할 수 있습니다.
3-1-7. 운영에서 확인할 컨테이너 증거¶
컨테이너 운영 증거는 배포 산출물과 실행 상태를 연결하는 기록입니다. image tag만으로는 어떤 모델과 설정이 실행 중인지 충분히 설명할 수 없고, API 응답만으로는 어떤 image와 runtime 조건에서 나온 결과인지 설명하기 어렵습니다. 따라서 image identity, runtime environment, health, log, volume, resource 상태를 함께 남겨야 합니다.
AI 서빙에서는 MODEL_VERSION, MODEL_THRESHOLD, 모델 경로, request log가 핵심 증거입니다. 이 값들이 Dockerfile, compose, Kubernetes manifest, API 응답, structured log에서 서로 다르게 보이면 2장의 평가 metric과 3장의 serving 결과를 연결할 수 없습니다. 특히 latest tag만 사용하거나 threshold를 환경 변수로 덮어쓰면서 응답에 노출하지 않으면, 배포 후 결과 변화가 모델 때문인지 설정 때문인지 구분하기 어렵습니다.
운영 확인은 실행 전과 실행 후로 나누어야 합니다. 실행 전에는 image와 manifest가 의도한 파일과 설정을 담았는지 확인하고, 실행 후에는 health endpoint, predict response, event log, restart 상태가 같은 값을 노출하는지 확인합니다. 이 구분을 해야 “배포 파일은 맞지만 실행 중 설정이 다름” 같은 문제를 놓치지 않습니다.
| 시점 | 확인할 증거 | 보고서에 남길 수 있는 의미 |
|---|---|---|
| 실행 전 | Dockerfile, image tag/digest, model artifact path | 배포 후보가 어떤 모델과 dependency를 포함하는지 |
| 실행 시 | environment, volume, port, resource limit | runtime 설정이 평가 기준과 일치하는지 |
| 실행 후 | /health, /predict, event log, restart count |
실제 실행 중 모델 version과 threshold가 확인되는지 |
| 장애 시 | exit code, OOM 여부, latency, missing log | 모델 문제와 runtime 문제를 분리할 단서 |
이 절에서 가능한 판단은 “운영에서 추적 가능한 컨테이너인가”입니다. 증거가 부족하면 API가 정상 응답해도 품질 판단은 보류해야 합니다. 반대로 image identity, 모델 version, threshold, health, log가 이어지면 다음 절에서 동일 실행 환경 재현 여부를 더 구체적으로 확인할 수 있습니다.
3-1-8. 동일 실행 환경 재현¶
같은 모델 평가 결과를 서비스에서 재현하려면 학습과 평가에 사용한 특성, 예측 클래스 기준, 임계값, 모델 버전이 서빙 환경과 맞아야 합니다. 컨테이너는 이 정보를 실행 환경에 묶는 수단이지만, 모든 항목의 일치 여부를 자동으로 검증해 주지는 않습니다.
동일 실행 환경 재현은 “API가 실행된다”보다 더 넓은 의미입니다. API가 정상 응답을 반환하더라도 임계값이 평가 때와 다르거나, 모델 산출물이 다른 버전이거나, 특성 순서가 달라지면 품질이 달라질 수 있습니다. QA는 실행 성공과 품질 조건 일치를 구분해야 합니다.
| 재현 대상 | 확인 방법 |
|---|---|
| 코드 버전 | 이미지 태그, git commit, 배포 기록 |
| 모델 산출물 | 모델 경로(model path), 해시(checksum), 모델 버전 |
| 특성 목록 | configs/validation/model_features.yaml, API 스키마(schema) |
| 임계값 | MODEL_THRESHOLD, 응답의 threshold |
| 예측 클래스 기준 | low_risk, high_risk 기준 |
컨테이너는 QA가 동일 조건을 확인할 수 있도록 정보를 한곳에 모아 줍니다. 그러나 검증 항목을 응답이나 로그에 남기지 않으면 실제 운영에서 확인하기 어렵습니다. 그래서 실습 예측 응답에는 model_version, score, threshold, prediction, request_id를 포함합니다.
같은 확인은 실행 전후로 나누어 볼 수 있습니다. 실행 전에는 이미지에 어떤 모델 파일과 설정이 들어갔는지 확인하고, 실행 후에는 실제 API 응답과 로그가 같은 값을 노출하는지 확인합니다.
| 시점 | 확인 대상 | 판단 |
|---|---|---|
| 실행 전 | 이미지, 설정 파일, 모델 경로 | 의도한 산출물이 배포 단위에 포함되었는지 확인 |
| 실행 후 | /health, /predict 응답, 예측 이벤트 로그 |
실행 중인 컨테이너가 의도한 모델과 임계값을 사용하는지 확인 |
3-1-9. AI 서비스에서 컨테이너가 담는 것¶
실습 Dockerfile은 tta-aiqa 기준 demos/ch03_docker_kubernetes/Dockerfile에 있습니다. Dockerfile은 애플리케이션 코드, 설정 파일, 모델 산출물, 실행 명령을 이미지에 포함합니다.
Docker image 문서 관점에서 이미지는 실행에 필요한 파일과 설정을 담은 패키지입니다. QA는 이미지를 “배포 파일”로만 보지 말고, 어떤 모델과 설정이 함께 묶였는지 확인해야 합니다. 같은 코드라도 이미지에 포함된 모델 산출물이 다르면 API가 반환하는 점수와 예측은 달라질 수 있습니다.
| 구성 요소 | 예시 | 운영 확인 |
|---|---|---|
| 애플리케이션 코드 | packages/ai-quality/src/ai_quality |
예측 API와 공통 로직이 포함되었는지 |
| 설정 파일 | configs/operations/serving.yaml, configs/validation/model_metadata.yaml |
임계값과 모델 경로 기준이 맞는지 |
| 모델 산출물 | artifacts/models/chapter_02_baseline.pkl |
2장에서 만든 기준선 모델인지 |
| 실행 명령 | python -m ai_quality.serving.infrastructure.fastapi_app 또는 model server entrypoint |
의도한 serving process가 실행되는지 |
컨테이너에 무엇이 들어가는지 확인하는 것은 배포 전 QA의 기본입니다. 모델 산출물이 누락되면 API가 실행되지 않을 수 있고, 잘못된 산출물이 들어가면 API는 정상 응답을 주지만 2장에서 평가한 모델과 다른 기준으로 예측할 수 있습니다.
실제 운영 기준은 설정 파일과 환경 변수의 우선순위까지 확인해야 알 수 있습니다. configs/operations/serving.yaml에 임계값이 있어도 Docker 또는 Kubernetes에서 환경 변수로 덮어쓰면 실제 운영 임계값은 달라질 수 있습니다. QA는 파일에 적힌 값이 아니라 실행 중인 응답과 로그에 남는 값을 확인해야 합니다.