콘텐츠로 이동
Study Notekagent 실습

1. 전용 cluster와 kagent 설치

결론부터
설치 성공은 dashboard가 열린 순간이 아니라 전용 context에서 pinned CRD·control plane·model 연결이 함께 준비된 상태다
이 장에서 처음 나오는 말4개
demo profileDemo Installation Profile
학습용 sample Agent와 MCP tool을 함께 설치하는 kagent profile이다.
CRDCustom Resource Definition
Agent·ModelConfig 같은 새 Kubernetes resource type의 schema다.
contextkubectl Context
cluster·user·namespace 연결을 가리키는 kubectl 대상 이름이다.
Helm release
chart와 values로 설치한 Kubernetes resource 묶음과 upgrade 이력을 가리킨다.

Docker·kind·kubectl은 kind 실습 환경의 운영체제별 탭을 먼저 따른다. 이어서 공통 도구인 Helm CLI를 준비한다. 이 장은 kagent 전용인 CLI 설치부터 맡는다.

터미널 창
docker info
kind version
kubectl version --client
helm version

확인 당시 kagent 공식 설치 문서의 기본 CLI release는 0.9.9다. 출력이 다르면 실패는 아니지만 이 덱의 CR 예시와 맞는지 release notes를 먼저 본다.

kagent 공식 설치 문서의 Homebrew 경로를 사용한다.

터미널 창
brew install kagent
kagent version

이미 설치되어 있다면 다음 명령으로 갱신하고 version을 다시 확인한다.

터미널 창
brew upgrade kagent
kagent version
  1. 전용 kind cluster를 만든다

    터미널 창
    kind create cluster --name kagent-lab --wait 5m
  2. 현재 context를 문자열로 확인한다

    터미널 창
    kubectl config current-context

    기대값은 정확히 kind-kagent-lab이다. 다르면 다음 명령으로 바꾼 뒤 다시 확인한다.

    터미널 창
    kubectl config use-context kind-kagent-lab
  3. 사내 TLS 검사 프록시를 쓴다면 kind 노드에 CA trust를 먼저 설정한다

    이미지 pull에서 x509: certificate signed by unknown authority가 발생하는 환경은 사내 프록시의 CA를 신뢰시키는 절차를 모든 노드에 적용한다. 클러스터 생성 후, kagent workload를 설치하기 전인 지금 실행한다.

  4. 선택한 API key가 현재 shell에 있는지만 확인한다

    OpenAI 직접 연결은 OPENAI_API_KEY를 그대로 쓴다. LiteLLM 경로에서는 kagent installer의 provider 입력 계약을 통과하도록 virtual key를 설치 순간에만 같은 이름으로 연결한다. 이것만으로 endpoint가 바뀌지는 않으며, 설치 뒤 아래 OpenAI 대신 사내 LiteLLM 연결하기 절에서 ModelConfig의 Secret 참조와 baseUrl을 반드시 바꾼다.

    터미널 창
    if test -n "$LITELLM_API_KEY" && test -z "$OPENAI_API_KEY"; then
    export OPENAI_API_KEY="$LITELLM_API_KEY"
    fi
    test -n "$OPENAI_API_KEY" && echo "OPENAI_API_KEY is set"

    아무 key도 없다면 0장의 비밀과 비용 경계로 돌아가 두 경로 중 하나를 먼저 준비한다.

  5. 학습용 demo profile을 설치한다

    터미널 창
    kagent install --profile demo

    이 명령은 현재 Kubernetes context를 대상으로 한다. 실행 직전에 context를 확인한 이유다.

kagent install은 설치를 별도로 구현하지 않고 host의 helm executable로 다음 두 release를 upgrade --install한다. demo profile은 CLI에 내장된 values를 두 번째 release에 전달한다.

kagent-crds → Agent·ModelConfig·MCP 관련 CRD
kagent → controller·UI·DB·default ModelConfig·sample Agent와 tool

실제 Helm 소유권과 이력을 확인한다.

터미널 창
helm -n kagent list
helm -n kagent status kagent
helm -n kagent status kagent-crds
helm -n kagent history kagent

설치 성공 문장만 믿지 않고 실제 resource를 본다.

터미널 창
kubectl get crd | grep kagent.dev
kubectl -n kagent get pods
kubectl -n kagent get svc
kubectl -n kagent get modelconfig

CRD 목록에는 agents.kagent.dev, modelconfigs.kagent.dev 같은 type이 있고, kagent namespace의 control plane Pod는 시간이 지나면 Running·ready가 된다. default-model-config가 있어야 뒤 장의 Agent가 참조할 수 있다.

터미널 창
kagent dashboard

CLI가 port-forward를 열고 로컬 주소를 출력한다. 포트 번호를 외우지 말고 CLI가 이번 실행에 출력한 주소를 사용한다.

어느 경로든 port-forward가 실행 중인 terminal을 유지한 채 dashboard에서 sample Agent와 tool 목록을 둘러본다. 종료는 Ctrl+C다.

OpenAI API를 직접 쓸 수 없다면 2장의 첫 호출 전에 이 절을 수행한다. kagent에는 LiteLLM 전용 provider를 지정하는 대신 OpenAI-compatible provider와 openAI.baseUrl을 조합한다.

