- Descripción del Proyecto
- Guía de Despliegue
- Endpoints y API
- Monitorización
- Desarrollo y Testing
- Configuración
- Recursos Adicionales
Este proyecto implementa una aplicación web simple usando FastAPI con los siguientes componentes:
- Aplicación: Servidor web con múltiples endpoints
- Tests: Cobertura del 93.18% con pytest
- CI/CD: GitHub Actions para testing y release
- Containerización: Docker image publicada en GHCR
- Orquestación: Helm chart para Kubernetes
- Monitorización: Prometheus + Grafana + Alertmanager
La aplicación expone los siguientes endpoints:
curl http://localhost:8081/Response: {"msg": "Hello World"}
curl http://localhost:8081/byeResponse: {"msg": "Bye Bye"}
curl http://localhost:8081/healthResponse: {"health": "ok"}
curl http://localhost:8081/metricsResponse: métricas en formato Prometheus
Métricas expuestas:
server_requests_total- Total de peticiones al servidormain_requests_total- Peticiones al endpoint/bye_requests_total- Peticiones al endpoint/bye⭐ NUEVOhealthcheck_requests_total- Peticiones al endpoint/health
tests/
├── __init__.py
├── conftest.py # Configuración de pytest
└── app_test.py # Tests de los endpoints
Los tests cubren todos los endpoints con un 93.18% de cobertura:
- ✅
test_server_initialization()- Verifica la inicialización del servidor - ✅
test_server_configuration()- Verifica la configuración del servidor - ✅
test_read_health()- Verifica endpoint/health - ✅
test_read_main()- Verifica endpoint/ - ✅
test_read_bye()- Verifica endpoint/bye - ✅
test_metrics()- Verifica endpoint/metrics - ✅
test_multiple_requests()- Verifica múltiples peticiones - ✅
test_fastapi_app_metadata()- Verifica metadata de la aplicación - ✅
test_concurrent_requests()- Verifica peticiones concurrentes - ✅
test_counter_reset()- Verifica reset de contadores - ✅
test_metrics_content_type()- Verifica content type de métricas - ✅
test_hypercorn_config()- Verifica configuración de Hypercorn
python3 -m venv venvsource venv/bin/activatepip install -r requirements.txtpytest --cov --cov-report=term -vpytest --cov --cov-report=htmlopen htmlcov/index.html---------- coverage: platform linux, python 3.12.3-final-0 -----------
Name Stmts Miss Branch BrPart Cover
----------------------------------------------------------------
src/__init__.py 0 0 0 0 100.00%
src/application/__init__.py 0 0 0 0 100.00%
src/application/app.py 36 3 8 0 93.18%
----------------------------------------------------------------
TOTAL 36 3 8 0 93.18%
El proyecto implementa dos workflows de GitHub Actions:
Trigger: Push o Pull Request a cualquier rama
Pasos:
- Checkout del código
- Setup de Python 3.11.8
- Instalación de dependencias
- Ejecución de tests con coverage
- Generación de reportes de cobertura
- Comentario automático en PRs con el coverage
Ejemplo de ejecución: Ver en GitHub Actions:
https://github.com/jpalenz77/KC-liberando-productos-practica-final/actionsResultado esperado:
- ✅ Tests passing
- ✅ Coverage > 70%
- ✅ Comentario automático en PR con cobertura
Trigger: Push de tags con formato v* (ejemplo: v1.0.0)
Pasos:
- Checkout del código
- Setup de Docker Buildx
- Login en GitHub Container Registry (GHCR)
- Extracción de metadata (tags)
- Build y push de la imagen Docker
Estrategia de tags:
Para un tag v1.2.3, se generan automáticamente:
ghcr.io/jpalenz77/kc-liberando-productos-practica-final:1.2.3ghcr.io/jpalenz77/kc-liberando-productos-practica-final:1.2ghcr.io/jpalenz77/kc-liberando-productos-practica-final:1ghcr.io/jpalenz77/kc-liberando-productos-practica-final:latest
Crear un release:
git tag -a v1.0.0 -m "Release version 1.0.0"git push origin v1.0.0docker pull ghcr.io/jpalenz77/kc-liberando-productos-practica-final:latesthelm/simple-server/
├── Chart.yaml # Metadata del chart
├── values.yaml # Valores configurables
└── templates/
├── _helpers.tpl # Funciones helper
├── deployment.yaml # Deployment con la app
├── service.yaml # Service (ClusterIP)
├── serviceaccount.yaml # ServiceAccount
├── hpa.yaml # HorizontalPodAutoscaler
├── ingress.yaml # Ingress (opcional)
├── service_monitor.yaml # ServiceMonitor (Prometheus)
└── dockerhub_access.yaml # Secret para GHCR
- ✅ Deployment: 1-100 réplicas con autoscaling
- ✅ Service: Expone puerto 8081 (app) y 8000 (metrics)
- ✅ HPA: Autoscaling basado en CPU (70%) y memoria (70%)
- ✅ ServiceMonitor: Integración automática con Prometheus
- ✅ Health Checks: Liveness y Readiness probes
- ✅ Resources: Limits y requests configurados
helm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo updatehelm install simple-server ./helm/simple-server --namespace simple-server --create-namespace --set image.repository=ghcr.io/jpalenz77/kc-liberando-productos-practica-final --set image.tag=latestkubectl get pods -n simple-serverkubectl get svc -n simple-serverkubectl get hpa -n simple-serverkubectl get servicemonitor -n simple-serverkubectl logs -n simple-server -l app.kubernetes.io/name=simple-server -fkubectl port-forward -n simple-server svc/simple-server 8081:8081curl http://localhost:8081/curl http://localhost:8081/byecurl http://localhost:8081/healthcurl http://localhost:8081/metricsCrear namespace:
kubectl create namespace monitoringInstalar Prometheus Operator + Grafana + Alertmanager:
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --values monitoring/kube-prometheus-stack/values.yaml \
--set alertmanager.config.global.slack_api_url='https://hooks.slack.com/services/XXX/YYY/ZZZ'💡 Importante: En el parámetro
--set alertmanager.config.global.slack_api_url, debes poner el webhook de Slack que has obtenido anteriormente. No compartas este webhook públicamente.
Ver todos los pods de monitoring:
kubectl get pods -n monitoringDeberías ver:
- prometheus-operator
- prometheus-prometheus-kube-prometheus-prometheus-0
- alertmanager-prometheus-kube-prometheus-alertmanager-0
- prometheus-grafana-xxx
- prometheus-kube-state-metrics-xxx
- prometheus-prometheus-node-exporter-xxx
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090open http://localhost:9090- Ve a Status → Targets
- Busca el job
simple-server - Debería estar en estado UP
Total de requests:
server_requests_total
Rate de requests por segundo:
rate(server_requests_total[5m])
Requests al endpoint /bye:
bye_requests_total
Rate del endpoint /bye:
rate(bye_requests_total[5m])
Comparar todos los endpoints:
sum by (endpoint) (rate(server_requests_total[5m]))
Reinicios de la aplicación:
kube_pod_container_status_restarts_total{pod=~".*simple-server.*"}
El webhook de Slack contiene información sensible y NUNCA debe ser commiteado al repositorio.
Pasos para configurar:
-
Crear canal en Slack:
#josepalenzuela-prometheus-alarms -
Crear Incoming Webhook:
- Ve a https://api.slack.com/apps
- Create New App → From scratch
- Nombre: "Prometheus Alertmanager"
- Incoming Webhooks → Activate → Add New Webhook
- Selecciona tu canal
- Copia la URL del webhook
-
Instalar Prometheus con el webhook (usando --set):
Opción 1: Mediante --set en la línea de comandos (RECOMENDADO)
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --values monitoring/kube-prometheus-stack/values.yaml --set alertmanager.config.global.slack_api_url='https://hooks.slack.com/services/YOUR/WEBHOOK/HERE'Opción 2: Crear archivo secrets.yaml local (NO hacer commit)
Copiar el ejemplo:
cp monitoring/kube-prometheus-stack/secrets.example.yaml monitoring/kube-prometheus-stack/secrets.yamlEditar con tu webhook real:
nano monitoring/kube-prometheus-stack/secrets.yamlInstalar con ambos archivos:
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --values monitoring/kube-prometheus-stack/values.yaml --values monitoring/kube-prometheus-stack/secrets.yamlOpción 3: Variable de entorno
Exportar como variable de entorno:
export SLACK_WEBHOOK='https://hooks.slack.com/services/YOUR/WEBHOOK/HERE'Usar en helm:
helm install prometheus prometheus-community/kube-prometheus-stack --namespace monitoring --values monitoring/kube-prometheus-stack/values.yaml --set alertmanager.config.global.slack_api_url="$SLACK_WEBHOOK"Este documento sirve como referencia para el monitoreo (Alerts) y como guía para realizar pruebas de rendimiento y escalado (Stress Test) sobre el despliegue de Kubernetes simple-server.
Lista detallada de las reglas de alerta configuradas en nuestro sistema de monitoreo, categorizadas por severidad y tiempo de activación.
| Categoría | Alerta | Condición | Duración | Impacto |
|---|
| Alerta | Condición | Retardo (Duración) | Descripción de Impacto |
|---|---|---|---|
| SimpleServerDown | Pod caído o no disponible. | 1 minuto | Interrupción del servicio. Requiere acción inmediata. |
| SimpleServerMemoryLimitReached | Uso de memoria > 90% del límite. | 1 minuto | Riesgo inminente de OOMKill (eliminación por falta de memoria). |
| SimpleServerConsumingMoreThanRequest | Uso de memoria real > límite de request. | 2 minutos | Saturación de recursos del nodo. |
| SimpleServerCPUThrottlingHigh | Limitación de CPU (Throttling) > 25%. | 5 minutos | Degradación grave del rendimiento. |
| Alerta | Condición | Retardo (Duración) | Descripción de Impacto |
|---|---|---|---|
| SimpleServerPodRestarting | El Pod en ciclo de reinicios. | 5 minutos | Inestabilidad del servicio. |
| SimpleServerCPUConsumingMoreThanRequest | Uso de CPU real > límite de request. | 2 minutos | Consumo ineficiente, potencial latencia. |
| SimpleServerHighRequestRate | Tasa de peticiones > 100 req/s. | 5 minutos | Alerta de tráfico elevado. |
| SimpleServerNoRequests | No se han recibido peticiones. | 10 minutos | Indicio de problema en el balanceador. |
Este procedimiento utiliza la herramienta NodeWrecker para generar una carga artificial intensa (CPU y Memoria) dentro de un pod. El objetivo es validar el Horizontal Pod Autoscaler (HPA).
- Acceso kubectl configurado al clúster.
- El Pod debe tener permisos para ejecutar apk y go build.
Obtén el nombre del pod de simple-server.
kubectl get pods -n simple-serverEjemplo de salida: simple-server-b87696dcc-gzzzz
Abre una sesión interactiva. Reemplaza "simple-server-xxxxxxxx-yyyyy" con el nombre del pod obtenido en el paso anterior:
kubectl -n simple-server exec --stdin --tty simple-server-xxxxxxxx-yyyyy -c simple-server -- /bin/shDentro del pod, instala las herramientas necesarias (git y go).
apk updateapk add git goDescarga y genera el binario ejecutable (extress):
git clone https://github.com/jaeg/NodeWrecker.gitcd NodeWreckergo build -o extress main.goInicia la carga intensiva sobre el Pod.
./extress -abuse-memory -escalate -max-duration 10000000Consejo: Detén la prueba manualmente en cualquier momento con Ctrl + C.
En una terminal NUEVA (fuera del pod), observa el comportamiento del autoscaler.
kubectl -n simple-server get hpa -wEn otra terminal NUEVA, sigue la creación de réplicas.
kubectl -n simple-server get pods -wDetén la ejecución de extress (Ctrl + C) en la sesión del pod. El HPA iniciará el downscaling.
kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-alertmanager 9093:9093open http://localhost:9093kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80open http://localhost:3000Obtener la contraseña de administrador:
kubectl get secret prometheus-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode ; echo💡 Importante: Guarda la contraseña de Grafana y el webhook de Slack en un lugar seguro, los necesitarás para acceder al dashboard y configurar alertas en Slack. Nunca compartas el webhook públicamente.
Opción 1: Mediante ConfigMap (Automático)
Aplicar el ConfigMap:
kubectl apply -f monitoring/grafana/simple-server-dashboard-configmap.yamlEl dashboard aparecerá automáticamente en Grafana.
Opción 2: Import Manual
- En Grafana, click en + → Import
- Click en Upload JSON file
- Selecciona
monitoring/grafana/dashboards/simple-server-dashboard.json - Selecciona datasource: Prometheus
- Click Import
El dashboard "Simple Server - Application Metrics" incluye:
- Total Requests - Total de peticiones al servidor
- Main Endpoint (/) Calls - Llamadas a
/ - Bye Endpoint (/bye) Calls - Llamadas a
/bye⭐ - Application Restarts - Número de reinicios ⭐
- Request Rate by Endpoint - Peticiones/segundo por endpoint
- Cumulative Requests by Endpoint - Requests totales acumulados
kubectl port-forward -n simple-server svc/simple-server 8081:8081 &
for i in {1..1000}; do
curl -s http://localhost:8081/ > /dev/null
curl -s http://localhost:8081/bye > /dev/null
curl -s http://localhost:8081/health > /dev/null
sleep 0.1
doneSi haces cambios en el dashboard:
- Click en el icono de configuración (⚙️) → JSON Model
- Copia el JSON
- Guarda en
monitoring/grafana/dashboards/simple-server-dashboard.json
- Usuario: admin
- Obtener contraseña:
kubectl get secret prometheus-grafana -n monitoring -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
💡 Importante: Guarda la contraseña de Grafana y el webhook de Slack en un lugar seguro, los necesitarás para acceder al dashboard y configurar alertas en Slack. Nunca compartas el webhook públicamente.
- Aplicación: http://localhost:8081
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000
- Alertmanager: http://localhost:9093
- Docker
- Kubernetes (Minikube, Kind, K3s, o cluster real)
- kubectl configurado
- Helm 3.x
- Git
- Slack configurado (con webhook para alertas)
Iniciar minikube con los recursos necesarios:
minikube start --cpus=4 --memory=8192 --driver=dockerHabilitar el addon metrics-server:
minikube addons enable metrics-serverVerificar que el nodo está funcionando:
kubectl get nodeshelm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo updatekubectl create namespace monitoringhelm install prometheus prometheus-community/kube-prometheus-stack \
--namespace monitoring --create-namespace \
--values monitoring/kube-prometheus-stack/values.yaml \
--set alertmanager.config.global.slack_api_url='https://hooks.slack.com/services/XXX/YYY/ZZZ'💡 Importante: En el parámetro
--set alertmanager.config.global.slack_api_url, debes poner el webhook de Slack que has obtenido anteriormente. No compartas este webhook públicamente.
kubectl get pods -n monitoring -wkubectl create namespace simple-serverhelm install simple-server ./helm/simple-server --namespace simple-server --set image.repository=ghcr.io/jpalenz77/kc-liberando-productos-practica-final --set image.tag=latest --set metrics.enabled=truekubectl get pods -n simple-serverkubectl get svc -n simple-serverkubectl get servicemonitor -n simple-serverkubectl apply -f monitoring/grafana/simple-server-dashboard-configmap.yamlkubectl get configmap -n monitoring simple-server-dashboardkubectl apply -f monitoring/grafana/simple-server-dashboard-configmap.yaml
kubectl get configmap -n monitoring simple-server-dashboardkubectl port-forward -n simple-server svc/simple-server 8081:8081kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-alertmanager 9093:9093kubectl port-forward -n simple-server svc/simple-server 8081:8081kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-prometheus 9090:9090kubectl port-forward -n monitoring svc/prometheus-grafana 3000:80kubectl port-forward -n monitoring svc/prometheus-kube-prometheus-alertmanager 9093:9093URLs:
- Aplicación: http://localhost:8081
- Prometheus: http://localhost:9090
- Grafana: http://localhost:3000 (admin / prom-operator)
- Alertmanager: http://localhost:9093
curl http://localhost:8081/
curl http://localhost:8081/bye
curl http://localhost:8081/health
curl http://localhost:8081/metrics
kubectl scale deployment simple-server -n simple-server --replicas=0
kubectl scale deployment simple-server -n simple-server --replicas=2python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
pip install -r requirements.txt
pytest --cov -vdocker build -t simple-server:test .
docker build -t simple-server:test . --progress=plainkubectl describe pod -n simple-server <pod-name>
kubectl logs -n simple-server <pod-name>
kubectl get events -n simple-server --sort-by='.lastTimestamp'kubectl get servicemonitor -n simple-server -o yaml
kubectl get svc -n simple-server -o yaml
kubectl logs -n monitoring prometheus-prometheus-kube-prometheus-prometheus-0kubectl get configmap -n monitoring simple-server-dashboard
kubectl get configmap -n monitoring simple-server-dashboard -o yaml | grep labels -A 5
kubectl rollout restart deployment -n monitoring prometheus-grafanakubectl get secret -n monitoring alertmanager-prometheus-kube-prometheus-alertmanager -o yaml
kubectl logs -n monitoring alertmanager-prometheus-kube-prometheus-alertmanager-0
curl -X POST -H 'Content-type: application/json' --data '{"text":"Test from curl"}' YOUR_SLACK_WEBHOOK_URL