Skip to content

Add Kubernetes pod template patching support#267

Merged
JAORMX merged 1 commit intomainfrom
feature/k8s-pod-template-patch
Apr 24, 2025
Merged

Add Kubernetes pod template patching support#267
JAORMX merged 1 commit intomainfrom
feature/k8s-pod-template-patch

Conversation

@JAORMX
Copy link
Copy Markdown
Collaborator

@JAORMX JAORMX commented Apr 24, 2025

Add Kubernetes pod template patching support

Kubernetes Pod Template Patching

When running ToolHive in a Kubernetes environment, you can customize the Kubernetes pod template used to deploy MCP servers. This is useful when you need to add specific Kubernetes configurations to your MCP server pods, such as:

  • Volume mounts
  • Environment variables
  • Resource limits and requests
  • Node selectors
  • Tolerations
  • Security contexts
  • Service accounts
  • And more

Using the --k8s-pod-patch Flag

The --k8s-pod-patch flag allows you to provide a JSON string that will be used to patch the Kubernetes pod template. This flag is only applicable when using the Kubernetes runtime.

thv run my-server --k8s-pod-patch '{"spec":{"volumes":[{"name":"my-volume","emptyDir":{}}]}}'

Container Structure

When ToolHive deploys an MCP server in Kubernetes, it creates a pod with a single container named "mcp". This is important to know when you want to modify container-specific settings in your pod template patch.

For example, to add environment variables or volume mounts to the container, you need to target the "mcp" container specifically:

thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "env": [
          {
            "name": "CUSTOM_ENV",
            "value": "custom-value"
          }
        ]
      }
    ]
  }
}'

Example Use Cases

Adding Volumes and Volume Mounts

thv run my-server --k8s-pod-patch '{
  "spec": {
    "volumes": [
      {
        "name": "data-volume",
        "emptyDir": {}
      }
    ],
    "containers": [
      {
        "name": "mcp",
        "volumeMounts": [
          {
            "name": "data-volume",
            "mountPath": "/data"
          }
        ]
      }
    ]
  }
}'

Adding Node Tolerations

thv run my-server --k8s-pod-patch '{
  "spec": {
    "tolerations": [
      {
        "key": "dedicated",
        "operator": "Equal",
        "value": "mcp-server",
        "effect": "NoSchedule"
      }
    ]
  }
}'

Setting Resource Limits and Requests

thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "resources": {
          "limits": {
            "cpu": "500m",
            "memory": "512Mi"
          },
          "requests": {
            "cpu": "100m",
            "memory": "128Mi"
          }
        }
      }
    ]
  }
}'

Using a Service Account

thv run my-server --k8s-pod-patch '{
  "spec": {
    "serviceAccountName": "my-service-account"
  }
}'

Adding Environment Variables

thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "env": [
          {
            "name": "DATABASE_URL",
            "value": "postgres://user:password@localhost:5432/db"
          },
          {
            "name": "API_KEY",
            "valueFrom": {
              "secretKeyRef": {
                "name": "api-secrets",
                "key": "api-key"
              }
            }
          }
        ]
      }
    ]
  }
}'

Setting Security Context

thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "securityContext": {
          "runAsUser": 1000,
          "runAsGroup": 1000,
          "allowPrivilegeEscalation": false
        }
      }
    ]
  }
}'

How It Works

When you provide a JSON patch via the --k8s-pod-patch flag:

  1. ToolHive creates a base pod template spec
  2. The JSON patch is applied to the base template
  3. ToolHive then applies its own required configurations (container name, image, command, etc.)
  4. The final pod template is used to create a StatefulSet in Kubernetes

This approach allows you to customize the pod template while ensuring that ToolHive's required configurations are still applied.

Notes

  • The JSON patch must be valid JSON and conform to the Kubernetes pod template spec structure
  • The patch is applied before ToolHive's own configurations, so some fields may be overridden by ToolHive
  • This feature is only applicable when running ToolHive in a Kubernetes environment
  • Always target the container named "mcp" when modifying container-specific settings
  • Some container settings like image, command, and args will be overridden by ToolHive's configurations

