Container Orchestration/Kubernetes

Unity MCP Server를 Kubernetes에 배포하기

Somaz 2026. 7. 30. 00:00
728x90
반응형

Overview

MCP for Unity는 AI 어시스턴트(Claude, Cursor, VS Code 등)와 Unity Editor를 Model Context Protocol(MCP)을 통해 연결하는 오픈소스 브릿지 서버이다.

 

기본적으로 로컬(localhost:8080)에서 동작하지만, Kubernetes에 배포하면 팀원 전체가 하나의 MCP 서버를 공유하고, Unity Editor 인스턴스를 중앙에서 관리할 수 있다.

 

이 글에서는 Unity MCP Server를 Docker 이미지로 빌드하고, Harbor 레지스트리에 Push한 뒤, Kubernetes 클러스터에 배포하는 전체 과정을 다룬다.

 

 

 

 

 

 

 


 

Architecture

┌─────────────────┐     HTTP/SSE      ┌─────────────────────┐     WebSocket      ┌─────────────────┐
│   AI Client     │ ◄──────────────► │   MCP Server (K8s)  │ ◄────────────────► │  Unity Editor   │
│ (Claude/Cursor) │    /mcp endpoint  │   Pod + Service     │   /hub/plugin      │  (Local PC)     │
└─────────────────┘                   └─────────────────────┘                    └─────────────────┘
                                              │
                                        Ingress (nginx)
                                        unity-mcp.example.com
  • AI Client → MCP Server: HTTP/SSE 프로토콜로 JSON-RPC 통신
  • Unity Editor → MCP Server: WebSocket(/hub/plugin)으로 플러그인 연결
  • MCP Server: 양쪽을 중계하며 40+ Unity 제어 도구 제공

 

 

 

Prerequisites

  • Docker Desktop (buildx 지원)
  • Kubernetes 클러스터 (kubectl 설정 완료)
  • Container Registry (Harbor, Docker Hub 등)
  • 도메인 및 DNS 설정 가능 환경
  • Unity 2021.3 LTS 이상 + MCP for Unity 패키지

 

 

 


 

 

 

1. Docker 이미지 빌드

 

 

소스 클론

git clone https://github.com/CoplayDev/unity-mcp.git
cd unity-mcp

 

 

Docker Desktop 설정

Private 레지스트리를 사용하는 경우, Docker Desktop 설정에서 insecure-registries를 추가한다.

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "insecure-registries": [
    "registry.example.com"
  ]
}

 

 

Linux (dockerd)

Linux 환경에서는 `/etc/docker/daemon.json` 파일을 직접 수정한다.

sudo vi /etc/docker/daemon.json
 
{
  "insecure-registries": [
    "registry.example.com"
  ]
}

 

 

설정 후 Docker 데몬을 재시작한다.

sudo systemctl restart docker

 

 

정상 적용 여부는 아래 명령으로 확인할 수 있다.

docker info | grep -A 5 "Insecure Registries"

 

 

 

 

이미지 빌드 및 Push

Kubernetes 노드가 AMD64 아키텍처인 경우, Mac(ARM64)에서 빌드할 때 반드시 `--platform linux/amd64` 을 지정해야 한다.

 

 

방법 1: 빌드 → 태그 → Push 순서로 진행

# 빌드
docker build --platform linux/amd64 -t unity-mcp-server:v9.4.7 .

# 태그 변경
docker tag unity-mcp-server:v9.4.7 registry.example.com/library/unity-mcp-server:v9.4.7

# 레지스트리 로그인
docker login registry.example.com

# Push
docker push registry.example.com/library/unity-mcp-server:v9.4.7

 

 

방법 2: buildx로 빌드+Push 한번에

docker buildx build --platform linux/amd64 \
  -t registry.example.com/library/unity-mcp-server:v9.4.7 \
  -f Dockerfile --push .

주의: Mac ARM64에서 `--platform` 없이 빌드하면 ARM64 이미지가 생성되어 AMD64 노드에서 `ImagePullBackOff` 또는 `exec format error` 가 발생한다.

 

 

 


 

 

 

2. API Key Secret 생성

MCP 서버에 인증을 추가하려면 `--api-key-service-token` 옵션을 사용한다. 먼저 Kubernetes Secret을 생성한다.

 

 

랜덤 API Key 생성

# 랜덤 API Key 생성 후 Secret 생성
API_KEY=$(openssl rand -hex 32) && echo "API Key: $API_KEY" && \
kubectl create secret generic unity-mcp-api-key \
  -n mcp-server \
  --from-literal=api-key="$API_KEY"

 

 

