3-7. Kubernetes와 KServe 실행 구조¶
3-7 Demo의 판단은 Git에 선언된 배포 의도가 Kubernetes cluster 안에서 어떤 실행 상태로 바뀌는지 확인하는 것입니다. 3-6에서 Argo CD가 GitOps 배포 경로를 확인했다면, 여기서는 Kubernetes control plane이 원하는 상태(desired state)를 실제 상태(live state)에 맞추는 방식을 읽고, KServe InferenceService가 runtime container와 Pod readiness로 이어지는 구조를 확인합니다.
Kubernetes는 이 과정에서 운영 심화 과목이 아니라 cluster 운영체제처럼 읽는 배포 해석 도구입니다. 일반 운영체제가 한 서버 안에서 process, file, network, resource를 관리한다면, Kubernetes는 여러 Linux node 위에서 container workload, service network, configuration, secret, volume, health 상태를 API object로 관리합니다. 이 비유는 Kubernetes를 쉽게 이해하기 위한 출발점이며, 실제 Linux kernel을 대체한다는 뜻은 아닙니다.
Kubernetes가 OS 개념을 차용했다는 해석은 맞지만, 더 정확히는 “단일 host OS의 실행 관리 관심사를 분산 시스템 control plane으로 옮긴 것”입니다. 단일 Linux host에서는 kernel, filesystem, process scheduler, namespace, cgroup, network stack이 한 machine 안의 실행을 관리합니다. Kubernetes는 이 기능을 직접 다시 구현하지 않고, 각 node의 Linux와 container runtime 위에서 Pod를 실행하게 하며, cluster 전체의 상태 선언, 배치, 복구, 접근 경로, 설정 주입을 API와 controller loop로 관리합니다. 따라서 Kubernetes를 이해할 때는 “새로운 OS가 Linux를 대체한다”가 아니라 “Linux node들을 대상으로 운영체제적 관심사를 조율한다”로 읽어야 합니다.
Kubernetes를 이렇게 보는 이유는 QA 판단이 kubectl 명령 성공에서 끝나지 않기 때문입니다. 수강생은 “Argo CD가 sync했다”, “Kubernetes가 원하는 상태로 맞추고 있다”, “KServe endpoint가 Ready이다”, “모델 응답 계약이 확인됐다”를 분리해서 말할 수 있어야 합니다.
| 관점 | 쉽게 보면 | 실제 확인 대상 | 품질 판단 연결 |
|---|---|---|---|
| GitOps | 원하는 배포 상태의 원본 | repository, revision, path | 어떤 배포 의도를 기준으로 삼는가 |
| Kubernetes | cluster 운영체제 같은 control plane | spec, status, condition, event | 원하는 상태와 실제 상태가 가까워지는가 |
| KServe | ML serving용 Kubernetes 확장 | InferenceService, ServingRuntime |
모델 endpoint와 runtime이 준비되는가 |
| Runtime container | 실제 추론 프로세스 | Pod, image, model storage, readiness | 모델 로딩과 응답 가능 여부 |
| Observability | 실행 후 증거 | log, metric, request_id | 4장 운영 관측으로 넘길 수 있는가 |
3-7-1. Linux node와 OS 개념 대응¶
Kubernetes는 cluster 수준에서 실행 상태를 관리하는 control plane입니다. Kubernetes Overview는 Kubernetes를 containerized workload와 service를 관리하고 declarative configuration과 automation을 지원하는 platform으로 설명합니다. 이 과정에서는 그 설명을 “여러 Linux node에 흩어진 container 실행 상태를 API object로 선언하고 유지하는 운영 계층”으로 좁혀 읽습니다.
운영체제 비유는 초보자가 Kubernetes의 경계를 잡는 데 유용합니다. Linux kernel이 한 서버 안에서 process, filesystem, network, resource를 관리한다면, Kubernetes는 여러 Linux node 위에서 Pod, Service, ConfigMap, Secret, PersistentVolume, health condition을 관리합니다. 다만 Kubernetes는 kernel이 아니며 container 내부 syscall, namespace, cgroup을 직접 대체하지 않습니다. 실제 container는 여전히 node의 Linux kernel과 container runtime 위에서 실행됩니다.
Kubernetes가 OS에서 빌려온 개념은 실행, 격리, 파일, 네트워크, 자원 제어입니다. 그러나 Kubernetes는 이 기능을 kernel처럼 직접 수행하지 않고, Linux node와 container runtime이 수행할 수 있도록 선언과 조정을 맡습니다. 이 차이를 구분해야 “Kubernetes가 있으니 격리, 저장소, network가 자동으로 안전하다”는 잘못된 결론을 피할 수 있습니다.
| OS 개념 | 단일 Linux host | Kubernetes에서의 확장 | QA/운영 확인 |
|---|---|---|---|
| process | PID와 process tree | Pod 안의 container process | serving process가 Running/Ready인가 |
| filesystem | directory tree, inode, mount | image layer, volume, ConfigMap mount, Secret mount | 모델 artifact와 설정이 어느 mount에서 읽히는가 |
| isolation | namespace, cgroup | Pod 단위 network/process/resource 경계 | container가 필요한 port와 resource limit 안에서 실행되는가 |
| scheduling | CPU scheduler | scheduler가 Pod를 node에 배치 | 어떤 node에 배치됐고 Pending 이유가 무엇인가 |
| network | interface, routing, port | Pod IP, Service, ingress, CNI | 요청이 runtime Pod까지 도달하는가 |
| health | process exit, supervisor | readiness, liveness, condition, event | Ready 실패가 모델 로딩인지 설정 오류인지 구분되는가 |
분산 시스템이 되면서 단일 OS에는 없던 운영 문제가 추가됩니다. 여러 node 사이에는 네트워크 지연, node 장애, image pull 실패, storage 접근 실패, scheduler 제약, controller 재시도, 상태 전파 지연이 생깁니다. Kubernetes는 이런 문제를 “즉시 완벽한 상태”로 없애는 것이 아니라, 관측한 live state를 desired state에 가깝게 수렴시키는 방식으로 다룹니다.
| 분산 환경 문제 | Kubernetes가 다루는 방식 | 잘못 읽으면 생기는 오류 |
|---|---|---|
| node마다 resource와 상태가 다름 | scheduler와 kubelet이 배치와 실행을 분담 | manifest가 있으니 어느 node든 즉시 실행된다고 판단 |
| network와 storage가 원격 의존성을 가짐 | Service, CNI, volume plugin, event로 상태 노출 | Pod 생성만 보고 모델 파일 접근 성공으로 판단 |
| 상태가 즉시 일치하지 않음 | controller가 reconcile loop로 반복 조정 | sync 직후 Ready가 아니면 무조건 실패로 판단 |
| 장애가 부분적으로 발생함 | condition, event, restart count로 원인 후보 노출 | Ready만 보고 image, storage, probe 원인을 놓침 |
| 여러 controller가 같은 object를 조정함 | API object와 owner reference로 관계 관리 | Argo CD, KServe, Deployment 책임을 섞어 해석 |
QA/운영 관점에서는 OS 비유를 실행 증거 질문으로 바꿔야 합니다. “Kubernetes가 있으니 운영 준비가 끝났다”가 아니라, 어떤 object가 어떤 Linux node 위에서 실행되고, 어떤 파일과 설정을 읽고, 어떤 network endpoint로 요청을 받는지 확인합니다.
| OS 비유 | Kubernetes object | QA가 확인할 질문 |
|---|---|---|
| process 실행 | Pod | 어떤 container image가 실제로 실행되는가 |
| process 개수 유지 | Deployment, ReplicaSet | 원하는 replica와 live replica가 맞는가 |
| network endpoint | Service, ingress | 요청이 의도한 Pod로 들어가는가 |
| 환경 설정 | ConfigMap, Secret | MODEL_VERSION, MODEL_THRESHOLD가 어디서 주입되는가 |
| 상태와 event | status, condition, event | Ready가 왜 실패하거나 지연되는가 |
이 절에서 가능한 판단은 Kubernetes가 Linux node 위의 실행, 격리, 파일, 네트워크, resource 개념을 cluster object로 표현한다는 점입니다. 수강생은 Pod, Service, ConfigMap을 암기 대상이 아니라 모델 serving 상태를 설명하는 증거로 읽어야 합니다.
3-7-2. 상태 저장과 reconcile loop¶
Kubernetes의 핵심은 상태 저장, API 제공, reconcile loop의 분리입니다. 상태 저장소는 etcd이고, 사용자는 보통 etcd에 직접 접근하지 않고 API server를 통해 Kubernetes object를 읽고 씁니다. controller는 API server가 제공하는 object 상태를 관측하고, spec에 담긴 desired state와 status에 드러난 live state의 차이를 줄이는 reconcile loop를 반복합니다.
API server는 Kubernetes control plane의 관문입니다. 사용자가 manifest를 제출하면 API server는 인증, 권한, admission, schema 검증을 거쳐 object를 받아들이고, cluster 상태를 etcd에 저장합니다. kubectl get, kubectl describe, Argo CD, controller, scheduler, kubelet도 모두 API server를 통해 object를 읽고 상태 변경을 보고합니다. 따라서 “API server가 상태를 제공한다”는 말은 API server가 etcd에 저장된 cluster state를 Kubernetes API로 노출하고 검증된 변경 경로를 제공한다는 뜻입니다.
etcd는 cluster object의 일관된 저장소입니다. Pod, Deployment, Service, ConfigMap, Secret, KServe InferenceService 같은 object의 원하는 상태와 관측 상태가 이 저장 계층을 통해 추적됩니다. 실무자가 etcd를 직접 다루는 시간은 많지 않지만, cluster 상태 주장을 할 때는 “어떤 object가 API server를 통해 저장되고 관측되는가”를 이해해야 합니다.
Controller는 Kubernetes가 단발성 명령 실행기가 아니라 계속 상태를 맞추는 시스템이라는 점을 보여 줍니다. controller는 API server를 watch하면서 원하는 상태와 현재 상태의 차이를 찾고, 필요한 object 생성, 수정, 삭제 요청을 다시 API server에 보냅니다. 예를 들어 Deployment controller는 원하는 replica 수와 live Pod 수를 비교하고, KServe controller는 InferenceService 선언을 보고 predictor와 runtime 준비 상태를 맞춥니다.
| 구성요소 | 맡는 일 | QA/운영에서 읽을 증거 |
|---|---|---|
| API server | Kubernetes API 제공, object 검증, 상태 변경 관문 | manifest 적용 여부, object spec, status, event 조회 |
etcd |
cluster object 상태 저장 | object resourceVersion, 상태 변화가 보존되는 계층 |
| scheduler | 아직 node가 정해지지 않은 Pod 배치 | Pod nodeName, Pending event, resource 부족 원인 |
| controller | desired state와 live state 차이를 reconcile | replica 변화, condition, owner reference, reconcile event |
| kubelet | 각 node에서 Pod 실행 상태를 맞춤 | Pod Running, Ready, restart count, node event |
Desired state와 live state는 이 구조를 읽는 운영 언어입니다. manifest의 spec은 사용자가 원하는 상태를 담고, status, condition, event는 control plane과 node가 관측한 현재 상태를 보여 줍니다. Kubernetes controller 문서는 controller가 cluster state를 관측하고 필요한 변경을 수행해 현재 상태를 원하는 상태에 가깝게 만든다고 설명합니다.
이 차이는 GitOps와 직접 연결됩니다. Git repository에는 원하는 배포 상태가 있고, Argo CD는 Git의 desired state와 cluster live state를 비교합니다. Kubernetes control plane은 API server, etcd, scheduler, controller, kubelet을 통해 실제 Pod와 Service 상태를 조정합니다. 따라서 배포 확인은 한 번의 명령 결과가 아니라 Git desired state, Kubernetes API state, controller reconcile, KServe readiness의 연결입니다.
| 단계 | 원하는 상태 | live 확인 | 해석 |
|---|---|---|---|
| Git | KServe manifest가 candidate model을 가리킴 | Argo CD diff, sync revision | 배포 의도가 Git에 기록됨 |
| Kubernetes API | InferenceService, Pod, Service spec 생성 |
object status, condition | API server가 object를 인식하고 저장함 |
| Controller reconcile | desired/live 차이 조정 | condition, owner reference, event | control loop가 상태를 맞추는 중임 |
| Scheduler와 node | runtime Pod 배치 | Pod Pending, Running, Ready | 실행 위치와 준비 상태 확인 |
| Endpoint | 요청 가능 상태 | /predict, log, metric |
실제 응답 계약 확인 |
QA가 확인할 것은 control plane 내부를 운영하는 방법이 아니라 상태 차이를 읽는 방법입니다. kubectl get으로 Ready만 보는 것이 아니라, describe와 event를 통해 왜 NotReady인지, image pull인지, storage인지, readiness probe인지, resource 부족인지 확인해야 합니다.
이 비유가 깨지는 지점도 명확히 알아야 합니다. Kubernetes는 분산 filesystem을 자동으로 제공하지 않고, 애플리케이션 데이터 일관성을 보장하지 않으며, 모델 응답 계약을 자동으로 검증하지도 않습니다. Kubernetes는 “어떤 container를 어디서 실행하고 어떤 상태로 유지할지”를 관리하는 계층이고, 모델 품질과 응답 의미는 MLflow 기록, API 계약, 로그, metric으로 따로 확인해야 합니다.
| Kubernetes가 해 주는 것 | Kubernetes만으로 보장되지 않는 것 | 추가 확인 |
|---|---|---|
| Pod 실행과 재시작 | 모델 파일이 올바른 후보 버전인지 | MLflow alias, storage URI |
| Service endpoint 제공 | /predict 응답 schema가 과정 기준과 맞는지 |
API contract test |
| ConfigMap/Secret 주입 | 설정값이 응답과 로그에 남는지 | response field, structured log |
| readiness condition 노출 | 예측 분포가 기존 기준에서 벗어났는지 | Grafana dashboard, metric |
| event 기록 | 배포 승인 또는 보류 판단 | 5장 release evidence |
이 절에서 가능한 판단은 “manifest가 있다”와 “live 상태가 준비됐다”를 분리하는 것입니다. cluster evidence가 없으면 보고서에는 prepared artifact inspection이라고 쓰고, live deployment verified라고 쓰지 않습니다.
3-7-3. Argo CD, Kubernetes, KServe 역할 분리¶
Argo CD, Kubernetes, KServe는 같은 배포 흐름에 있지만 책임이 다릅니다. Argo CD는 Git과 cluster state를 비교하고 sync합니다. Kubernetes는 object lifecycle과 workload 실행 상태를 관리합니다. KServe는 Kubernetes 위에서 ML serving resource를 제공하고, model format에 맞는 runtime을 연결합니다.
이 분리가 중요한 이유는 성공 조건이 서로 다르기 때문입니다. Argo CD sync 성공은 Git의 manifest가 cluster에 반영됐다는 뜻입니다. Kubernetes Pod Ready는 runtime container가 실행 준비 상태라는 뜻입니다. KServe InferenceService Ready는 serving resource가 endpoint로 준비됐다는 뜻입니다. /predict 응답과 log 확인은 모델 응답 계약이 실제로 관측됐다는 뜻입니다.
| 계층 | 맡는 일 | 확인할 것 | 잘못된 결론 |
|---|---|---|---|
| Git repository | 원하는 배포 파일 저장 | commit, path, manifest | Git에 있으니 live 배포 완료 |
| Argo CD | Git 파일과 cluster 상태 비교 및 sync | sync status, diff, revision | sync 성공이 inference 성공 |
| Kubernetes | resource 생성과 상태 유지 | namespace, event, Pod, Service | Pod 생성이 모델 응답 정상 |
| KServe | model serving resource 관리 | InferenceService, predictor, runtime, readiness |
Ready가 품질 정상 |
| model server runtime | 실제 모델 로딩과 추론 | sklearnserver, MLServer, Triton, custom runtime | runtime 선택이 response contract 보장 |
이 역할 분리는 5장의 release 판단까지 이어집니다. 보고서에는 어느 계층까지 확인했는지 명시해야 합니다. 예를 들어 “Argo CD Application과 KServe manifest는 candidate model을 가리키지만, live cluster sync와 /predict 응답은 미확인입니다”처럼 범위를 제한해야 합니다.
3-7-4. InferenceService에서 Pod까지 이어지는 경로¶
KServe InferenceService는 모델 serving 의도를 선언하는 Kubernetes custom resource입니다. 이 resource는 predictor를 필수로 가지며, 필요한 경우 transformer와 explainer를 붙일 수 있습니다. KServe controller는 이 선언을 읽고 model format과 runtime 설정을 바탕으로 serving runtime을 연결합니다.
이번 과정의 기본 manifest는 scikit-learn 후보 모델을 가리킵니다. 여기서 중요한 것은 YAML 문법을 외우는 것이 아니라, MLflow alias와 model storage URI가 serving runtime으로 연결되는지 확인하는 것입니다.
| 필드 | 예시 | 의미 |
|---|---|---|
kind |
InferenceService |
KServe controller가 처리할 serving 선언 |
metadata.labels.ai-quality/model-alias |
candidate |
후보 모델 endpoint임 |
metadata.annotations.ai-quality/mlflow-model-uri |
models:/risk-classifier@candidate |
MLflow Registry와 배포 manifest 연결 |
spec.predictor.sklearn.protocolVersion |
v2 |
inference protocol 의도 |
spec.predictor.sklearn.storageUri |
pvc://ai-quality-models/risk-classifier/candidate |
runtime이 읽을 모델 저장 위치 |
이 manifest는 추상화만 잘한 파일이 아닙니다. KServe controller가 이 선언을 읽고 지원 runtime을 선택하며, 해당 runtime container가 모델을 로딩합니다. 이때 storage URI, runtime image, resource, readiness 조건 중 하나라도 맞지 않으면 Argo CD sync가 성공해도 endpoint는 준비되지 않을 수 있습니다.
3-7-5. ServingRuntime과 내부 엔진¶
KServe의 내부 엔진은 하나로 고정되어 있지 않습니다. ServingRuntime은 어떤 container image가 어떤 model format을 지원하는지 정의합니다. sklearn 모델이면 sklearnserver 또는 MLServer 계열 runtime이 후보이고, ONNX나 TensorRT 모델이면 Triton runtime이 후보가 됩니다.
| 모델 또는 요구 | runtime 후보 | 이번 과정 적용 |
|---|---|---|
| scikit-learn Tree 모델 | kserve-sklearnserver, MLServer |
기본 실습 후보 |
| ONNX, TensorRT, 고처리량 GPU inference | Triton | 비교 후보 |
| PyTorch serving | TorchServe 또는 custom runtime | Mention |
| LLM serving | vLLM runtime | 이번 모델에는 적용하지 않음 |
| custom response field | transformer 또는 custom predictor | score/threshold/request_id 보강 필요 |
따라서 “KServe로 배포한다”는 말은 “KServe가 직접 모든 추론 로직을 한다”는 뜻이 아닙니다. KServe는 Kubernetes resource lifecycle과 serving 추상화를 맡고, 실제 inference는 runtime container가 수행합니다. 이 구분을 해야 KServe를 단순 추상화 계층으로만 오해하지 않습니다.
3-7-6. Built-in runtime의 한계¶
Built-in sklearn runtime은 모델 inference에는 유용하지만, 과정에서 필요한 운영 응답 필드를 자동으로 보장하지 않습니다. request_id, model_version, score, threshold, prediction, latency, validation_failure가 필요하면 transformer 또는 custom predictor가 필요할 수 있습니다.
| 요구 | built-in runtime만으로 충분한가 | 보강 위치 |
|---|---|---|
| raw prediction | 대체로 가능 | predictor |
| threshold 적용 | 모델 artifact 설계에 따라 다름 | transformer 또는 custom predictor |
request_id 생성/전파 |
별도 구현 필요 | transformer/API gateway |
| custom response field | 별도 구현 필요 | transformer 또는 custom predictor |
| structured log emission | 별도 구현 필요 | wrapper, transformer, sidecar, telemetry layer |
이 한계는 KServe를 쓰지 말자는 뜻이 아닙니다. KServe를 제대로 쓰려면 추상화와 실제 runtime 책임을 분리해서 설계해야 한다는 뜻입니다. 운영 응답 계약이 중요하면 built-in runtime만 쓸지, transformer를 붙일지, custom predictor를 만들지 선택해야 합니다.
3-7-7. 실행 확인 경로와 evidence 경계¶
KServe가 준비된 cluster에서는 Argo CD sync 후 Kubernetes resource 상태를 확인합니다. 준비되지 않은 환경에서는 manifest와 runtime 구조를 inspection하고 실제 endpoint 확인은 미확인으로 둡니다.
kubectl get inferenceservice ai-quality-risk-classifier-dev -n ai-quality
kubectl describe inferenceservice ai-quality-risk-classifier-dev -n ai-quality
kubectl get pods -n ai-quality
| 확인 대상 | 확인할 값 | 보고서 의미 |
|---|---|---|
InferenceService |
Ready, URL, predictor condition | KServe serving resource 준비 여부 |
| Pod | Running, Ready | runtime container 실행 여부 |
| Events | storage download, runtime error, readiness 실패 | NotReady 원인 후보 |
| URL | inference endpoint | smoke test 가능 여부 |
이 결과는 4장 운영 관측으로 넘어가는 전제입니다. KServe readiness가 없으면 endpoint 로그와 메트릭을 정상적으로 기대하기 어렵습니다. 반대로 manifest inspection만 완료했다면 “배포 의도는 확인했지만 live readiness는 미확인”이라고 남겨야 합니다.