sample/custom Agent → default-model-config → 사내 LiteLLM /v1 → 허용된 upstream model

이 kind 실습에서는 demo Agent들이 공유하는 default-model-config를 한 번 바꿔 모두 같은 gateway를 보게 한다.

  1. 0장에서 준비한 세 입력이 현재 shell에 있는지 확인한다

    터미널 창
    test -n "$LITELLM_API_KEY" || echo "missing: LITELLM_API_KEY"
    test -n "$LITELLM_BASE_URL" || echo "missing: LITELLM_BASE_URL"
    test -n "$LITELLM_MODEL" || echo "missing: LITELLM_MODEL"
    case "$LITELLM_BASE_URL" in
    https://*) echo "LiteLLM uses HTTPS" ;;
    *) echo "refusing non-HTTPS LiteLLM URL"; exit 1 ;;
    esac

    아무것도 출력되지 않아야 한다. missing이 보이면 0장의 비밀과 비용 경계로 돌아가 그 변수부터 다시 설정한다. 새 terminal에는 이전 shell의 변수가 전달되지 않았다는 점도 함께 확인한다.

  2. kagent보다 먼저 gateway 자체를 확인한다

    조직 CA가 OS trust store에 있거나 public CA를 쓰면 기본 검증으로 호출한다.

    터미널 창
    curl --fail --silent --show-error \
    -H "Authorization: Bearer $LITELLM_API_KEY" \
    "$LITELLM_BASE_URL/models" | grep -o '"id":"[^"]*"'

    private CA가 OS trust store에 없다면 LITELLM_CA_FILE을 PEM 경로로 정하고 명시적으로 검증한다.

    터미널 창
    test -f "$LITELLM_CA_FILE"
    curl --fail --silent --show-error --cacert "$LITELLM_CA_FILE" \
    -H "Authorization: Bearer $LITELLM_API_KEY" \
    "$LITELLM_BASE_URL/models" | grep -o '"id":"[^"]*"'

    목록에 $LITELLM_MODEL과 같은 이름이 있어야 한다. 여기서 실패하면 kagent 설정 문제가 아니라 URL·virtual key·network·trust chain 문제이므로 gateway 쪽을 먼저 해결한다. curl -k로 우회하지 않는다.

  3. virtual key를 담는 별도 Secret을 만든다

    같은 명령을 다시 실행해도 해당 key만 갱신되는 형태다.

    터미널 창
    kubectl -n kagent create secret generic kagent-litellm \
    --from-literal=LITELLM_API_KEY="$LITELLM_API_KEY" \
    --dry-run=client -o yaml | kubectl apply -f -
  4. 바꾸기 전의 default-model-config를 먼저 읽는다

    터미널 창
    kubectl -n kagent get modelconfig default-model-config -o yaml

    Helm이 만든 기본값은 provider OpenAI, 공개 OpenAI model 이름, 설치 때 OPENAI_API_KEY 값으로 만든 Secret 참조다. openAI.baseUrl이 없으면 public endpoint를 뜻한다. 다음 patch는 이 중 provider 골격은 그대로 두고 Secret 참조·model·endpoint 세 값을 바꾼다.

  5. Secret 참조·model·endpoint를 한 번에 바꾼다

    shell 변수에는 key가 아니라 URL과 공개 model alias만 들어간다.

    터미널 창
    kubectl -n kagent patch modelconfig default-model-config --type merge \
    -p "{\"spec\":{\"apiKeySecret\":\"kagent-litellm\",\"apiKeySecretKey\":\"LITELLM_API_KEY\",\"provider\":\"OpenAI\",\"model\":\"${LITELLM_MODEL}\",\"openAI\":{\"baseUrl\":\"${LITELLM_BASE_URL}\"}}}"
    필드값의미
    providerOpenAI 유지LiteLLM 전용 provider가 없어 OpenAI-compatible 계약을 그대로 쓴다
    apiKeySecret·apiKeySecretKeykagent-litellm의 LITELLM_API_KEYHelm이 만든 Secret 대신 방금 만든 Secret을 참조한다
    modelLiteLLM 공개 aliasgateway가 허용한 upstream으로 routing되는 이름이다
    openAI.baseUrl사내 /v1 주소요청이 public OpenAI가 아니라 gateway로 가게 하는 핵심이다

    private CA를 쓰는 경우 같은 namespace에 CA bundle을 Secret으로 만들고 ModelConfig.spec.tls를 추가한다.

    터미널 창
    kubectl -n kagent create secret generic litellm-ca \
    --from-file=ca.crt="$LITELLM_CA_FILE" \
    --dry-run=client -o yaml | kubectl apply -f -
    kubectl -n kagent patch modelconfig default-model-config --type merge \
    -p '{"spec":{"tls":{"caCertSecretRef":"litellm-ca","caCertSecretKey":"ca.crt"}}}'

    public CA 또는 node의 system CA를 신뢰하면 이 tls block은 필요 없다. disableVerify: true는 production 대안이 아니며 이 실습에서도 사용하지 않는다.

  6. 설정값과 영향받는 Agent를 확인한다

    Secret 값은 출력하지 않는다.

    터미널 창
    kubectl -n kagent get modelconfig default-model-config \
    -o jsonpath='{.spec.provider}{"\t"}{.spec.model}{"\t"}{.spec.openAI.baseUrl}{"\n"}'
    kubectl -n kagent get agents \
    -o custom-columns='AGENT:.metadata.name,TYPE:.spec.type,MODEL_CONFIG:.spec.declarative.modelConfig'
    kubectl -n kagent get pods

    default-model-config를 참조한 Agent는 모두 같은 변경의 영향을 받는다. control plane과 Agent Pod가 Running·ready로 돌아오는지 본다.