또는 직접 지정

kubectl create secret generic unity-mcp-api-key \
  -n mcp-server \
  --from-literal=api-key="my-secure-api-key-here"

 

 

확인

kubectl get secrets -n mcp-server unity-mcp-api-key -o yaml

# base64 디코딩으로 값 확인
kubectl get secret unity-mcp-api-key -n mcp-server \
  -o jsonpath='{.data.api-key}' | base64 -d

 

 

주의할 점

해당 api key 를 생성하였지만, Unity에서 MCP Server와 연결할때 아무키나 넣어도 연결이 되었다?!

이유는 알 수 없다.

 

 


 

 

 

3. Kubernetes 매니페스트 작성

Namespace, Deployment, Service, Ingress를 하나의 YAML 파일로 구성한다.

 

 

Namespace

apiVersion: v1
kind: Namespace
metadata:
  name: mcp-server

 

 

Deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: unity-mcp-server
  namespace: mcp-server
  labels:
    app: unity-mcp-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: unity-mcp-server
  template:
    metadata:
      labels:
        app: unity-mcp-server
    spec:
      containers:
      - name: unity-mcp-server
        image: registry.example.com/library/unity-mcp-server:v9.4.7
        ports:
        - containerPort: 8080
          name: http
        env:
        - name: PYTHONPATH
          value: /app/Server/src
        - name: DISABLE_TELEMETRY
          value: "true"
        - name: PYTHONUNBUFFERED
          value: "1"
        - name: MCP_API_KEY
          valueFrom:
            secretKeyRef:
              name: unity-mcp-api-key
              key: api-key
        command: ["uv", "run", "mcp-for-unity"]
        args:
        - "--transport"
        - "http"
        - "--http-host"
        - "0.0.0.0"
        - "--http-port"
        - "8080"
        - "--api-key-service-token"
        - "$(MCP_API_KEY)"
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "1024Mi"
            cpu: "500m"
        livenessProbe:
          tcpSocket:
            port: http
          initialDelaySeconds: 15
          periodSeconds: 10
          failureThreshold: 3
        readinessProbe:
          tcpSocket:
            port: http
          initialDelaySeconds: 5
          periodSeconds: 5
          failureThreshold: 3

Probe 설명: MCP 서버는 JSON-RPC 프로토콜을 사용하므로 일반 HTTP GET 요청에 405/406 에러를 반환한다. 따라서 httpGet 대신 tcpSocket 프로브를 사용한다.

 

Service

apiVersion: v1
kind: Service
metadata:
  name: unity-mcp-server
  namespace: mcp-server
  labels:
    app: unity-mcp-server
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
      name: http
  selector:
    app: unity-mcp-server

 

Ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: unity-mcp-server-ingress
  namespace: mcp-server
  annotations:
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/ssl-passthrough: "false"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "300"
    nginx.ingress.kubernetes.io/proxy-buffering: "off"
    nginx.ingress.kubernetes.io/proxy-http-version: "1.1"
spec:
  ingressClassName: nginx
  rules:
  - host: unity-mcp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: unity-mcp-server
            port:
              number: 80

SSE 지원: `proxy-buffering: "off"` 와 `proxy-http-version: "1.1"` 설정이 MCP의 Server-Sent Events 통신에 필수다. 이 설정이 없으면 스트리밍 응답이 버퍼링되어 실시간 통신이 실패한다.

 

 

DNS 설정

Ingress에 설정한 호스트명에 대해 CNAME or A 레코드를 추가한다. 알맞은 레코드를 추가하면 된다.

Record Value
unity-mcp.example.com ingress-lb.example.com

 

 

 


 

 

 

4. 배포 및 확인

 

 

배포

# Namespace 생성
kubectl create namespace mcp-server

# 매니페스트 적용
kubectl apply -f unity-mcp-server.yaml

 

Pod 상태 확인

kubectl get pods -n mcp-server

# 로그 확인
kubectl logs -n mcp-server -l app=unity-mcp-server

 

 

 

정상 기동 시 아래와 같은 로그가 출력된다.

╭──────────────────────────────────────────────────────────────────────────────╮
│                         ▄▀▀ ▄▀█ █▀▀ ▀█▀ █▀▄▀█ █▀▀ █▀█                        │
│                         █▀  █▀█ ▄▄█  █  █ ▀ █ █▄▄ █▀▀                        │
│                                                                              │
│                                FastMCP 2.14.1                                │
│                                                                              │
│                   🖥  Server name: mcp-for-unity-server                       │
│                   📦 Transport:   HTTP                                       │
│                   🔗 Server URL:  http://0.0.0.0:8080/mcp                    │
╰──────────────────────────────────────────────────────────────────────────────╯

 

 

