GitOps 이전까지 쓸 배포 파이프라인과 Portal 모드 Chart를 추가한다
GitOps 저장소도 ArgoCD Application도 아직 없어, 그때까지 이 저장소가 push 방식 파이프라인(.gitea/workflows/)을 임시로 소유한다. 무엇을 포기하는지와 넘길 때 할 일은 deploy/README.md에 적었다. Chart는 portal과 bundles 두 배포 모델을 모두 렌더링한다. ADR-0013이 ADR-0007을 대체했으므로 운영은 portal이 기준이지만, bundles 경로를 언제 삭제할지는 아직 정하지 않았다. - .gitea/workflows/ci.yaml, deploy-openshift.yaml - deploy/ci/render-manifests.sh, deploy/examples/ - Chart: mode 분기, selectedDeployment/tier helper, imagePullSecrets, toolService.apiKeySecret 참조 - extension-points.md에 미결 항목 9~12 추가 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
42
README.md
42
README.md
@@ -55,8 +55,9 @@ $env:MCP_LOCAL_TOOL_REGISTRY_FILE='file:C:/path/local-tools.json'
|
||||
|
||||
## 공개 계약
|
||||
|
||||
- 공개 endpoint: `POST https://{global.mcpHost}{deployments.<key>.publicPath}`
|
||||
- 예: `https://mcp-dev.apps.example.internal/mcp/processing-critical`
|
||||
- 공개 endpoint: `POST https://{global.mcpHost}/mcp/{routeKey}`
|
||||
- 예: `https://mcp-dev.apps.example.internal/mcp/cus`
|
||||
- route key는 URI에서만 결정된다. route 없는 `/mcp` 호출은 거부한다
|
||||
- OpenShift Route는 공개 path로 MCP Service만 선택하고, 컨테이너가 같은 path를 직접 처리
|
||||
- Method: `initialize`, `notifications/initialized`, `tools/list`, `tools/call`
|
||||
- Response: 항상 단일 `application/json` JSON-RPC response
|
||||
@@ -70,13 +71,12 @@ Agent Builder는 공개 URL마다 별도 MCP로 등록하고 initialize한다. U
|
||||
|
||||
## Tool metadata와 실행
|
||||
|
||||
| 환경 | Tool 원천 | Redis |
|
||||
|-----------|-----------------------------------------|---------------------------------|
|
||||
| `local` | local JSON fixture | 사용 안 함 |
|
||||
| 운영(`ocp`) | 이 배포가 보는 Tool Service 매니페스트를 주기적으로 pull | 성공 snapshot 공유와 warm start에만 사용 |
|
||||
| 환경 | Tool 원천 | Redis |
|
||||
|---|---|---|
|
||||
| `local` | local JSON fixture | 사용 안 함 |
|
||||
| 운영(`ocp`) | Portal registry가 알려 준 route별 Tool Service 매니페스트를 주기적으로 pull | 성공 snapshot 공유와 Portal registry fallback에 사용 |
|
||||
|
||||
요청 경로의 `tools/list`와 `tools/call`은 in-memory snapshot만 읽는다. 운영 refresh는 bundle별 last-good을 유지하고, 모든 bundle에 사용 가능한 성공본이 있을 때만 aggregate를 교체한다. 조회 실패만으로 Tool을
|
||||
제거하지 않으며 정상 매니페스트에서 삭제가 확인될 때만 반영한다. 코드는 bundle N개 병합을 지원하지만 **운영 배포의 bundle은 항상 하나다**([ADR-0007](docs/decisions/ADR-0007-one-mcp-per-tool-service.md)).
|
||||
요청 경로의 `tools/list`와 `tools/call`은 in-memory snapshot만 읽는다. 운영 refresh는 bundle별 last-good을 유지하고, 그 route의 모든 bundle에 사용 가능한 성공본이 있을 때만 route의 aggregate를 교체한다. 조회 실패만으로 Tool을 제거하지 않으며 정상 매니페스트에서 삭제가 확인될 때만 반영한다. **한 route에는 Tool Service가 여럿 붙을 수 있고, 병합 단위는 route다**([ADR-0013](docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md)).
|
||||
|
||||
Tool 실행 주소는 local `_meta.endpoint` 또는 운영 `baseEndpoint` 설정에서만 정한다. Agent Builder의 `arguments`와 Tool Service 매니페스트는 호출 대상을 바꿀 수 없다.
|
||||
|
||||
@@ -131,33 +131,19 @@ namespace에서만 MCP Pod에 도달한다. 실제 CIDR을 넣지 않은 배포
|
||||
readiness는 첫 Tool discovery 시도가 끝나고 usable in-memory snapshot이 있을 때만 UP이다. 원천 장애 중에도
|
||||
기존 memory 또는 Redis last-good이 있으면 서비스를 유지하고, 아무 성공본도 없으면 트래픽을 받지 않는다.
|
||||
|
||||
**MCP 배포 하나는 Tool Service 하나만 본다**([ADR-0007](docs/decisions/ADR-0007-one-mcp-per-tool-service.md)). 대상을 늘리는 방법은 bundle 목록을 늘리는 것이 아니라 배포를 하나 더 만드는 것이다. 외부에서는
|
||||
같은 host의 고유 path로 각 배포를 노출하고 컨테이너가 그 path를 그대로 처리한다([ADR-0009](docs/decisions/ADR-0009-container-handles-public-mcp-path.md)). 배포는 업무 × 중요도 등급으로 나뉘며, 등급이
|
||||
replica 수와 PodDisruptionBudget을 정한다.
|
||||
**route↔Tool Service 매핑의 원천은 Portal이다**([ADR-0013](docs/decisions/ADR-0013-portal-owns-route-and-endpoint-registry.md)). 배포 하나가 N개 route를 서비스하고, route key는 `/mcp/{routeKey}` URI에서만 결정된다. 매핑이 바뀌어도 재배포하지 않는다. 외부에서는 같은 host의 path로 route를 구분하고 컨테이너가 그 path를 그대로 처리한다([ADR-0009](docs/decisions/ADR-0009-container-handles-public-mcp-path.md)).
|
||||
|
||||
배포 정의는 [Helm Chart](deploy/helm/mcp-server/) 하나뿐이다. 배포 토폴로지는 `values.yaml`이, 환경 차이는 `values-{dev,test,prod}.yaml`이 소유한다. 설치할 배포 하나는 `--set`으로 고른다.
|
||||
배포 정의는 [Helm Chart](deploy/helm/mcp-server/) 하나뿐이다. Chart는 배포 모델 둘을 `mode`로 고른다. `portal`이 현재 애플리케이션이 실제로 도는 경로이고, `bundles`는 ADR-0013이 대체한 1:1 구성([ADR-0007](docs/decisions/ADR-0007-one-mcp-per-tool-service.md))이다.
|
||||
|
||||
```bash
|
||||
helm upgrade --install processing-critical-mcp deploy/helm/mcp-server -f deploy/helm/mcp-server/values-dev.yaml --set deploymentKey=processing-critical -n <namespace>
|
||||
helm upgrade --install axhub-mcp deploy/helm/mcp-server -f deploy/helm/mcp-server/values-dev.yaml -n <namespace>
|
||||
```
|
||||
|
||||
**MCP Server와 Tool Service는 같은 namespace에 배포한다.** 그래서 values에는 Tool Service의 이름만 적고 주소는 template이 조립한다. 환경마다 URL을 반복해 적지 않으므로 오타로 엉뚱한 곳을 호출할 수 없다.
|
||||
배포 토폴로지는 `values.yaml`이, 환경 차이는 `values-{dev,test,prod}.yaml`이 소유한다. 두 모드의 차이, 등급별 가용성, 확정 전 임시값은 [deploy/README.md](deploy/README.md)가 정본이다.
|
||||
|
||||
```yaml
|
||||
deployments:
|
||||
processing-critical:
|
||||
name: processing-critical-mcp
|
||||
service: processing-critical-tools # ← 이름만. 주소는 template이 만든다
|
||||
namePrefix: "processing." # ← 업무 단위. 등급을 넣지 않는다
|
||||
tier: critical
|
||||
publicPath: /mcp/processing-critical # ← 같은 환경 host 안에서 유일
|
||||
```
|
||||
평문 manifest가 필요하면 `deploy/ci/render-manifests.sh`가 `helm template`으로 만든다. 별도 YAML을 저장소에 두지 않는다 — 두 벌은 반드시 어긋난다.
|
||||
|
||||
배포가 10개든 20개든 파일 수는 늘지 않는다. 자세한 사용법은 [deploy/README.md](deploy/README.md)에 있다.
|
||||
|
||||
평문 manifest가 필요하면 `helm template`으로 만든다. 별도 YAML을 저장소에 두지 않는다 — 두 벌은 반드시 어긋난다.
|
||||
|
||||
빌드·이미지·배포 실행 방식은 사내 표준 CI/CD가 담당하며 이 저장소가 정하지 않는다. 배포 시 알아야 할 앱 제약은 [deploy/README.md](deploy/README.md)에 정리했다.
|
||||
빌드·이미지·배포 실행 방식은 원래 사내 표준 CI/CD가 담당한다. GitOps 저장소가 준비되기 전까지만 `.gitea/workflows/`가 임시로 그 역할을 하며, 그 방식이 무엇을 포기하는지와 넘길 때 할 일은 [deploy/README.md](deploy/README.md#gitops-저장소가-없는-동안의-우회)에 적었다. 배포 시 알아야 할 앱 제약도 같은 문서에 정리했다.
|
||||
|
||||
## 문서 R&R
|
||||
|
||||
|
||||
Reference in New Issue
Block a user