Kubernetes Deployment
Deployment
Kubernetes Deployment
Deploy WebInteract MCP Server on Kubernetes with high availability, auto-scaling, and production-ready configuration.
Quick Start
Prerequisites
- Kubernetes 1.20+
- kubectl configured
- Helm 3.0+ (optional)
- Docker registry access
Simple Deployment
Deploy WebInteract MCP Server with basic configuration:
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: webinteract-mcp-server
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: webinteract-mcp-server
template:
metadata:
labels:
app: webinteract-mcp-server
spec:
containers:
- name: webinteract-mcp-server
image: webinteract-mcp-server:latest
ports:
- containerPort: 8080
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: McpInteract__Client__BaseUrl
value: "https://myapp.example.com"
---
apiVersion: v1
kind: Service
metadata:
name: webinteract-mcp-service
namespace: default
spec:
selector:
app: webinteract-mcp-server
ports:
- port: 80
targetPort: 8080
type: ClusterIP
EOF
Verify Deployment
# Check deployment status
kubectl get deployments
# Check pods
kubectl get pods -l app=webinteract-mcp-server
# Check service
kubectl get services
# View logs
kubectl logs -l app=webinteract-mcp-server
Helm Deployment
Using the Official Helm Chart
# Add Helm repository (replace with actual repo)
helm repo add webinteract https://charts.webinteract.com
helm repo update
# Install with default values
helm install webinteract-mcp webinteract/webinteract-mcp-server
# Install with custom values
helm install webinteract-mcp webinteract/webinteract-mcp-server \
--set image.tag=v1.0.0 \
--set replicaCount=3 \
--set ingress.enabled=true \
--set ingress.hosts[0].host=mcp.example.com
Custom Helm Values
Create values.yaml
for customization:
# values.yaml
replicaCount: 3
image:
repository: webinteract-mcp-server
tag: "latest"
pullPolicy: IfNotPresent
nameOverride: ""
fullnameOverride: ""
service:
type: ClusterIP
port: 80
targetPort: 8080
ingress:
enabled: true
className: "nginx"
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
hosts:
- host: mcp.example.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: webinteract-mcp-tls
hosts:
- mcp.example.com
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 10
targetCPUUtilizationPercentage: 80
targetMemoryUtilizationPercentage: 80
config:
mcpInteract:
client:
baseUrl: "https://myapp.example.com"
timeoutSeconds: 60
cacheDurationMinutes: 60
tool:
timeoutMinutes: 10
enableDetailedErrorLogging: false
cors:
allowedOrigins:
- "https://myapp.example.com"
nodeSelector: {}
tolerations: []
affinity: {}
serviceAccount:
create: true
annotations: {}
name: ""
podAnnotations: {}
podSecurityContext:
fsGroup: 1001
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1001
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5
Deploy with custom values:
helm install webinteract-mcp webinteract/webinteract-mcp-server -f values.yaml
Production Deployment
Complete Production Manifest
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: webinteract-mcp
labels:
name: webinteract-mcp
---
# configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: webinteract-mcp-config
namespace: webinteract-mcp
data:
appsettings.json: |
{
"McpInteract": {
"Client": {
"BaseUrl": "https://myapp.example.com",
"TimeoutSeconds": 60,
"CacheDurationMinutes": 60
},
"Tool": {
"TimeoutMinutes": 10,
"EnableDetailedErrorLogging": false
},
"Cors": {
"AllowedOrigins": ["https://myapp.example.com"]
}
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
---
# secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: webinteract-mcp-secrets
namespace: webinteract-mcp
type: Opaque
data:
# Base64 encoded secrets
api-key: <base64-encoded-api-key>
client-secret: <base64-encoded-client-secret>
---
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: webinteract-mcp-server
namespace: webinteract-mcp
labels:
app: webinteract-mcp-server
version: v1.0.0
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
selector:
matchLabels:
app: webinteract-mcp-server
template:
metadata:
labels:
app: webinteract-mcp-server
version: v1.0.0
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "8080"
prometheus.io/path: "/metrics"
spec:
serviceAccountName: webinteract-mcp-sa
securityContext:
fsGroup: 1001
runAsNonRoot: true
runAsUser: 1001
containers:
- name: webinteract-mcp-server
image: webinteract-mcp-server:1.0.0
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: ASPNETCORE_ENVIRONMENT
value: "Production"
- name: ASPNETCORE_URLS
value: "http://+:8080"
- name: DOTNET_gcServer
value: "1"
envFrom:
- secretRef:
name: webinteract-mcp-secrets
volumeMounts:
- name: config-volume
mountPath: /app/appsettings.json
subPath: appsettings.json
readOnly: true
- name: tmp-volume
mountPath: /tmp
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 5
periodSeconds: 5
timeoutSeconds: 3
failureThreshold: 3
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumes:
- name: config-volume
configMap:
name: webinteract-mcp-config
- name: tmp-volume
emptyDir: {}
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- webinteract-mcp-server
topologyKey: kubernetes.io/hostname
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: webinteract-mcp-service
namespace: webinteract-mcp
labels:
app: webinteract-mcp-server
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app: webinteract-mcp-server
---
# serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: webinteract-mcp-sa
namespace: webinteract-mcp
labels:
app: webinteract-mcp-server
---
# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webinteract-mcp-hpa
namespace: webinteract-mcp
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webinteract-mcp-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 80
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 15
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webinteract-mcp-ingress
namespace: webinteract-mcp
annotations:
kubernetes.io/ingress.class: nginx
cert-manager.io/cluster-issuer: letsencrypt-prod
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/use-regex: "true"
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
tls:
- hosts:
- mcp.example.com
secretName: webinteract-mcp-tls
rules:
- host: mcp.example.com
http:
paths:
- path: /(.*)
pathType: Prefix
backend:
service:
name: webinteract-mcp-service
port:
number: 80
Deploy the complete stack:
kubectl apply -f namespace.yaml
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f serviceaccount.yaml
kubectl apply -f hpa.yaml
kubectl apply -f ingress.yaml
Monitoring and Observability
Prometheus Integration
Add monitoring with Prometheus and Grafana:
# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: webinteract-mcp-monitor
namespace: webinteract-mcp
labels:
app: webinteract-mcp-server
spec:
selector:
matchLabels:
app: webinteract-mcp-server
endpoints:
- port: http
path: /metrics
interval: 30s
Grafana Dashboard
Create Grafana dashboard configuration:
{
"dashboard": {
"title": "WebInteract MCP Server",
"panels": [
{
"title": "Request Rate",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total{service=\"webinteract-mcp-service\"}[5m])"
}
]
},
{
"title": "Response Time",
"type": "graph",
"targets": [
{
"expr": "histogram_quantile(0.95, rate(http_request_duration_seconds_bucket{service=\"webinteract-mcp-service\"}[5m]))"
}
]
},
{
"title": "Error Rate",
"type": "graph",
"targets": [
{
"expr": "rate(http_requests_total{service=\"webinteract-mcp-service\",status=~\"5..\"}[5m])"
}
]
}
]
}
}
Security Configuration
RBAC Setup
# rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: webinteract-mcp
name: webinteract-mcp-role
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "list"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: webinteract-mcp-rolebinding
namespace: webinteract-mcp
subjects:
- kind: ServiceAccount
name: webinteract-mcp-sa
namespace: webinteract-mcp
roleRef:
kind: Role
name: webinteract-mcp-role
apiGroup: rbac.authorization.k8s.io
Network Policies
# networkpolicy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: webinteract-mcp-netpol
namespace: webinteract-mcp
spec:
podSelector:
matchLabels:
app: webinteract-mcp-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8080
egress:
- to: []
ports:
- protocol: TCP
port: 53
- protocol: UDP
port: 53
- to:
- namespaceSelector: {}
ports:
- protocol: TCP
port: 443
Pod Security Standards
# podsecuritypolicy.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: webinteract-mcp-psp
namespace: webinteract-mcp
spec:
privileged: false
allowPrivilegeEscalation: false
requiredDropCapabilities:
- ALL
volumes:
- 'configMap'
- 'emptyDir'
- 'projected'
- 'secret'
- 'downwardAPI'
- 'persistentVolumeClaim'
runAsUser:
rule: 'MustRunAs'
ranges:
- min: 1001
max: 1001
runAsGroup:
rule: 'MustRunAs'
ranges:
- min: 1001
max: 1001
fsGroup:
rule: 'MustRunAs'
ranges:
- min: 1001
max: 1001
seLinux:
rule: 'RunAsAny'
Persistent Storage
StatefulSet with Persistent Volumes
# statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: webinteract-mcp-server
namespace: webinteract-mcp
spec:
serviceName: webinteract-mcp-service
replicas: 3
selector:
matchLabels:
app: webinteract-mcp-server
template:
metadata:
labels:
app: webinteract-mcp-server
spec:
containers:
- name: webinteract-mcp-server
image: webinteract-mcp-server:latest
volumeMounts:
- name: data-volume
mountPath: /app/data
- name: logs-volume
mountPath: /app/logs
volumeClaimTemplates:
- metadata:
name: data-volume
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "fast-ssd"
resources:
requests:
storage: 10Gi
- metadata:
name: logs-volume
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: "standard"
resources:
requests:
storage: 5Gi
Multi-Environment Setup
Development Environment
# dev-values.yaml
replicaCount: 1
image:
tag: "dev"
config:
aspnetcoreEnvironment: "Development"
mcpInteract:
tool:
enableDetailedErrorLogging: true
resources:
limits:
cpu: 200m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
autoscaling:
enabled: false
Staging Environment
# staging-values.yaml
replicaCount: 2
image:
tag: "staging"
config:
aspnetcoreEnvironment: "Staging"
ingress:
hosts:
- host: mcp-staging.example.com
resources:
limits:
cpu: 300m
memory: 384Mi
requests:
cpu: 150m
memory: 192Mi
Production Environment
# prod-values.yaml
replicaCount: 3
image:
tag: "v1.0.0"
config:
aspnetcoreEnvironment: "Production"
ingress:
hosts:
- host: mcp.example.com
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 250m
memory: 256Mi
autoscaling:
enabled: true
minReplicas: 3
maxReplicas: 10
Troubleshooting
Common Issues
Pods not starting:
# Check pod status
kubectl get pods -n webinteract-mcp
# Describe pod for events
kubectl describe pod <pod-name> -n webinteract-mcp
# Check logs
kubectl logs <pod-name> -n webinteract-mcp
# Check previous container logs
kubectl logs <pod-name> -n webinteract-mcp --previous
Service connectivity issues:
# Test service connectivity
kubectl exec -it <pod-name> -n webinteract-mcp -- curl http://webinteract-mcp-service
# Check service endpoints
kubectl get endpoints webinteract-mcp-service -n webinteract-mcp
# Port forward for testing
kubectl port-forward service/webinteract-mcp-service 8080:80 -n webinteract-mcp
Ingress issues:
# Check ingress status
kubectl get ingress -n webinteract-mcp
# Describe ingress for events
kubectl describe ingress webinteract-mcp-ingress -n webinteract-mcp
# Check ingress controller logs
kubectl logs -n ingress-nginx deployment/ingress-nginx-controller
Debug Tools
Interactive debugging:
# Run debug pod
kubectl run debug-pod --image=nicolaka/netshoot -it --rm -n webinteract-mcp
# Execute commands in existing pod
kubectl exec -it <pod-name> -n webinteract-mcp -- /bin/bash
# Copy files from pod
kubectl cp <pod-name>:/app/logs/app.log ./app.log -n webinteract-mcp
Performance Troubleshooting
Resource monitoring:
# Check resource usage
kubectl top pods -n webinteract-mcp
# Check node resource usage
kubectl top nodes
# Check HPA status
kubectl get hpa -n webinteract-mcp
# Describe HPA for scaling events
kubectl describe hpa webinteract-mcp-hpa -n webinteract-mcp
Best Practices
Resource Management
- Set resource requests and limits
- Use horizontal pod autoscaling
- Configure pod disruption budgets
- Use node affinity and anti-affinity
Security
- Run as non-root user
- Use read-only root filesystem
- Drop all capabilities
- Implement network policies
High Availability
- Deploy across multiple nodes
- Use pod anti-affinity
- Configure proper health checks
- Implement graceful shutdown
Monitoring
- Expose metrics endpoint
- Configure service monitoring
- Set up alerting rules
- Monitor resource usage
Next Steps
- Docker Deployment - Container deployment options
- Configuration Reference - Detailed configuration
- Monitoring Setup - Monitoring and alerting
- Backup and Recovery - Data protection strategies