MCP 서버 동작 테스트

curl -s -X POST http://unity-mcp.example.com/mcp \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2024-11-05",
      "capabilities": {},
      "clientInfo": {
        "name": "test",
        "version": "1.0"
      }
    }
  }'

 

 

정상 응답 예시

event: message
data: {
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": { "listChanged": true },
      "resources": { "subscribe": false, "listChanged": true }
    },
    "serverInfo": {
      "name": "mcp-for-unity-server",
      "version": "2.14.1"
    }
  }
}

 

 

 

 


 

 

 

5. Unity Editor 연결

 

 

Unity 패키지 설치

Unity Editor에서 Window > Package Manager > + > Add package from git URL...로 아래 URL을 추가한다.

https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main

 

 

MCP 서버 연결 설정

  1. Window > MCP for Unity 창을 연다.
  2. 서버 주소를 http://unity-mcp.example.com/mcp로 변경한다.
  3. 상태가 Connected ✓ 로 표시되는지 확인한다.

 

연결 성공 시 서버 로그에 아래와 같이 표시된다.

Plugin registered: YourProject (해시값)
Registered 20 tools for session xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

 

 

MCP 클라이언트 설정 (Claude Desktop / Cursor)

{
  "mcpServers": {
    "unityMCP": {
      "url": "http://unity-mcp.example.com/mcp"
    }
  }
}

 

 

 

 

 

Troubleshooting

 

 

ImagePullBackOff / exec format error

Mac ARM64에서 빌드한 이미지를 AMD64 노드에서 실행할 때 발생한다. `--platform linux/amd64` 옵션을 추가하여 재빌드한다.

docker buildx build --platform linux/amd64 -t registry.example.com/library/unity-mcp-server:v9.4.7 --push .

 

 

Readiness Probe 실패 (405/406 에러)

MCP 서버는 JSON-RPC 기반이므로 httpGet 프로브가 동작하지 않는다. tcpSocket 프로브로 변경한다.

readinessProbe:
  tcpSocket:
    port: http
  initialDelaySeconds: 5
  periodSeconds: 5

 

 

"No Unity plugin reconnected within 20.00s"

MCP 서버가 이전에 연결됐던 Unity 인스턴스를 기억하고 있지만, 해당 Unity Editor가 현재 연결되지 않은 상태다.

  • Unity Editor가 열려있고 MCP 플러그인이 활성화되어 있는지 확인한다.
  • 또는 Pod를 재시작하여 오래된 인스턴스 정보를 초기화한다.
 
kubectl rollout restart deployment unity-mcp-server -n mcp-server

 

 

ClosedResourceError

위의 Unity 미연결 상태에서 AI 클라이언트가 tool을 호출할 때 발생하는 연쇄 에러다. Unity Editor 연결 문제를 먼저 해결하면 함께 해결된다.

 

 

OAuth 404 Not Found

GET /.well-known/oauth-authorization-server → 404
  • MCP 클라이언트가 자동으로 OAuth 엔드포인트를 탐색하는 동작이며, 인증이 API Key 방식인 경우 404가 정상이다. 무시해도 된다.

 

 

 

 


 

 

 

마무리

Unity MCP Server를 Kubernetes에 배포하면, 팀 전체가 하나의 엔드포인트(`unity-mcp.example.com/mcp`)를 통해 AI 어시스턴트와 Unity Editor를 연결할 수 있다. 특히 여러 프로젝트를 동시에 관리할 때 `set_active_instance` 로 인스턴스를 전환하며 사용할 수 있어 편리하다.

 

다만 기본적으로 인증이 없는 상태로 외부에 노출되므로, 프로덕션 환경에서는 API Key 인증이나 Ingress 레벨의 IP 화이트리스트를 반드시 적용해야 한다. 또한 Unity Editor가 연결되지 않은 상태에서 AI 클라이언트가 tool을 호출하면 타임아웃 에러가 발생하므로, 사용 전에 Unity Editor의 연결 상태를 항상 확인하는 습관이 필요하다.

 

 

 

 

 

 

 

 


Reference

 

 

 

 

 

 

Somaz | DevOps Engineer | Kubernetes & Cloud Infrastructure Specialist

728x90
반응형