여기까지가 이 절의 검증 범위다 — 설정값과 gateway 연결까지 확인했고, model 호출을 통한 최종 검증은 2장의 첫 호출이 맡는다. LiteLLM의 model alias 뒤 upstream은 function/tool calling과 tool_choice: auto를 지원해야 한다. kagent는 사용자 tool을 하나도 넣지 않아도 built-in tool을 포함한 요청을 보낼 수 있다.

설치 단계에서 OPENAI_API_KEY로 연결한 alias는 installer 입력용이었을 뿐이고, 이제 kagent는 kagent-litellm Secret을 읽는다. 설치 때 그 값으로 만들어진 기존 Secret에는 virtual key 사본이 남아 있지만 참조가 끊긴 상태이므로 실습에서는 그대로 두어도 된다. shell의 alias가 더 필요 없다면 unset OPENAI_API_KEY로 해제한다.

UI에서 LiteLLM model 목록 가져오기

섹션 제목: “UI에서 LiteLLM model 목록 가져오기”

LiteLLM 경로라면 이 절까지가 기본 절차다. 이후 장은 dashboard에서 실제 사용자 흐름을 따라가는데, UI의 model 입력은 목록 선택이어서 discovery를 준비해 두지 않으면 UI에서 새 ModelConfig를 만들 수 없다. dashboard의 Models → New Model은 ModelConfig 생성 화면이다. Custom parameters는 첫 화면에 바로 보이는 것이 아니라 provider와 model을 모두 선택한 뒤 나타난다. OpenAI provider에서는 그 안의 baseUrl에 LiteLLM /v1 주소를 넣는다.

LiteLLM의 /v1/models를 그 목록으로 쓰려면 provider discovery를 한 번 bootstrap한다. ModelProviderConfig의 Secret은 정확히 data key 하나만 가져야 하므로 앞의 kagent-litellm Secret을 그대로 참조할 수 있다.

터미널 창
kubectl apply -f - <<EOF
apiVersion: kagent.dev/v1alpha2
kind: ModelProviderConfig
metadata:
name: company-litellm
namespace: kagent
spec:
type: OpenAI
endpoint: ${LITELLM_BASE_URL}
secretRef:
name: kagent-litellm
EOF
터미널 창
kubectl -n kagent get modelproviderconfig company-litellm -o yaml

이후 UI에서 Configured Providers → company-litellm → Fetch Models → model 선택 순서로 간다. model을 선택하면 Custom parameters가 나타난다. v0.9.9 UI에서는 discovery에 쓴 endpoint와 credential을 새 ModelConfig에 자동 복사하지 않으므로 API key를 다시 입력하고 baseUrl도 명시한다.

이 덱의 사내 gateway는 https endpoint를 전제한다. private CA라면 앞에서 만든 ModelConfig.spec.tls.caCertSecretRef·caCertSecretKey로 검증하고, system CA만 쓰는 경우와 구분한다 — 공식 BYO OpenAI-compatible 문서에 같은 경계가 있다.

증상확인
설치가 엉뚱한 cluster를 가리킴즉시 중단하고 kubectl config current-context 확인
Pod가 Pendingkubectl -n kagent describe pod <이름>의 Events와 메모리
ImagePullBackOffPod Events, registry 접근, proxy·DNS
model config가 없음kagent install 출력과 controller log
LiteLLM model 목록이 비어 있음ModelProviderConfig condition, /v1/models, key scope와 DNS
LiteLLM 호출이 400공개 model alias와 upstream의 tool calling 지원
dashboard가 안 열림kubectl ... get svc, UI Pod log, 로컬 포트 충돌

설치 문제가 남으면 공식 debug 절의 첫 상태를 모은다.

터미널 창
kubectl -n kagent logs deployment/kagent-controller --tail=100
  • kubectl config current-context가 kind-kagent-lab이다.
  • kagent CRD, control plane Pod, default-model-config를 확인했다.
  • LiteLLM을 선택했다면 gateway /models 응답에서 model alias를 봤고, default-model-config의 model·baseUrl과 참조 Agent를 확인했다.
  • LiteLLM을 선택했다면 ModelProviderConfig를 만들었고 UI Fetch Models에서 model 목록을 봤다.
  • kagent와 kagent-crds가 Helm release라는 것을 확인했다.
  • dashboard에서 sample Agent를 볼 수 있다.
  • cluster는 지우지 않는다. 다음 장에서 그대로 쓴다.