@JAORMX JAORMX force-pushed the feature/k8s-pod-template-patch branch 2 times, most recently from 5b866ff to 873d3b3 Compare April 24, 2025 10:49
@JAORMX JAORMX requested a review from ChrisJBurns April 24, 2025 10:49
When running ToolHive in a Kubernetes environment, you can customize the Kubernetes pod template used to deploy MCP servers. This is useful when you need to add specific Kubernetes configurations to your MCP server pods, such as:

- Volume mounts
- Environment variables
- Resource limits and requests
- Node selectors
- Tolerations
- Security contexts
- Service accounts
- And more

The `--k8s-pod-patch` flag allows you to provide a JSON string that will be used to patch the Kubernetes pod template. This flag is only applicable when using the Kubernetes runtime.

```bash
thv run my-server --k8s-pod-patch '{"spec":{"volumes":[{"name":"my-volume","emptyDir":{}}]}}'
```

When ToolHive deploys an MCP server in Kubernetes, it creates a pod with a single container named **"mcp"**. This is important to know when you want to modify container-specific settings in your pod template patch.

For example, to add environment variables or volume mounts to the container, you need to target the "mcp" container specifically:

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "env": [
          {
            "name": "CUSTOM_ENV",
            "value": "custom-value"
          }
        ]
      }
    ]
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "volumes": [
      {
        "name": "data-volume",
        "emptyDir": {}
      }
    ],
    "containers": [
      {
        "name": "mcp",
        "volumeMounts": [
          {
            "name": "data-volume",
            "mountPath": "/data"
          }
        ]
      }
    ]
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "tolerations": [
      {
        "key": "dedicated",
        "operator": "Equal",
        "value": "mcp-server",
        "effect": "NoSchedule"
      }
    ]
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "resources": {
          "limits": {
            "cpu": "500m",
            "memory": "512Mi"
          },
          "requests": {
            "cpu": "100m",
            "memory": "128Mi"
          }
        }
      }
    ]
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "serviceAccountName": "my-service-account"
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "env": [
          {
            "name": "DATABASE_URL",
            "value": "postgres://user:password@localhost:5432/db"
          },
          {
            "name": "API_KEY",
            "valueFrom": {
              "secretKeyRef": {
                "name": "api-secrets",
                "key": "api-key"
              }
            }
          }
        ]
      }
    ]
  }
}'
```

```bash
thv run my-server --k8s-pod-patch '{
  "spec": {
    "containers": [
      {
        "name": "mcp",
        "securityContext": {
          "runAsUser": 1000,
          "runAsGroup": 1000,
          "allowPrivilegeEscalation": false
        }
      }
    ]
  }
}'
```

When you provide a JSON patch via the `--k8s-pod-patch` flag:

1. ToolHive creates a base pod template spec
2. The JSON patch is applied to the base template
3. ToolHive then applies its own required configurations (container name, image, command, etc.)
4. The final pod template is used to create a StatefulSet in Kubernetes

This approach allows you to customize the pod template while ensuring that ToolHive's required configurations are still applied.

- The JSON patch must be valid JSON and conform to the Kubernetes pod template spec structure
- The patch is applied before ToolHive's own configurations, so some fields may be overridden by ToolHive
- This feature is only applicable when running ToolHive in a Kubernetes environment
- Always target the container named "mcp" when modifying container-specific settings
- Some container settings like image, command, and args will be overridden by ToolHive's configurations

Signed-off-by: Juan Antonio Osorio <ozz@stacklok.com>
@JAORMX JAORMX force-pushed the feature/k8s-pod-template-patch branch from 873d3b3 to 9c15e55 Compare April 24, 2025 12:56
@JAORMX JAORMX merged commit 9736fd8 into main Apr 24, 2025
10 checks passed
@JAORMX JAORMX deleted the feature/k8s-pod-template-patch branch April 24, 2025 13:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants