콘텐츠로 이동
Study Notekagent · kmcp

실사용 설치 구성

결론부터
  • 설치는 Helm chart 두 개다. kagent-crds를 먼저, kagent를 다음에 올리고 업그레이드도 같은 순서로 한다.
  • 기본 설치는 평가용이다. 예제 Agent와 클러스터 조작 tool, 내장 PostgreSQL, 인증 없는 controller가 함께 올라온다.
  • 운영 구성에서는 예제를 끄고, 감시 namespace를 좁히고, 외부 PostgreSQL을 쓰고, 인증 모드와 image 경로를 명시한다.
  • chart 버전은 고정한다. 문서는 최신 release만 지원하고 API가 alpha라 버전 사이에 값이 바뀐다.
이 장에서 처음 나오는 말4개
Helm chart
Kubernetes manifest 묶음과 그 설정값(values)을 함께 배포하는 package다. values 파일로 설치 내용을 바꾼다.
leader election
같은 controller를 여러 개 띄웠을 때 하나만 실제 작업을 하도록 뽑는 방식이다. 나머지는 대기하다가 장애 시 넘겨받는다.
migrationDatabase Migration
버전이 바뀔 때 DB table 구조를 새 버전에 맞게 고치는 작업이다.
pgvector
PostgreSQL에 vector 검색을 추가하는 extension이다. kagent의 memory 기능이 사용한다.

kagent install --profile demo 한 줄이면 kagent가 올라온다. 평가에는 충분하지만 그 상태 그대로 임직원에게 열면 문제가 생긴다. 이 페이지는 기본 설치가 무엇을 올리는지와 운영에 가까운 구성에서 무엇을 바꾸는지를 정리한다. 설치 명령 자체는 공식 설치 문서를 따른다.

chart내용순서
kagent-crdsCRD 정의 (Agent, ModelConfig, RemoteMCPServer, kmcp의 MCPServer 등)먼저
kagentcontroller, UI, kmcp controller, PostgreSQL, 예제 Agent와 tool다음

CRD를 분리한 이유는 수명이 다르기 때문이다. CRD를 지우면 그 종류의 리소스가 전부 지워지므로, 본체 chart를 지우거나 다시 설치해도 CRD와 Agent 리소스는 남게 한다. 업그레이드도 kagent-crds → kagent 순서다.

터미널 창
# 설치된 release와 버전 확인
helm list -n kagent
kagent version
기본값평가에서는운영에서는 문제가 되는 이유
예제 Agent 여러 개 (k8s-agent, helm-agent, istio-agent 등)바로 써 볼 수 있다우리 catalog에 없는 Agent가 호출 주소를 갖는다
kagent-tools (Kubernetes·Helm 등 클러스터 조작 tool)예제 Agent가 사용한다Agent에 클러스터 조회·변경 능력을 주는 서버가 떠 있다
내장 PostgreSQL (postgres:18)외부 준비 없이 동작데모용 단일 instance. pgvector가 없다
controller.auth.mode: unsecure로그인 없이 UI 사용요청의 X-User-Id를 그대로 믿는다
모든 namespace 감시, cluster 범위 RBAC어디에 만들어도 동작controller의 권한과 영향 범위가 클러스터 전체다
default-model-config 생성모델이 바로 연결된다Git으로 관리하는 ModelConfig와 원본이 둘이 된다

아래는 영역별로 발췌한 values다. 한 파일로 합쳐 쓰되, 각 값이 대상 버전의 chart에 있는지 helm show values oci://ghcr.io/kagent-dev/kagent/helm/kagent --version <버전>으로 먼저 확인한다.

k8s-agent: { enabled: false }
helm-agent: { enabled: false }
istio-agent: { enabled: false }
kgateway-agent: { enabled: false }
promql-agent: { enabled: false }
observability-agent: { enabled: false }
argo-rollouts-agent: { enabled: false }
cilium-debug-agent: { enabled: false }
cilium-manager-agent: { enabled: false }
cilium-policy-agent: { enabled: false }
grafana-mcp: { enabled: false }
kagent-tools: { enabled: false }
providers: null

kagent-tools는 운영용 Agent(클러스터 진단 등)를 실제로 쓸 때만 켠다. 켠다면 그 tool을 가리킬 수 있는 namespace를 allowedNamespaces로 좁힌다. providers: null은 기본 ModelConfig 생성을 끈다.

rbac:
namespaces:
- kagent # 설치 namespace는 반드시 포함
- agents

rbac.namespaces가 비어 있으면 chart는 ClusterRole을 만들고 controller가 모든 namespace를 감시한다. 목록을 주면 namespace마다 Role을 만들고 감시 범위도 그 목록으로 줄어든다 (RBAC scope). 목록에 설치 namespace가 없으면 chart가 실패한다.

database:
postgres:
bundled:
enabled: false
urlFile: /var/secrets/db-url
vectorEnabled: false # memory 기능을 쓸 때만 true (pgvector 필요)
sessionRetentionDays: 90
controller:
replicas: 2
volumes:
- name: db-secret
secret:
secretName: kagent-postgres-url
volumeMounts:
- name: db-secret
mountPath: /var/secrets
readOnly: true
  • 접속 문자열은 urlFile > url > 내장 instance 순으로 쓰인다. urlFile로 Secret을 mount하면 비밀번호가 values에 남지 않는다(Database configuration).
  • controller.replicas가 2 이상이면 leader election이 자동으로 켜진다. 한 replica만 reconcile하고 나머지는 대기한다.
  • sessionRetentionDays는 그 기간 동안 활동이 없는 session과 딸린 데이터를 지운다. 기본 0은 지우지 않는다. 대화 원문 보존 기간은 회사 정책에 맞춘다.

migration은 기본적으로 controller가 시작할 때 실행한다. 배포 시점을 통제하려면 database.postgres.skipMigrations: true로 끄고 kagent db migrate up을 미리 실행한다 (Run migrations out-of-band).

사내 registry mirror를 쓰면 세 곳을 모두 지정한다 (Private registry and image mirroring).

image:
registry: registry.example.com
controller:
agentImage: # Python Declarative runtime
registry: registry.example.com
repository: kagent/app
tag: v0.10.2
goAgentImage: # Go Declarative runtime
registry: registry.example.com
repository: kagent/golang-adk
tag: v0.10.2
controller:
auth:
mode: trusted-proxy # 기본은 unsecure
userIdClaim: "" # 비우면 sub
ui:
service:
type: ClusterIP

trusted-proxy가 무엇을 믿는지, oauth2-proxy를 어디에 두는지는 oauth2-proxy와 trusted-proxy 인증에서 다룬다. controller의 8083과 UI는 인증 proxy나 우리 backend를 거쳐서만 닿게 하고, NetworkPolicy는 우리가 따로 만든다.

Agent가 여러 단계를 실행하면 응답 stream이 몇 분씩 이어진다. 중간 proxy의 기본 timeout이 짧으면 응답이 도중에 끊긴다(Long-running connections).

값기본의미
ui.streamTimeoutSeconds1800브라우저가 stream의 침묵을 기다리는 시간
ui.nginx.proxyReadTimeout · proxySendTimeout1800sUI의 nginx가 기다리는 시간
controller.a2aClientTimeout"" (제한 없음)Agent가 다른 Agent를 부를 때의 timeout

kagent의 기본값은 넉넉하다. 끊김이 생기면 kagent 앞의 ingress·gateway·oauth2-proxy timeout을 먼저 본다.

admission policy가 있는 클러스터에서 쓰는 값이다. 필요할 때만 넣는다.

값용도
controller.agentDeployment.nodeSelector · podLabelscontroller가 만드는 모든 Agent Pod에 기본 nodeSelector·label을 붙인다
podLabels · controller.podLabels · ui.podLabelskagent 자체 Pod의 label
extraObjectsExternalSecret 같은 동반 manifest를 같은 chart로 배포한다
otel.tracing.enabledtrace를 OTLP endpoint로 보낸다. 수집 쪽은 관측 덱 범위
  1. 대상 버전의 release notes에서 breaking change를 읽는다.
  2. PostgreSQL을 백업한다.
  3. helm get values kagent -n kagent로 현재 values를 받아 새 버전의 helm show values와 비교한다.
  4. kagent-crds를 올리고 kagent를 올린다. 둘 다 --version으로 같은 버전을 지정한다.
  5. Agent 몇 개의 Ready condition과 A2A 호출을 확인한다.

v0.9 이상으로 올리려면 먼저 v0.8.0 이상이어야 한다. v0.10에서는 querydoc subchart가 제거되어 query_documentation tool을 참조하던 Agent가 reconcile에 실패한다. 버전을 건너뛸 때는 사이 버전의 release notes도 함께 읽는다.

  • values에 rbac.namespaces: [agents]만 적었다. 무슨 일이 생기는가? → chart가 실패한다. 목록이 비어 있지 않으면 설치 namespace(kagent)가 포함되어야 한다.
  • 사내 mirror로 옮긴 뒤 Python runtime Agent는 뜨는데 Go runtime Agent만 ImagePullBackOff다. 원인은? → controller.goAgentImage를 지정하지 않아 Go image를 ghcr.io에서 받으려 한다.