46 KiB
అమరిక వ్యూహాలు
🎯 ఈ ప్రయోగశాలలో ఏమి ఉంటుంది
ఈ ప్రయోగశాల ఆధునిక కంటైనరైజేషన్ మరియు క్లౌడ్-నేటివ్ విధానాలను ఉపయోగించి మీ MCP రిటైల్ సర్వర్ను ఉత్పత్తి వాతావరణాల్లో అమర్చడానికి సమగ్ర మార్గదర్శకాన్ని అందిస్తుంది. మీరు ఎంటర్ప్రైజ్ వర్క్లోడ్లను నిర్వహించగల, స్కేలబుల్, సురక్షిత మరియు పర్యవేక్షించబడే MCP సర్వర్లను అమర్చడం నేర్చుకుంటారు.
అవలోకనం
MCP సర్వర్ల ఉత్పత్తి అమరికకు కంటైనరైజేషన్, ఆర్కెస్ట్రేషన్, సెక్యూరిటీ, స్కేలబిలిటీ మరియు పర్యవేక్షణపై జాగ్రత్తగా పరిగణించాలి. ఈ ప్రయోగశాల Azure Container Apps తో PostgreSQL Flexible Server, CI/CD పైప్లైన్ల అమలు, మరియు వేరువేరు వర్క్లోడ్ల కోసం ఆటో-స్కేలింగ్ కాన్ఫిగరేషన్ను కవర్ చేస్తుంది.
అమరిక వ్యూహాలు అభివృద్ధి కోసం సులభమైన సింగిల్-కంటైనర్ అమరికల నుండి సమగ్ర పర్యవేక్షణ మరియు సెక్యూరిటీ ఫీచర్లతో కూడిన బహుళ-ప్రాంత, ఆటో-స్కేలింగ్ ఉత్పత్తి వాతావరణాల వరకు విస్తరించాయి.
నేర్చుకునే లక్ష్యాలు
ఈ ప్రయోగశాల ముగింపు వరకు, మీరు చేయగలుగుతారు:
- కంటైనరైజ్ MCP సర్వర్లను Docker ఉపయోగించి మల్టీ-స్టేజ్ బిల్డ్స్ తో
- అమర్చు Azure Container Apps లో సురక్షిత నెట్వర్కింగ్ తో
- కాన్ఫిగర్ అధిక లభ్యతతో ఉత్పత్తి-గ్రేడ్ PostgreSQL
- అమలు CI/CD పైప్లైన్లను ఆటోమేటెడ్ అమరిక కోసం
- స్కేలు డిమాండ్ ఆధారంగా ఆటోమేటిక్గా అప్లికేషన్లను
- పర్యవేక్షించు సమగ్ర పర్యవేక్షణతో ఉత్పత్తి అమరికలను
🐳 Docker కంటైనరైజేషన్
మల్టీ-స్టేజ్ Dockerfile
# Dockerfile - Production-ready multi-stage build
FROM python:3.11-slim AS builder
# Set build environment
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PIP_NO_CACHE_DIR=1 \
PIP_DISABLE_PIP_VERSION_CHECK=1
# Install build dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# Create virtual environment
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
# Copy requirements and install dependencies
COPY requirements.lock.txt /tmp/
RUN pip install --no-cache-dir -r /tmp/requirements.lock.txt
# Production stage
FROM python:3.11-slim AS production
# Set production environment
ENV PYTHONDONTWRITEBYTECODE=1 \
PYTHONUNBUFFERED=1 \
PATH="/opt/venv/bin:$PATH" \
PYTHONPATH="/app"
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
libpq5 \
curl \
&& rm -rf /var/lib/apt/lists/* \
&& groupadd -r mcp \
&& useradd -r -g mcp -d /app -s /bin/bash mcp
# Copy virtual environment from builder
COPY --from=builder /opt/venv /opt/venv
# Set working directory and copy application
WORKDIR /app
COPY --chown=mcp:mcp . .
# Create necessary directories with proper permissions
RUN mkdir -p /app/logs /app/data /tmp/mcp \
&& chown -R mcp:mcp /app /tmp/mcp \
&& chmod -R 755 /app
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD python -m mcp_server.health_check || exit 1
# Switch to non-root user
USER mcp
# Expose port
EXPOSE 8000
# Default command
CMD ["python", "-m", "mcp_server.main"]
అభివృద్ధి కోసం Docker Compose
# docker-compose.yml - Development environment
version: '3.8'
services:
mcp-server:
build:
context: .
dockerfile: Dockerfile
target: production
ports:
- "8000:8000"
environment:
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- POSTGRES_DB=retail_db
- POSTGRES_USER=mcp_user
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- PROJECT_ENDPOINT=${PROJECT_ENDPOINT}
- AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
- AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
- AZURE_TENANT_ID=${AZURE_TENANT_ID}
- LOG_LEVEL=INFO
- ENVIRONMENT=development
depends_on:
postgres:
condition: service_healthy
volumes:
- ./logs:/app/logs
networks:
- mcp-network
restart: unless-stopped
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
postgres:
image: pgvector/pgvector:pg16
environment:
- POSTGRES_DB=retail_db
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=${POSTGRES_ADMIN_PASSWORD}
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./docker-init:/docker-entrypoint-initdb.d
- ./data:/backup
networks:
- mcp-network
restart: unless-stopped
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d retail_db"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
redis:
image: redis:7-alpine
ports:
- "6379:6379"
command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
volumes:
- redis_data:/data
networks:
- mcp-network
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "--raw", "incr", "ping"]
interval: 30s
timeout: 10s
retries: 3
volumes:
postgres_data:
driver: local
redis_data:
driver: local
networks:
mcp-network:
driver: bridge
ఉత్పత్తి Docker Compose
# docker-compose.prod.yml - Production environment
version: '3.8'
services:
mcp-server:
image: ${CONTAINER_REGISTRY}/mcp-retail-server:${IMAGE_TAG}
ports:
- "8000:8000"
environment:
- POSTGRES_HOST=${POSTGRES_HOST}
- POSTGRES_PORT=${POSTGRES_PORT}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- PROJECT_ENDPOINT=${PROJECT_ENDPOINT}
- AZURE_CLIENT_ID=${AZURE_CLIENT_ID}
- AZURE_CLIENT_SECRET=${AZURE_CLIENT_SECRET}
- AZURE_TENANT_ID=${AZURE_TENANT_ID}
- APPLICATIONINSIGHTS_CONNECTION_STRING=${APPLICATIONINSIGHTS_CONNECTION_STRING}
- LOG_LEVEL=INFO
- ENVIRONMENT=production
- REDIS_URL=${REDIS_URL}
deploy:
replicas: 3
resources:
limits:
cpus: '2.0'
memory: 2G
reservations:
cpus: '0.5'
memory: 512M
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
failure_action: rollback
networks:
- mcp-network
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
networks:
mcp-network:
external: true
☁️ Azure Container Apps అమరిక
Bicep తో ఇన్ఫ్రాస్ట్రక్చర్ కోడ్
// infra/container-apps.bicep - Azure Container Apps deployment
@description('Location for all resources')
param location string = resourceGroup().location
@description('Environment name')
param environmentName string
@description('Container App name')
param containerAppName string
@description('Container registry details')
param containerRegistry object
@description('Database connection details')
@secure()
param databaseConnectionString string
@description('Azure OpenAI configuration')
param azureOpenAI object
@description('Application Insights workspace ID')
param workspaceId string
// Container Apps Environment
resource containerAppsEnvironment 'Microsoft.App/managedEnvironments@2023-05-01' = {
name: '${environmentName}-env'
location: location
properties: {
appLogsConfiguration: {
destination: 'log-analytics'
logAnalyticsConfiguration: {
customerId: workspaceId
}
}
infrastructureResourceGroup: '${environmentName}-infra-rg'
}
}
// Container App
resource mcp_retail_server 'Microsoft.App/containerApps@2023-05-01' = {
name: containerAppName
location: location
properties: {
managedEnvironmentId: containerAppsEnvironment.id
configuration: {
activeRevisionsMode: 'Single'
ingress: {
external: false
targetPort: 8000
allowInsecure: false
traffic: [
{
weight: 100
latestRevision: true
}
]
}
registries: [
{
server: containerRegistry.server
identity: containerRegistry.identity
}
]
secrets: [
{
name: 'database-connection-string'
value: databaseConnectionString
}
{
name: 'azure-openai-key'
value: azureOpenAI.apiKey
}
]
}
template: {
containers: [
{
name: 'mcp-retail-server'
image: '${containerRegistry.server}/mcp-retail-server:latest'
resources: {
cpu: json('1.0')
memory: '2Gi'
}
env: [
{
name: 'POSTGRES_CONNECTION_STRING'
secretRef: 'database-connection-string'
}
{
name: 'PROJECT_ENDPOINT'
value: azureOpenAI.endpoint
}
{
name: 'AZURE_OPENAI_API_KEY'
secretRef: 'azure-openai-key'
}
{
name: 'LOG_LEVEL'
value: 'INFO'
}
{
name: 'ENVIRONMENT'
value: 'production'
}
]
probes: [
{
type: 'Liveness'
httpGet: {
path: '/health'
port: 8000
scheme: 'HTTP'
}
initialDelaySeconds: 60
periodSeconds: 30
timeoutSeconds: 10
failureThreshold: 3
}
{
type: 'Readiness'
httpGet: {
path: '/ready'
port: 8000
scheme: 'HTTP'
}
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 3
}
]
}
]
scale: {
minReplicas: 2
maxReplicas: 20
rules: [
{
name: 'http-scaling'
http: {
metadata: {
concurrentRequests: '10'
}
}
}
{
name: 'cpu-scaling'
custom: {
type: 'cpu'
metadata: {
type: 'Utilization'
value: '70'
}
}
}
]
}
}
}
}
// Output the FQDN
output containerAppFQDN string = mcp_retail_server.properties.configuration.ingress.fqdn
output containerAppId string = mcp_retail_server.id
PostgreSQL Flexible Server
// infra/database.bicep - PostgreSQL Flexible Server
@description('Location for all resources')
param location string = resourceGroup().location
@description('PostgreSQL server name')
param serverName string
@description('Database administrator login')
param administratorLogin string
@description('Database administrator password')
@secure()
param administratorPassword string
@description('Virtual network subnet ID')
param subnetId string
@description('Private DNS zone ID')
param privateDnsZoneId string
// PostgreSQL Flexible Server
resource postgresqlServer 'Microsoft.DBforPostgreSQL/flexibleServers@2023-03-01-preview' = {
name: serverName
location: location
sku: {
name: 'Standard_D4s_v3'
tier: 'GeneralPurpose'
}
properties: {
administratorLogin: administratorLogin
administratorLoginPassword: administratorPassword
version: '16'
storage: {
storageSizeGB: 128
autoGrow: 'Enabled'
type: 'PremiumSSD'
}
backup: {
backupRetentionDays: 35
geoRedundantBackup: 'Enabled'
}
highAvailability: {
mode: 'ZoneRedundant'
}
network: {
delegatedSubnetResourceId: subnetId
privateDnsZoneArmResourceId: privateDnsZoneId
}
maintenanceWindow: {
dayOfWeek: 0
startHour: 2
startMinute: 0
}
}
}
// Database
resource retailDatabase 'Microsoft.DBforPostgreSQL/flexibleServers/databases@2023-03-01-preview' = {
parent: postgresqlServer
name: 'retail_db'
properties: {
charset: 'UTF8'
collation: 'en_US.utf8'
}
}
// PostgreSQL extensions
resource pgvectorExtension 'Microsoft.DBforPostgreSQL/flexibleServers/configurations@2023-03-01-preview' = {
parent: postgresqlServer
name: 'shared_preload_libraries'
properties: {
value: 'pg_stat_statements,pgaudit,vector'
source: 'user-override'
}
}
// Output connection details
output serverFQDN string = postgresqlServer.properties.fullyQualifiedDomainName
output serverId string = postgresqlServer.id
output databaseName string = retailDatabase.name
🚀 CI/CD పైప్లైన్ కాన్ఫిగరేషన్
GitHub Actions వర్క్ఫ్లో
# .github/workflows/deploy.yml - CI/CD pipeline
name: Deploy MCP Retail Server
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
inputs:
environment:
description: 'Deployment environment'
required: true
default: 'development'
type: choice
options:
- development
- staging
- production
env:
CONTAINER_REGISTRY: mcpretailregistry.azurecr.io
IMAGE_NAME: mcp-retail-server
AZURE_RESOURCE_GROUP: mcp-retail-rg
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: retail_test
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.11'
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.lock.txt
pip install pytest pytest-cov pytest-asyncio
- name: Set up test database
run: |
PGPASSWORD=postgres psql -h localhost -U postgres -d retail_test -f scripts/create_schema.sql
python scripts/generate_sample_data.py --test
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: retail_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- name: Run tests
run: |
pytest tests/ -v --cov=mcp_server --cov-report=xml --cov-report=html
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: retail_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
PROJECT_ENDPOINT: ${{ secrets.TEST_PROJECT_ENDPOINT }}
AZURE_CLIENT_ID: ${{ secrets.TEST_AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.TEST_AZURE_CLIENT_SECRET }}
AZURE_TENANT_ID: ${{ secrets.AZURE_TENANT_ID }}
- name: Upload coverage reports
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
security-scan:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
scan-type: 'fs'
scan-ref: '.'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: 'trivy-results.sarif'
- name: Run Bandit security linter
run: |
pip install bandit[toml]
bandit -r mcp_server/ -f json -o bandit-report.json
build:
runs-on: ubuntu-latest
needs: [test, security-scan]
if: github.event_name == 'push' || github.event_name == 'workflow_dispatch'
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Build and push Docker image
uses: azure/docker-login@v1
with:
login-server: ${{ env.CONTAINER_REGISTRY }}
username: ${{ secrets.REGISTRY_USERNAME }}
password: ${{ secrets.REGISTRY_PASSWORD }}
- name: Build, tag, and push image
run: |
# Generate unique tag
IMAGE_TAG="${GITHUB_SHA::8}-$(date +%s)"
# Build image
docker build \
--target production \
--tag $CONTAINER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG \
--tag $CONTAINER_REGISTRY/$IMAGE_NAME:latest \
.
# Push images
docker push $CONTAINER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
docker push $CONTAINER_REGISTRY/$IMAGE_NAME:latest
# Save tag for deployment
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
- name: Output image details
run: |
echo "Built and pushed image: $CONTAINER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG"
deploy-staging:
runs-on: ubuntu-latest
needs: build
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
environment: staging
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to staging
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
# Deploy infrastructure
az deployment group create \
--resource-group $AZURE_RESOURCE_GROUP-staging \
--template-file infra/main.bicep \
--parameters infra/main.parameters.staging.json \
--parameters containerImageTag=$IMAGE_TAG
# Update container app
az containerapp update \
--name mcp-retail-server-staging \
--resource-group $AZURE_RESOURCE_GROUP-staging \
--image $CONTAINER_REGISTRY/$IMAGE_NAME:$IMAGE_TAG
- name: Run integration tests
run: |
# Wait for deployment to be ready
sleep 60
# Run integration tests against staging
pytest tests/integration/ \
--endpoint https://mcp-retail-server-staging.azurecontainerapps.io \
--timeout 300
deploy-production:
runs-on: ubuntu-latest
needs: [build, deploy-staging]
if: github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'production'
environment: production
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Azure Login
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: Deploy to production
uses: azure/CLI@v1
with:
azcliversion: latest
inlineScript: |
# Deploy with blue-green strategy
az deployment group create \
--resource-group $AZURE_RESOURCE_GROUP-prod \
--template-file infra/main.bicep \
--parameters infra/main.parameters.prod.json \
--parameters containerImageTag=$IMAGE_TAG \
--parameters deploymentSlot=green
# Health check
az containerapp show \
--name mcp-retail-server-prod-green \
--resource-group $AZURE_RESOURCE_GROUP-prod
# Switch traffic (blue-green deployment)
az containerapp ingress traffic set \
--name mcp-retail-server-prod \
--resource-group $AZURE_RESOURCE_GROUP-prod \
--revision-weight latest=100
Azure DevOps పైప్లైన్
# azure-pipelines.yml - Azure DevOps pipeline
trigger:
branches:
include:
- main
- develop
paths:
exclude:
- docs/*
- README.md
variables:
containerRegistry: 'mcpretailregistry.azurecr.io'
imageName: 'mcp-retail-server'
imageTag: '$(Build.BuildId)'
azureServiceConnection: 'azure-service-connection'
stages:
- stage: Build
displayName: 'Build and Test'
jobs:
- job: Test
displayName: 'Run Tests'
pool:
vmImage: 'ubuntu-latest'
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_PASSWORD: postgres
POSTGRES_DB: retail_test
ports:
5432:5432
steps:
- task: UsePythonVersion@0
inputs:
versionSpec: '3.11'
displayName: 'Use Python 3.11'
- script: |
python -m pip install --upgrade pip
pip install -r requirements.lock.txt
pip install pytest pytest-cov pytest-asyncio
displayName: 'Install dependencies'
- script: |
PGPASSWORD=postgres psql -h localhost -U postgres -d retail_test -f scripts/create_schema.sql
python scripts/generate_sample_data.py --test
displayName: 'Set up test database'
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: retail_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- script: |
pytest tests/ -v --cov=mcp_server --cov-report=xml --junitxml=test-results.xml
displayName: 'Run tests'
env:
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
POSTGRES_DB: retail_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
- task: PublishTestResults@2
condition: succeededOrFailed()
inputs:
testResultsFiles: 'test-results.xml'
testRunTitle: 'Python Tests'
- task: PublishCodeCoverageResults@1
inputs:
codeCoverageTool: 'Cobertura'
summaryFileLocation: 'coverage.xml'
- job: Build
displayName: 'Build Docker Image'
dependsOn: Test
pool:
vmImage: 'ubuntu-latest'
steps:
- task: AzureCLI@2
displayName: 'Build and push Docker image'
inputs:
azureSubscription: $(azureServiceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Login to container registry
az acr login --name $(containerRegistry)
# Build and push image
docker build \
--target production \
--tag $(containerRegistry)/$(imageName):$(imageTag) \
--tag $(containerRegistry)/$(imageName):latest \
.
docker push $(containerRegistry)/$(imageName):$(imageTag)
docker push $(containerRegistry)/$(imageName):latest
- stage: Deploy_Staging
displayName: 'Deploy to Staging'
dependsOn: Build
condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
jobs:
- deployment: DeployStaging
displayName: 'Deploy to Staging Environment'
pool:
vmImage: 'ubuntu-latest'
environment: 'staging'
strategy:
runOnce:
deploy:
steps:
- task: AzureCLI@2
displayName: 'Deploy infrastructure'
inputs:
azureSubscription: $(azureServiceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group create \
--resource-group mcp-retail-staging-rg \
--template-file infra/main.bicep \
--parameters infra/main.parameters.staging.json \
--parameters containerImageTag=$(imageTag)
- stage: Deploy_Production
displayName: 'Deploy to Production'
dependsOn: Deploy_Staging
condition: and(succeeded(), eq(variables['Build.Reason'], 'Manual'))
jobs:
- deployment: DeployProduction
displayName: 'Deploy to Production Environment'
pool:
vmImage: 'ubuntu-latest'
environment: 'production'
strategy:
runOnce:
deploy:
steps:
- task: AzureCLI@2
displayName: 'Deploy to production'
inputs:
azureSubscription: $(azureServiceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
az deployment group create \
--resource-group mcp-retail-prod-rg \
--template-file infra/main.bicep \
--parameters infra/main.parameters.prod.json \
--parameters containerImageTag=$(imageTag)
📊 స్కేలింగ్ మరియు పనితీరు
ఆటో-స్కేలింగ్ కాన్ఫిగరేషన్
# k8s/hpa.yaml - Horizontal Pod Autoscaler for Kubernetes
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: mcp-retail-server-hpa
namespace: mcp-retail
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: mcp-retail-server
minReplicas: 3
maxReplicas: 50
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
- type: Pods
pods:
metric:
name: http_requests_per_second
target:
type: AverageValue
averageValue: 100
behavior:
scaleDown:
stabilizationWindowSeconds: 300
policies:
- type: Percent
value: 50
periodSeconds: 60
scaleUp:
stabilizationWindowSeconds: 60
policies:
- type: Percent
value: 100
periodSeconds: 30
- type: Pods
value: 5
periodSeconds: 30
selectPolicy: Max
పనితీరు పర్యవేక్షణ
# mcp_server/monitoring/performance.py
"""
Performance monitoring and metrics collection for production deployment.
"""
import asyncio
import time
import psutil
from typing import Dict, Any
from dataclasses import dataclass
from datetime import datetime, timedelta
import logging
@dataclass
class PerformanceMetrics:
"""Performance metrics data structure."""
timestamp: datetime
cpu_percent: float
memory_percent: float
memory_used_mb: float
active_connections: int
request_rate: float
avg_response_time: float
error_rate: float
database_connections: int
class PerformanceMonitor:
"""Monitor and collect performance metrics."""
def __init__(self, config):
self.config = config
self.logger = logging.getLogger(__name__)
# మెట్రిక్స్ సేకరణ
self.metrics_history = []
self.request_times = []
self.error_count = 0
self.request_count = 0
# డేటాబేస్ మానిటరింగ్
self.db_pool = None
async def start_monitoring(self):
"""Start continuous performance monitoring."""
self.logger.info("Starting performance monitoring")
# మెట్రిక్స్ సేకరణ టాస్క్ ప్రారంభించండి
asyncio.create_task(self._collect_metrics_loop())
asyncio.create_task(self._cleanup_old_metrics())
async def _collect_metrics_loop(self):
"""Continuously collect performance metrics."""
while True:
try:
metrics = await self._collect_current_metrics()
self.metrics_history.append(metrics)
# కీలకమైన మెట్రిక్స్ లాగ్ చేయండి
if metrics.cpu_percent > 90:
self.logger.warning(f"High CPU usage: {metrics.cpu_percent:.1f}%")
if metrics.memory_percent > 90:
self.logger.warning(f"High memory usage: {metrics.memory_percent:.1f}%")
if metrics.error_rate > 0.05: # 5% లోపాల రేటు
self.logger.warning(f"High error rate: {metrics.error_rate:.2%}")
await asyncio.sleep(30) # ప్రతి 30 సెకన్లకు సేకరించండి
except Exception as e:
self.logger.error(f"Error collecting metrics: {e}")
await asyncio.sleep(60)
async def _collect_current_metrics(self) -> PerformanceMetrics:
"""Collect current system metrics."""
# సిస్టమ్ మెట్రిక్స్
cpu_percent = psutil.cpu_percent(interval=1)
memory = psutil.virtual_memory()
# అప్లికేషన్ మెట్రిక్స్
current_time = datetime.utcnow()
recent_requests = [
req_time for req_time in self.request_times
if current_time - req_time < timedelta(minutes=1)
]
request_rate = len(recent_requests) / 60.0 # సెకనుకు అభ్యర్థనలు
# సగటు స్పందన సమయం లెక్కించండి
avg_response_time = 0.0
if hasattr(self, '_recent_response_times'):
recent_response_times = [
rt for rt in self._recent_response_times
if current_time - rt['timestamp'] < timedelta(minutes=5)
]
if recent_response_times:
avg_response_time = sum(rt['time'] for rt in recent_response_times) / len(recent_response_times)
# లోపాల రేటు లెక్కింపు
error_rate = 0.0
if self.request_count > 0:
error_rate = self.error_count / self.request_count
# డేటాబేస్ కనెక్షన్లు
db_connections = 0
if self.db_pool:
db_connections = len(self.db_pool._holders)
return PerformanceMetrics(
timestamp=current_time,
cpu_percent=cpu_percent,
memory_percent=memory.percent,
memory_used_mb=memory.used / (1024 * 1024),
active_connections=0, # కనెక్షన్ ట్రాకింగ్ తో అమలు చేయాలి
request_rate=request_rate,
avg_response_time=avg_response_time,
error_rate=error_rate,
database_connections=db_connections
)
async def _cleanup_old_metrics(self):
"""Clean up old metrics to prevent memory leaks."""
while True:
try:
cutoff_time = datetime.utcnow() - timedelta(hours=24)
# మెట్రిక్స్ చరిత్ర శుభ్రపరచండి
self.metrics_history = [
m for m in self.metrics_history
if m.timestamp > cutoff_time
]
# అభ్యర్థన సమయాలను శుభ్రపరచండి
self.request_times = [
rt for rt in self.request_times
if rt > cutoff_time
]
# కౌంటర్లను కాలానుగుణంగా రీసెట్ చేయండి
if datetime.utcnow().minute == 0: # ప్రతి గంట
self.error_count = 0
self.request_count = 0
await asyncio.sleep(3600) # ప్రతి గంట నడపండి
except Exception as e:
self.logger.error(f"Error cleaning up metrics: {e}")
await asyncio.sleep(3600)
def record_request(self, response_time: float, success: bool = True):
"""Record a request for metrics."""
current_time = datetime.utcnow()
self.request_times.append(current_time)
self.request_count += 1
if not success:
self.error_count += 1
# స్పందన సమయాన్ని రికార్డ్ చేయండి
if not hasattr(self, '_recent_response_times'):
self._recent_response_times = []
self._recent_response_times.append({
'timestamp': current_time,
'time': response_time
})
def get_current_metrics(self) -> Dict[str, Any]:
"""Get current performance metrics."""
if not self.metrics_history:
return {}
latest_metrics = self.metrics_history[-1]
return {
'timestamp': latest_metrics.timestamp.isoformat(),
'system': {
'cpu_percent': latest_metrics.cpu_percent,
'memory_percent': latest_metrics.memory_percent,
'memory_used_mb': latest_metrics.memory_used_mb
},
'application': {
'active_connections': latest_metrics.active_connections,
'request_rate': latest_metrics.request_rate,
'avg_response_time': latest_metrics.avg_response_time,
'error_rate': latest_metrics.error_rate
},
'database': {
'connections': latest_metrics.database_connections
}
}
def get_metrics_summary(self, hours: int = 24) -> Dict[str, Any]:
"""Get performance metrics summary for the specified hours."""
cutoff_time = datetime.utcnow() - timedelta(hours=hours)
recent_metrics = [
m for m in self.metrics_history
if m.timestamp > cutoff_time
]
if not recent_metrics:
return {}
# సగటులను లెక్కించండి
avg_cpu = sum(m.cpu_percent for m in recent_metrics) / len(recent_metrics)
avg_memory = sum(m.memory_percent for m in recent_metrics) / len(recent_metrics)
avg_response_time = sum(m.avg_response_time for m in recent_metrics) / len(recent_metrics)
# పీక్ లను లెక్కించండి
max_cpu = max(m.cpu_percent for m in recent_metrics)
max_memory = max(m.memory_percent for m in recent_metrics)
max_response_time = max(m.avg_response_time for m in recent_metrics)
return {
'period_hours': hours,
'averages': {
'cpu_percent': round(avg_cpu, 2),
'memory_percent': round(avg_memory, 2),
'response_time': round(avg_response_time, 3)
},
'peaks': {
'cpu_percent': round(max_cpu, 2),
'memory_percent': round(max_memory, 2),
'response_time': round(max_response_time, 3)
},
'data_points': len(recent_metrics)
}
🔐 ఉత్పత్తి సెక్యూరిటీ కాన్ఫిగరేషన్
సెక్యూరిటీ హార్డెనింగ్
# k8s/security-policy.yaml - Kubernetes security policies
apiVersion: v1
kind: SecurityContext
metadata:
name: mcp-retail-security-context
spec:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: mcp-retail-network-policy
namespace: mcp-retail
spec:
podSelector:
matchLabels:
app: mcp-retail-server
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
name: ingress-nginx
ports:
- protocol: TCP
port: 8000
egress:
- to:
- namespaceSelector:
matchLabels:
name: database
ports:
- protocol: TCP
port: 5432
- to: []
ports:
- protocol: TCP
port: 443 # HTTPS for Azure OpenAI
- protocol: TCP
port: 53 # DNS
- protocol: UDP
port: 53 # DNS
వాతావరణ కాన్ఫిగరేషన్
# scripts/setup-production-env.sh
#!/bin/bash
# ఉత్పత్తి వాతావరణం సెటప్ స్క్రిప్ట్
set -euo pipefail
echo "🔧 Setting up production environment..."
# వనరుల సమూహాలను సృష్టించండి
az group create --name "mcp-retail-prod-rg" --location "East US"
az group create --name "mcp-retail-shared-rg" --location "East US"
# కీ వాల్ట్ సృష్టించండి
echo "🔐 Creating Azure Key Vault..."
az keyvault create \
--name "mcp-retail-kv-prod" \
--resource-group "mcp-retail-shared-rg" \
--location "East US" \
--enable-rbac-authorization true
# రహస్యాలను సెట్ చేయండి
echo "🔑 Setting up secrets..."
az keyvault secret set \
--vault-name "mcp-retail-kv-prod" \
--name "postgres-password" \
--value "${POSTGRES_PASSWORD}"
az keyvault secret set \
--vault-name "mcp-retail-kv-prod" \
--name "azure-openai-key" \
--value "${AZURE_OPENAI_KEY}"
# కంటైనర్ రిజిస్ట్రీని సృష్టించండి
echo "📦 Creating container registry..."
az acr create \
--name "mcpretailregistry" \
--resource-group "mcp-retail-shared-rg" \
--sku Premium \
--admin-enabled false
# వర్చువల్ నెట్వర్క్ సృష్టించండి
echo "🌐 Creating virtual network..."
az network vnet create \
--name "mcp-retail-vnet" \
--resource-group "mcp-retail-shared-rg" \
--address-prefix "10.0.0.0/16" \
--subnet-name "container-apps" \
--subnet-prefix "10.0.1.0/24"
az network vnet subnet create \
--name "database" \
--resource-group "mcp-retail-shared-rg" \
--vnet-name "mcp-retail-vnet" \
--address-prefix "10.0.2.0/24" \
--delegations Microsoft.DBforPostgreSQL/flexibleServers
# మౌలిక సదుపాయాలను అమలు చేయండి
echo "🏗️ Deploying infrastructure..."
az deployment group create \
--resource-group "mcp-retail-prod-rg" \
--template-file "infra/main.bicep" \
--parameters "infra/main.parameters.prod.json"
echo "✅ Production environment setup complete!"
🎯 ముఖ్యమైన విషయాలు
ఈ ప్రయోగశాల పూర్తి చేసిన తర్వాత, మీ వద్ద ఉండాలి:
✅ కంటైనర్ వ్యూహం: సెక్యూరిటీ హార్డెనింగ్ తో ఉత్పత్తి-సిద్ధ Docker కంటైనర్లు
✅ క్లౌడ్ అమరిక: ఆటో-స్కేలింగ్ మరియు పర్యవేక్షణతో Azure Container Apps
✅ డేటాబేస్ అమరిక: అధిక లభ్యతతో PostgreSQL Flexible Server
✅ CI/CD పైప్లైన్లు: ఆటోమేటెడ్ పరీక్ష, బిల్డ్ మరియు అమరిక వర్క్ఫ్లోలు
✅ పనితీరు పర్యవేక్షణ: సమగ్ర మెట్రిక్స్ సేకరణ మరియు అలర్టింగ్
✅ సెక్యూరిటీ కాన్ఫిగరేషన్: ఉత్పత్తి-గ్రేడ్ సెక్యూరిటీ విధానాలు మరియు నెట్వర్క్ ఐసోలేషన్
🚀 తదుపరి ఏమిటి
Lab 11: Monitoring and Observability తో కొనసాగండి:
- అప్లికేషన్ ఇన్సైట్స్ తో సమగ్ర పర్యవేక్షణ ఏర్పాటు చేయండి
- నిర్మిత లాగింగ్ మరియు పంపిణీ ట్రేసింగ్ కాన్ఫిగర్ చేయండి
- అలర్టింగ్ మరియు ఆటోమేటెడ్ ప్రతిస్పందన వ్యవస్థలను అమలు చేయండి
- వ్యాపార మెట్రిక్స్ మరియు పనితీరు KPIs పర్యవేక్షించండి
📚 అదనపు వనరులు
కంటైనర్ సాంకేతికతలు
- Docker Best Practices - అధికారిక Docker ఉత్తమ పద్ధతులు
- Azure Container Apps - Azure Container Apps డాక్యుమెంటేషన్
- Kubernetes Documentation - Kubernetes అధికారిక డాక్యుమెంటేషన్
CI/CD మరియు DevOps
- GitHub Actions - GitHub Actions డాక్యుమెంటేషన్
- Azure DevOps - Azure DevOps సేవలు
- Infrastructure as Code - Azure Bicep డాక్యుమెంటేషన్
సెక్యూరిటీ మరియు పర్యవేక్షణ
- Azure Security Center - Azure సెక్యూరిటీ సిఫార్సులు
- Container Security - Kubernetes సెక్యూరిటీ కాన్సెప్ట్లు
- Application Insights - Azure అప్లికేషన్ ఇన్సైట్స్
మునుపటి: Lab 09: VS Code Integration
తదుపరి: Lab 11: Monitoring and Observability
అస్పష్టత:
ఈ పత్రాన్ని AI అనువాద సేవ Co-op Translator ఉపయోగించి అనువదించబడింది. మేము ఖచ్చితత్వానికి ప్రయత్నించినప్పటికీ, ఆటోమేటెడ్ అనువాదాల్లో పొరపాట్లు లేదా తప్పిదాలు ఉండవచ్చు. మూల పత్రం దాని స్వదేశీ భాషలో అధికారిక మూలంగా పరిగణించాలి. ముఖ్యమైన సమాచారానికి, ప్రొఫెషనల్ మానవ అనువాదం సిఫార్సు చేయబడుతుంది. ఈ అనువాదం వాడకం వల్ల కలిగే ఏవైనా అపార్థాలు లేదా తప్పుదారితీసే అర్థాలు కోసం మేము బాధ్యత వహించము.