Helm으로 MCP 터널 배포하기
Anthropic Helm 차트를 사용하여 Kubernetes 클러스터에 터널 스택을 설치합니다.
Anthropic Helm 차트는 터널 스택을 단일 Deployment로 설치하고 이를 터널에 연결합니다. 터널은 차트의 setup 훅이 생성해 주는 것이거나, Console에서 직접 생성한 기존 터널일 수 있습니다.
시작하기 전에
다음이 필요합니다:
- 터널. 프로그래매틱 액세스를 사용하는 경우, 터널 ID를 제공하지 않으면 차트의 setup 훅이 터널을 생성해 줍니다. 대신 기존 터널에 연결하려면 Console에서 터널을 생성하고 터널 ID(
tnl_...)를 기록해 두세요. 수동 프로비저닝은 항상 Console에서 생성한 터널에서 시작하며, 해당 터널의 터널 토큰과 터널 도메인도 필요합니다. - 차트가 Tunnels API에 인증할 수 있는 방법.
- 프로그래매틱 액세스(권장). setup 컴포넌트가 Workload Identity Federation을 통해 인증하고, 터널 토큰을 가져오고, CA를 생성하여 Anthropic에 등록한 뒤, 모든 것을 Secret에 저장합니다.
workspace:manage_tunnels범위로 지정된 페더레이션 규칙이 필요합니다. - 수동. 프로그래매틱 액세스를 건너뜁니다. Console에서 터널 토큰을 가져오고, CA와 서버 인증서를 직접 생성하고, Console에 CA를 등록한 다음, 자격 증명을 Secret으로 클러스터에 제공합니다.
- 프로그래매틱 액세스(권장). setup 컴포넌트가 Workload Identity Federation을 통해 인증하고, 터널 토큰을 가져오고, CA를 생성하여 Anthropic에 등록한 뒤, 모든 것을 Secret에 저장합니다.
helm과kubectl로 배포할 수 있는 Kubernetes 클러스터. 프로그래매틱 액세스 없이 탭에서는openssl(1.1.1 이상)도 사용합니다.- 클러스터에서
api.anthropic.com(443 TCP) 및 터널 엣지(7844 TCP 및 UDP)로의 아웃바운드 네트워크 연결. 전체 네트워크 요구 사항을 참조하세요. gateway.config.routes아래에 구성할 주소에서 클러스터로부터 접근 가능하며 실행 중인 하나 이상의 MCP 서버. 아직 없다면 샘플 서버를 사용하세요.
선택 사항: 샘플 MCP 서버 사용하기
테스트에 사용할 수 있는 MCP 서버가 없다면 다음의 최소 서버를 사용하세요:
kubectl create namespace mcp-tunnel --dry-run=client -o yaml | kubectl apply -f -
kubectl -n mcp-tunnel apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: hello-mcp-src
data:
hello_server.py: |
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-server", host="0.0.0.0", port=9000)
@mcp.tool()
def hello(name: str = "world") -> str:
"""Say hello to someone."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run(transport="streamable-http")
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-mcp
spec:
replicas: 1
selector:
matchLabels: { app: hello-mcp }
template:
metadata:
labels: { app: hello-mcp }
spec:
containers:
- name: hello-mcp
image: python:3.13-slim
command: ["sh", "-c", "pip install --quiet mcp && python /app/hello_server.py"]
volumeMounts:
- { name: src, mountPath: /app }
ports:
- { containerPort: 9000 }
volumes:
- name: src
configMap: { name: hello-mcp-src }
---
apiVersion: v1
kind: Service
metadata:
name: hello-mcp
spec:
selector: { app: hello-mcp }
ports:
- { port: 9000, targetPort: 9000 }
EOF이어지는 설치 단계에서 해당 라우트를 어디에 추가해야 하는지 안내합니다.
설치
setup 컴포넌트는 페더레이션 규칙을 통해 클러스터의 프로젝션된 ServiceAccount 토큰을 교환하고, 터널 토큰을 가져오고, CA와 서버 인증서를 생성한 뒤, CA를 Anthropic에 등록합니다. 매일 실행되는 CronJob이 필요에 따라 서버 인증서를 갱신하므로, 어떤 시크릿도 직접 다룰 필요가 없습니다.
클러스터에 Workload Identity Federation 설정하기
Kubernetes에서 WIF 사용하기를 따라 클러스터의 OIDC 발급자를 등록하고 페더레이션 규칙을 생성하세요. setup 컴포넌트는 릴리스 네임스페이스에서 자체 ServiceAccount로 실행됩니다. 정확한 이름은 Helm의
fullname규칙을 따르므로, 릴리스 이름이mcp-tunnel이 아닌 경우 규칙을 생성하기 전에helm template <release> ... | grep -A2 'kind: ServiceAccount'를 실행하여 확인하세요. 이 가이드의 나머지 부분은 네임스페이스mcp-tunnel에 릴리스 이름mcp-tunnel을 사용한다고 가정하며, 이 경우 ServiceAccount는mcp-tunnel-setup입니다.필드 값 Subject system:serviceaccount:mcp-tunnel:mcp-tunnel-setupAudience api.anthropic.com(차트의 기본값, 스킴 없음)Scope workspace:manage_tunnels터널이 조직의 기본 워크스페이스가 아닌 다른 워크스페이스에 있는 경우, Settings > Workspaces에서 규칙의 서비스 계정을 해당 워크스페이스의 멤버로도 추가하세요(Tunnels API는 서비스 계정의 워크스페이스 멤버십을 기준으로 권한을 부여합니다).
규칙의 ID(
fdrl_...)를 기록해 두세요. 이를api.wif.federationRuleId로 설정하게 됩니다.기본 values 가져오기
helm show values \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 > values.yaml터널 연결 및 라우트 구성하기
values.yaml을 편집하여api.wif.*키에 페더레이션 규칙 ID와 조직 ID를 설정하고, 각 업스트림 MCP 서버에 대한routes항목을 추가하세요:values.yamlapi: wif: federationRuleId: "fdrl_..." organizationId: "00000000-0000-0000-0000-000000000000" # Set when the tunnel is in a non-default workspace and the # rule's service account is a member of that workspace. # workspaceId: "wrkspc_..." tunnel: # Leave empty to have the setup hook create a tunnel during install. # Set to attach to an existing tunnel from the Console. id: "" # Increment to rotate the tunnel token on the next upgrade. # See the "Rotate the tunnel token" section. tokenVersion: "1" gateway: config: routes: docs: http://docs-mcp.internal:8080 search: http://search-mcp.internal:8080이 라우트를 사용하면 Claude는
docs.<your-tunnel-domain>및search.<your-tunnel-domain>에서 서버에 접근합니다. 일부 관리형 Kubernetes 배포판은 Service CIDR을 표준 사설 범위 밖에 할당합니다. 라우트가 클러스터 내 Service를 대상으로 한다면 업스트림 IP 검증에 따라 여기에gateway.config.upstream.allowed_ips를 추가하세요.렌더링된 매니페스트 검토하기
차트를 렌더링하고 조직의 검증 관행에 따라 출력을 검토하세요:
helm template mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ -n mcp-tunnel \ -f values.yaml > rendered.yaml설치
helm install mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ --namespace mcp-tunnel --create-namespace \ -f values.yamlsetup 컴포넌트는 Helm pre-install 훅 Job으로 실행되므로,
helm install은 완료될 때까지 블록됩니다. 성공하면 Helm이 Job을 자동으로 삭제합니다.helm install이 훅 오류로 실패하면 setup 컴포넌트 인증 실패를 참조하세요.tunnel.id가 비어 있으면 setup 컴포넌트는 페더레이션 규칙이 대상으로 하는 워크스페이스(api.wif.workspaceId를 설정하지 않은 경우 조직의 기본 워크스페이스)에 터널을 생성하고 그 ID와 도메인을mcp-tunnelSecret에 저장합니다. 검증에 필요한 도메인은 Console의 Manage > MCP tunnels 아래 터널 상세 페이지에서 찾거나, Secret에서 읽을 수 있습니다:kubectl -n mcp-tunnel get secret mcp-tunnel \ -o jsonpath='{.data.tunnel-domain}' | base64 -dsetup 컴포넌트를 다시 실행하면(업그레이드 또는 토큰 교체 중) 이 Secret에 저장된 터널 ID를 재사용하며, 두 번째 터널을 생성하지 않습니다.
배포 검증하기
Anthropic 측에서 엔드 투 엔드로 검증하세요. Managed Agent 세션 또는 Messages API 요청에서 https://<route>.<your-tunnel-domain>/<path>를 사용하세요. 여기서 <route>는 gateway.config.routes의 키이고 <path>는 업스트림 MCP 서버가 서비스하는 경로입니다. 샘플 MCP 서버의 경우 https://echo.<your-tunnel-domain>/mcp입니다. 요청 형식은 터널링된 MCP 서버 사용하기를 참조하세요.
실패하면 파드 로그(kubectl -n mcp-tunnel logs deploy/mcp-tunnel -c mcp-proxy 및 -c cloudflared)를 확인하고 문제 해결을 참조하세요.
선택적 구성
NetworkPolicy로 이그레스 제한하기
프록시 파드로의 인그레스는 기본적으로 거부됩니다(networkPolicy.ingress.enabled: true). 파드 이그레스를 추가로 제한하려면 networkPolicy.egress.enabled: true를 설정하고 networkPolicy.egress.mcpServers에 업스트림 MCP 서버를 포함하는 파드 레이블 셀렉터 또는 CIDR 범위를 채우세요. cloudflared에서 터널 엣지로의 이그레스는 networkPolicy.egress.cloudflaredEgressCIDRs를 통해 별도로 허용됩니다.
프록시 튜닝하기
gateway.config.* 아래의 필드는 프록시 구성 파일로 그대로 전달됩니다. 일반적인 조정 항목으로는 upstream.allowed_ips, log_level, upstream.tls가 있습니다. 전체 필드 목록은 프록시 구성 레퍼런스를 참조하세요. 차트는 항상 listen_addr, tls.cert_file, tls.key_file을 설정하므로, gateway.config에서 이를 설정해도 효과가 없습니다.
자체 OIDC 토큰 제공하기
기본적으로 차트는 setup 컴포넌트를 위해 Kubernetes ServiceAccount 토큰을 프로젝션합니다. 다른 ID 공급자(예: SPIFFE, Vault 또는 클라우드 SDK 사이드카)의 토큰을 사용하려면 setup.extraVolumes 및 setup.extraVolumeMounts로 마운트하세요. 그런 다음 api.wif.tokenFile을 마운트 경로로 지정하세요. 차트는 ANTHROPIC_IDENTITY_TOKEN_FILE을 해당 경로로 설정하고, setup 컴포넌트는 거기서 토큰을 읽습니다.
업그레이드
예기치 않게 더 새로운 차트를 가져오지 않도록 helm upgrade에 항상 --version을 전달하세요.
차트 1.x에서 업그레이드하기
차트 2.0.0은 터널 ID를 api.wif.tunnelId에서 tunnel.id로 옮깁니다. 업그레이드하기 전에 values.yaml을 편집하세요. tnl_... 값을 tunnel.id로 옮기고 api.wif.tunnelId를 제거하세요. tunnel.id를 설정하지 않은 채로 두어도 안전하지만(setup 컴포넌트는 재실행 시 mcp-tunnel Secret에 이미 저장된 터널 ID를 재사용합니다), 명시적으로 옮기면 values.yaml이 정확하게 유지됩니다. 또한 Console에서 페더레이션 규칙의 범위를 org:manage_tunnels에서 workspace:manage_tunnels로 업데이트하세요.
구성 변경하기
라우트, 레플리카 수 또는 NetworkPolicy와 같은 일상적인 변경의 경우:
helm upgrade mcp-tunnel \
oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
--version 2.0.2 \
-n mcp-tunnel \
-f values.yaml터널 토큰 교체하기
프로그래매틱 액세스를 사용하는 경우, values.yaml에서 tunnel.tokenVersion을 증가시키고 --set setup.force=true로 업그레이드하세요. setup 컴포넌트는 강제된 경우에만 업그레이드 시 다시 실행됩니다:
helm upgrade mcp-tunnel \
oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
--version 2.0.2 \
-n mcp-tunnel \
-f values.yaml \
--set setup.force=truesetup 컴포넌트는 Workload Identity Federation으로 인증하므로, 폐기할 API 토큰이 없습니다.
프로그래매틱 액세스를 사용하지 않는 경우, Console의 터널 상세 페이지에서 Rotate token을 클릭한 다음 mcp-tunnel-token Secret을 업데이트하세요:
kubectl -n mcp-tunnel create secret generic mcp-tunnel-token \
--from-literal=tunnel-token='eyJ...' --dry-run=client -o yaml | kubectl apply -f -
kubectl -n mcp-tunnel rollout restart deploy/mcp-tunnel인증서 갱신
차트는 자동화를 제공하지만, 만료를 모니터링하고 갱신이 완료되었는지 확인하는 책임은 여전히 사용자에게 있습니다.
프로그래매틱 액세스를 사용하는 경우 인증서 갱신은 자동입니다. 차트는 setup renew-cert를 매일(serverCert.cronSchedule, 기본값 0 0 * * * UTC) 실행하는 CronJob(Helm fullname을 따라 이름이 지정되고 -cert-renew 접미사가 붙음)을 배포합니다. 인증서가 만료까지 serverCert.renewBefore(기본값 30일) 이내가 아니면 이 작업은 아무것도 하지 않습니다. 갱신은 로컬에서 이루어집니다. 작업은 Secret에 이미 저장된 CA로 새 인증서에 서명하고, API 호출을 하지 않으며, 차트가 부여하는 Kubernetes RBAC만 필요합니다. 프록시는 Secret 마운트에서 인증서를 핫 리로드하므로 Deployment 재시작이 필요하지 않습니다.
프로그래매틱 액세스를 사용하지 않는 경우 CronJob이 없습니다. 설치 후 보관해 둔 mcp-tunnel/ 디렉터리 안에서 기존 CA로 새 서버 인증서에 서명하세요(CA를 다시 생성하지 마세요):
export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE
openssl req -new -key data/tls.key -out /tmp/server.csr \
-subj "/CN=${TUNNEL_DOMAIN}"
openssl x509 -req -in /tmp/server.csr \
-CA data/ca.crt -CAkey data/ca.key -CAcreateserial \
-out data/tls.crt -days 90 -extfile data/tls.ext
kubectl -n mcp-tunnel create secret generic mcp-tunnel-cert \
--from-file=tls.crt=data/tls.crt --from-file=tls.key=data/tls.key \
--dry-run=client -o yaml | kubectl apply -f -프록시는 Secret 마운트에서 인증서를 핫 리로드합니다.
다음 단계
업스트림 MCP 서버를 Managed Agent 또는 Messages API에 연결합니다.
강화 지침, 자격 증명 교체 및 침해 대응.
연결, TLS 및 라우팅 문제를 진단합니다.
Was this page helpful?