842 lines
23 KiB
Markdown
842 lines
23 KiB
Markdown
# Laravel Application Deployment auf Azure Kubernetes Service (AKS)
|
|||
|
|
|
||
|
|
Diese Terraform-Konfiguration stellt deine Laravel-Anwendung auf Azure Kubernetes Service (AKS) bereit und erstellt eine Azure PostgreSQL Datenbank.
|
||
|
|
|
||
|
|
## 📋 Inhaltsverzeichnis
|
||
|
|
|
||
|
|
- [Voraussetzungen](#voraussetzungen)
|
||
|
|
- [Architektur-Übersicht](#architektur-übersicht)
|
||
|
|
- [Schnellstart](#schnellstart)
|
||
|
|
- [Detaillierte Anleitung](#detaillierte-anleitung)
|
||
|
|
- [Konfiguration](#konfiguration)
|
||
|
|
- [Deployment](#deployment)
|
||
|
|
- [Datenbank-Wiederherstellung](#datenbank-wiederherstellung)
|
||
|
|
- [Troubleshooting](#troubleshooting)
|
||
|
|
- [Wartung](#wartung)
|
||
|
|
|
||
|
|
## Voraussetzungen
|
||
|
|
|
||
|
|
Folgende Tools müssen installiert sein:
|
||
|
|
|
||
|
|
- [Terraform](https://www.terraform.io/downloads.html) >= 1.9.0
|
||
|
|
- [Azure CLI](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli) >= 2.0
|
||
|
|
- [kubectl](https://kubernetes.io/docs/tasks/tools/) >= 1.28
|
||
|
|
- [Docker](https://docs.docker.com/get-docker/) >= 20.10
|
||
|
|
- [PHP](https://www.php.net/downloads) >= 8.2 (für lokale Laravel-Befehle)
|
||
|
|
|
||
|
|
## Architektur-Übersicht
|
||
|
|
|
||
|
|
```
|
||
|
|
┌─────────────────────────────────────────────────────────────┐
|
||
|
|
│ Azure Cloud │
|
||
|
|
│ │
|
||
|
|
│ ┌────────────────────────────────────────────────────────┐ │
|
||
|
|
│ │ Resource Group: trusted_ai_demo_rg │ │
|
||
|
|
│ │ │ │
|
||
|
|
│ │ ┌──────────────────────────────────────────────────┐ │ │
|
||
|
|
│ │ │ AKS Cluster: trai_k8s_cluster │ │ │
|
||
|
|
│ │ │ │ │ │
|
||
|
|
│ │ │ ┌────────────────────────────────────────────┐ │ │ │
|
||
|
|
│ │ │ │ Namespace: laravel-app │ │ │ │
|
||
|
|
│ │ │ │ │ │ │ │
|
||
|
|
│ │ │ │ • Deployment (2+ Pods) │ │ │ │
|
||
|
|
│ │ │ │ • Service (ClusterIP) │ │ │ │
|
||
|
|
│ │ │ │ • ConfigMaps & Secrets │ │ │ │
|
||
|
|
│ │ │ │ • Horizontal Pod Autoscaler │ │ │ │
|
||
|
|
│ │ │ └────────────────────────────────────────────┘ │ │ │
|
||
|
|
│ │ │ │ │ │
|
||
|
|
│ │ │ ┌────────────────────────────────────────────┐ │ │ │
|
||
|
|
│ │ │ │ Namespace: ingress-nginx │ │ │ │
|
||
|
|
│ │ │ │ │ │ │ │
|
||
|
|
│ │ │ │ • Nginx Ingress Controller │ │ │ │
|
||
|
|
│ │ │ │ • LoadBalancer Service (Public IP) │ │ │ │
|
||
|
|
│ │ │ └────────────────────────────────────────────┘ │ │ │
|
||
|
|
│ │ └──────────────────────────────────────────────────┘ │ │
|
||
|
|
│ │ │ │
|
||
|
|
│ │ ┌──────────────────────────────────────────────────┐ │ │
|
||
|
|
│ │ │ Azure PostgreSQL Flexible Server │ │ │
|
||
|
|
│ │ │ │ │ │
|
||
|
|
│ │ │ • PostgreSQL 16 │ │ │
|
||
|
|
│ │ │ • 32 GB Storage │ │ │
|
||
|
|
│ │ │ • Automated Backups (7 days) │ │ │
|
||
|
|
│ │ └──────────────────────────────────────────────────┘ │ │
|
||
|
|
│ └────────────────────────────────────────────────────────┘ │
|
||
|
|
└─────────────────────────────────────────────────────────────┘
|
||
|
|
```
|
||
|
|
|
||
|
|
### Komponenten:
|
||
|
|
|
||
|
|
1. **AKS Cluster**: Bestehender Kubernetes-Cluster
|
||
|
|
2. **Laravel Application**: Containerisierte Laravel-App mit Nginx + PHP-FPM
|
||
|
|
3. **PostgreSQL Database**: Azure Database for PostgreSQL Flexible Server
|
||
|
|
4. **Nginx Ingress Controller**: Load Balancer für externen Zugriff
|
||
|
|
5. **Secrets Management**: Kubernetes Secrets für sensible Daten
|
||
|
|
|
||
|
|
## Schnellstart
|
||
|
|
|
||
|
|
### 1. Azure CLI Login
|
||
|
|
|
||
|
|
```bash
|
||
|
|
az login
|
||
|
|
az account set --subscription "77677a80-2dea-493d-9867-f1c961b80fb3"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 2. Docker Image erstellen und pushen
|
||
|
|
|
||
|
|
Erstelle zuerst eine Azure Container Registry (falls noch nicht vorhanden):
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Container Registry erstellen
|
||
|
|
az acr create \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name mylaravelregistry \
|
||
|
|
--sku Basic \
|
||
|
|
--location germanywestcentral
|
||
|
|
|
||
|
|
# In Registry einloggen
|
||
|
|
az acr login --name mylaravelregistry
|
||
|
|
```
|
||
|
|
|
||
|
|
Dann baue und pushe das Docker Image:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Zurück zum Projekt-Root
|
||
|
|
cd /Users/sebastianfrohlich/Herd/frontend
|
||
|
|
|
||
|
|
# Docker Image bauen
|
||
|
|
docker build -t mylaravelregistry.azurecr.io/laravel-app:v1.0.0 .
|
||
|
|
|
||
|
|
# Image pushen
|
||
|
|
docker push mylaravelregistry.azurecr.io/laravel-app:v1.0.0
|
||
|
|
```
|
||
|
|
|
||
|
|
### 3. Terraform konfigurieren
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd terraform
|
||
|
|
|
||
|
|
# Kopiere die Beispiel-Konfiguration
|
||
|
|
cp terraform.tfvars.example terraform.tfvars
|
||
|
|
|
||
|
|
# Bearbeite terraform.tfvars
|
||
|
|
nano terraform.tfvars
|
||
|
|
```
|
||
|
|
|
||
|
|
Wichtige Werte in `terraform.tfvars`:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
docker_image = "mylaravelregistry.azurecr.io/laravel-app:v1.0.0"
|
||
|
|
app_key = "base64:YOUR_GENERATED_KEY" # Generiere mit: php artisan key:generate --show
|
||
|
|
postgresql_admin_password = "YourSecurePassword123!"
|
||
|
|
alert_email_address = "your-email@example.com"
|
||
|
|
```
|
||
|
|
|
||
|
|
### 4. Deployment ausführen
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Automatisches Deployment mit Script
|
||
|
|
./scripts/deploy.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
Oder manuell:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Terraform initialisieren
|
||
|
|
terraform init
|
||
|
|
|
||
|
|
# Plan überprüfen
|
||
|
|
terraform plan
|
||
|
|
|
||
|
|
# Deployment ausführen
|
||
|
|
terraform apply
|
||
|
|
```
|
||
|
|
|
||
|
|
### 5. Datenbank wiederherstellen
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Interaktives Restore-Script
|
||
|
|
./scripts/restore-db.sh
|
||
|
|
```
|
||
|
|
|
||
|
|
Oder manuell:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Setze db_restore_enabled = true in terraform.tfvars
|
||
|
|
terraform apply
|
||
|
|
```
|
||
|
|
|
||
|
|
## Detaillierte Anleitung
|
||
|
|
|
||
|
|
### Schritt 1: Azure Container Registry (ACR) Setup
|
||
|
|
|
||
|
|
Die Laravel-Anwendung muss als Docker Image bereitgestellt werden:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ACR erstellen (wenn nicht vorhanden)
|
||
|
|
az acr create \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name mylaravelregistry \
|
||
|
|
--sku Basic
|
||
|
|
|
||
|
|
# Admin-Zugriff aktivieren (optional, für einfachere Handhabung)
|
||
|
|
az acr update -n mylaravelregistry --admin-enabled true
|
||
|
|
|
||
|
|
# Login credentials abrufen
|
||
|
|
az acr credential show --name mylaravelregistry
|
||
|
|
|
||
|
|
# Docker login
|
||
|
|
az acr login --name mylaravelregistry
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 2: Docker Image Build & Push
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /Users/sebastianfrohlich/Herd/frontend
|
||
|
|
|
||
|
|
# Image mit Tag bauen
|
||
|
|
docker build -t mylaravelregistry.azurecr.io/laravel-app:latest .
|
||
|
|
docker build -t mylaravelregistry.azurecr.io/laravel-app:v1.0.0 .
|
||
|
|
|
||
|
|
# Image pushen
|
||
|
|
docker push mylaravelregistry.azurecr.io/laravel-app:latest
|
||
|
|
docker push mylaravelregistry.azurecr.io/laravel-app:v1.0.0
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 3: AKS Pull-Berechtigung für ACR
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# AKS Pull-Berechtigung für ACR erteilen
|
||
|
|
az aks update \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name trai_k8s_cluster \
|
||
|
|
--attach-acr mylaravelregistry
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 4: Laravel APP_KEY generieren
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /Users/sebastianfrohlich/Herd/frontend
|
||
|
|
php artisan key:generate --show
|
||
|
|
```
|
||
|
|
|
||
|
|
Kopiere den Output (z.B. `base64:xyz...`) in deine `terraform.tfvars`.
|
||
|
|
|
||
|
|
### Schritt 5: Terraform Konfiguration
|
||
|
|
|
||
|
|
Erstelle `terraform/terraform.tfvars`:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
# Azure Configuration
|
||
|
|
subscription_id = "77677a80-2dea-493d-9867-f1c961b80fb3"
|
||
|
|
resource_group_name = "trusted_ai_demo_rg"
|
||
|
|
location = "germanywestcentral"
|
||
|
|
aks_cluster_name = "trai_k8s_cluster"
|
||
|
|
|
||
|
|
# Application Configuration
|
||
|
|
app_name = "laravel-app"
|
||
|
|
app_namespace = "laravel-app"
|
||
|
|
app_env = "production"
|
||
|
|
app_debug = false
|
||
|
|
app_replicas = 2
|
||
|
|
|
||
|
|
# Docker Image
|
||
|
|
docker_image = "mylaravelregistry.azurecr.io/laravel-app:v1.0.0"
|
||
|
|
|
||
|
|
# Laravel APP_KEY (generiert mit: php artisan key:generate --show)
|
||
|
|
app_key = "base64:YOUR_ACTUAL_KEY_HERE"
|
||
|
|
|
||
|
|
# PostgreSQL Configuration
|
||
|
|
postgresql_admin_username = "pgadmin"
|
||
|
|
postgresql_admin_password = "YourVerySecurePassword123!"
|
||
|
|
postgresql_sku_name = "B_Standard_B1ms"
|
||
|
|
postgresql_storage_mb = 32768
|
||
|
|
postgresql_version = "16"
|
||
|
|
postgresql_backup_retention_days = 7
|
||
|
|
|
||
|
|
# Ingress Configuration
|
||
|
|
ingress_enabled = true
|
||
|
|
ingress_host = "" # Leer lassen für IP-basierten Zugriff
|
||
|
|
|
||
|
|
# SSL/TLS Configuration (optional, später aktivieren)
|
||
|
|
ssl_enabled = false
|
||
|
|
ssl_issuer_email = ""
|
||
|
|
|
||
|
|
# Database Restore Configuration
|
||
|
|
db_restore_enabled = true
|
||
|
|
db_backup_file_path = "../backups/backup_backend_20251203_101741.dump"
|
||
|
|
|
||
|
|
# Alert Configuration
|
||
|
|
alert_email_address = "your-email@example.com"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 6: Terraform Deployment
|
||
|
|
|
||
|
|
```bash
|
||
|
|
cd /Users/sebastianfrohlich/Herd/frontend/terraform
|
||
|
|
|
||
|
|
# Terraform initialisieren
|
||
|
|
terraform init
|
||
|
|
|
||
|
|
# Validierung
|
||
|
|
terraform validate
|
||
|
|
|
||
|
|
# Plan erstellen und überprüfen
|
||
|
|
terraform plan -out=tfplan
|
||
|
|
|
||
|
|
# Deployment ausführen
|
||
|
|
terraform apply tfplan
|
||
|
|
|
||
|
|
# Outputs anzeigen
|
||
|
|
terraform output
|
||
|
|
terraform output deployment_instructions
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 7: kubectl konfigurieren
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# kubectl Credentials abrufen
|
||
|
|
az aks get-credentials \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name trai_k8s_cluster \
|
||
|
|
--overwrite-existing
|
||
|
|
|
||
|
|
# Cluster-Zugriff testen
|
||
|
|
kubectl get nodes
|
||
|
|
|
||
|
|
# Pods prüfen
|
||
|
|
kubectl get pods -n laravel-app
|
||
|
|
|
||
|
|
# Services prüfen
|
||
|
|
kubectl get svc -n laravel-app
|
||
|
|
kubectl get svc -n ingress-nginx
|
||
|
|
```
|
||
|
|
|
||
|
|
### Schritt 8: Anwendung testen
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# LoadBalancer IP abrufen
|
||
|
|
kubectl get svc ingress-nginx-controller -n ingress-nginx
|
||
|
|
|
||
|
|
# External IP sollte angezeigt werden, z.B.:
|
||
|
|
# NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
|
||
|
|
# ingress-nginx-controller LoadBalancer 10.0.45.123 20.79.123.456 80:31234/TCP,443:31567/TCP
|
||
|
|
|
||
|
|
# Anwendung im Browser öffnen:
|
||
|
|
# http://<EXTERNAL-IP>
|
||
|
|
```
|
||
|
|
|
||
|
|
### HTTP Basic Authentication
|
||
|
|
|
||
|
|
Die Anwendung ist mit HTTP Basic Auth geschützt:
|
||
|
|
|
||
|
|
- **Benutzer**: `afc-user`
|
||
|
|
- **Passwort**: `vDZFrZ+*~4gW=3^?-,:8{ga=7M.o5k,G`
|
||
|
|
|
||
|
|
Die Credentials sind in [`deploy/nginx/.htpasswd`](../deploy/nginx/.htpasswd) konfiguriert und werden während des Docker-Builds in das Image kopiert.
|
||
|
|
|
||
|
|
### Aktueller Deployment-Status
|
||
|
|
|
||
|
|
**Aktuell deployed**: Version `1.0.7`
|
||
|
|
|
||
|
|
**Aktuelle Konfiguration**:
|
||
|
|
|
||
|
|
- URL: `http://72.144.113.194/`
|
||
|
|
- Docker Image: `laravelappreg.azurecr.io/laravel-app:1.0.7`
|
||
|
|
- Replicas: 2
|
||
|
|
- Datenbank: `laravel_app` (PostgreSQL 16) mit 3 Schemas
|
||
|
|
- HTTP Basic Auth: Aktiv
|
||
|
|
|
||
|
|
**Letzte Änderungen (v1.0.7)**:
|
||
|
|
|
||
|
|
- HTTP Basic Authentication hinzugefügt
|
||
|
|
- Nginx Redirect für Livewire JavaScript (`.min.js` → `.js`)
|
||
|
|
- Alle 3 Datenbank-Schemas nach `laravel_app` migriert
|
||
|
|
- Datenbankverbindungen in `config/database.php` aktualisiert
|
||
|
|
- Session-Driver auf `database` umgestellt (Multi-Pod Support)
|
||
|
|
|
||
|
|
## Konfiguration
|
||
|
|
|
||
|
|
### Umgebungsvariablen
|
||
|
|
|
||
|
|
Die Laravel-Umgebungsvariablen werden über Kubernetes ConfigMaps und Secrets verwaltet:
|
||
|
|
|
||
|
|
**ConfigMap** (`kubernetes_config_map.app_config`):
|
||
|
|
- APP_NAME, APP_ENV, APP_DEBUG, APP_URL
|
||
|
|
- Session, Cache, Queue, Mail Konfiguration
|
||
|
|
|
||
|
|
**Secrets** (`kubernetes_secret.app_secrets`):
|
||
|
|
- APP_KEY
|
||
|
|
|
||
|
|
**Database Secrets** (`kubernetes_secret.db_credentials`):
|
||
|
|
- DB_CONNECTION, DB_HOST, DB_PORT, DB_DATABASE
|
||
|
|
- DB_USERNAME, DB_PASSWORD
|
||
|
|
|
||
|
|
### Resource Limits
|
||
|
|
|
||
|
|
Standard-Einstellungen in `variables.tf`:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
app_resources_requests_cpu = "100m"
|
||
|
|
app_resources_requests_memory = "256Mi"
|
||
|
|
app_resources_limits_cpu = "500m"
|
||
|
|
app_resources_limits_memory = "512Mi"
|
||
|
|
```
|
||
|
|
|
||
|
|
Diese können in `terraform.tfvars` überschrieben werden.
|
||
|
|
|
||
|
|
### Horizontal Pod Autoscaling
|
||
|
|
|
||
|
|
Die Anwendung skaliert automatisch basierend auf CPU und Memory:
|
||
|
|
|
||
|
|
- Min Replicas: `app_replicas` (default: 2)
|
||
|
|
- Max Replicas: `app_replicas * 3` (default: 6)
|
||
|
|
- CPU Threshold: 80%
|
||
|
|
- Memory Threshold: 80%
|
||
|
|
|
||
|
|
## Datenbank-Konfiguration
|
||
|
|
|
||
|
|
### Datenbank-Struktur
|
||
|
|
|
||
|
|
Die Anwendung verwendet **eine PostgreSQL-Datenbank** (`laravel_app`) mit **drei Schemas**:
|
||
|
|
|
||
|
|
#### 1. **public** Schema (12 Tabellen)
|
||
|
|
Standard Laravel-Tabellen und Application-Daten:
|
||
|
|
- backend_data_pool, cache, cache_locks
|
||
|
|
- companies, failed_jobs, job_batches, jobs
|
||
|
|
- migrations, password_reset_tokens, sessions
|
||
|
|
- transactions, users
|
||
|
|
|
||
|
|
**Connection**: `DB::connection('pgsql_second')` oder `DB::connection('pgsql')`
|
||
|
|
|
||
|
|
#### 2. **backend** Schema (11 Tabellen)
|
||
|
|
Backend-spezifische Daten:
|
||
|
|
- entity_corporate_context, evidence_registry
|
||
|
|
- fallback_events, internal_context_blobs
|
||
|
|
- prompt_results, prompt_runs, prompt_templates, prompt_token_metrics
|
||
|
|
- sources, transaction_outputs, transactions
|
||
|
|
|
||
|
|
**Connection**: `DB::connection('backend')`
|
||
|
|
|
||
|
|
#### 3. **devbackend** Schema (13 Tabellen)
|
||
|
|
Development/Testing Backend-Daten:
|
||
|
|
- document_facts, entity_corporate_context
|
||
|
|
- evidence_registry, fallback_events
|
||
|
|
- internal_context_blobs, pdf_documents
|
||
|
|
- prompt_results, prompt_runs, prompt_templates, prompt_token_metrics
|
||
|
|
- sources, transaction_outputs, transactions
|
||
|
|
|
||
|
|
**Connection**: `DB::connection('devbackend')`
|
||
|
|
|
||
|
|
### Verwendung in Laravel
|
||
|
|
|
||
|
|
```php
|
||
|
|
// Public Schema (Standard)
|
||
|
|
$users = DB::connection('pgsql')->table('users')->get();
|
||
|
|
$users = DB::connection('pgsql_second')->table('users')->get();
|
||
|
|
|
||
|
|
// Backend Schema
|
||
|
|
$transactions = DB::connection('backend')->table('transactions')->get();
|
||
|
|
|
||
|
|
// DevBackend Schema
|
||
|
|
$documents = DB::connection('devbackend')->table('pdf_documents')->get();
|
||
|
|
```
|
||
|
|
|
||
|
|
Alle Connections sind in [config/database.php](../config/database.php) konfiguriert und zeigen auf dieselbe Datenbank `laravel_app` mit unterschiedlichen `search_path` Einstellungen.
|
||
|
|
|
||
|
|
## Datenbank-Wiederherstellung
|
||
|
|
|
||
|
|
### Automatische Wiederherstellung während Deployment
|
||
|
|
|
||
|
|
Die Datenbank-Wiederherstellung importiert alle drei Schemas in die `laravel_app` Datenbank:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Backups befinden sich in:
|
||
|
|
/Users/sebastianfrohlich/Herd/frontend/backups/
|
||
|
|
- backup_public_20251203_101723.dump # Public Schema
|
||
|
|
- backup_backend_20251203_101741.dump # Backend Schema
|
||
|
|
- backup_devbackend_20251203_103857.dump # DevBackend Schema
|
||
|
|
```
|
||
|
|
|
||
|
|
Setze in `terraform.tfvars`:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
db_restore_enabled = true
|
||
|
|
db_backup_file_path = "../backups/backup_backend_20251203_101741.dump"
|
||
|
|
```
|
||
|
|
|
||
|
|
Das Backup wird als Kubernetes Job ausgeführt.
|
||
|
|
|
||
|
|
### Manuelle Wiederherstellung
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Interaktives Script
|
||
|
|
./scripts/restore-db.sh
|
||
|
|
|
||
|
|
# Script fragt nach:
|
||
|
|
# - Welche Backup-Datei verwendet werden soll
|
||
|
|
# - Bestätigung zum Überschreiben der Datenbank
|
||
|
|
# - Zeigt Fortschritt und Logs an
|
||
|
|
```
|
||
|
|
|
||
|
|
### Manuelles DB-Restore (kubectl)
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# ConfigMap mit Backup erstellen
|
||
|
|
kubectl create configmap db-restore-backup \
|
||
|
|
--from-file=backup.dump=/Users/sebastianfrohlich/Herd/frontend/backups/backup_backend_20251203_101741.dump \
|
||
|
|
-n laravel-app
|
||
|
|
|
||
|
|
# Job aus db-restore.tf verwenden oder manuell erstellen
|
||
|
|
kubectl apply -f - <<EOF
|
||
|
|
apiVersion: batch/v1
|
||
|
|
kind: Job
|
||
|
|
metadata:
|
||
|
|
name: db-restore-manual
|
||
|
|
namespace: laravel-app
|
||
|
|
spec:
|
||
|
|
template:
|
||
|
|
spec:
|
||
|
|
containers:
|
||
|
|
- name: db-restore
|
||
|
|
image: postgres:16-alpine
|
||
|
|
command: ["/bin/sh", "-c"]
|
||
|
|
args:
|
||
|
|
- |
|
||
|
|
set -e
|
||
|
|
export PGPASSWORD="\$DB_PASSWORD"
|
||
|
|
pg_restore -h \$DB_HOST -p \$DB_PORT -U \$DB_USERNAME -d \$DB_DATABASE \
|
||
|
|
--verbose --clean --if-exists --no-owner --no-privileges /backup/backup.dump
|
||
|
|
envFrom:
|
||
|
|
- secretRef:
|
||
|
|
name: laravel-app-db-credentials
|
||
|
|
volumeMounts:
|
||
|
|
- name: backup-volume
|
||
|
|
mountPath: /backup
|
||
|
|
volumes:
|
||
|
|
- name: backup-volume
|
||
|
|
configMap:
|
||
|
|
name: db-restore-backup
|
||
|
|
restartPolicy: OnFailure
|
||
|
|
EOF
|
||
|
|
|
||
|
|
# Job-Status prüfen
|
||
|
|
kubectl get jobs -n laravel-app
|
||
|
|
|
||
|
|
# Logs anzeigen
|
||
|
|
kubectl logs -n laravel-app -l job-name=db-restore-manual -f
|
||
|
|
```
|
||
|
|
|
||
|
|
## Deployment
|
||
|
|
|
||
|
|
### Neues Image deployen
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# 1. Neues Image bauen
|
||
|
|
docker build -t mylaravelregistry.azurecr.io/laravel-app:v1.0.1 .
|
||
|
|
docker push mylaravelregistry.azurecr.io/laravel-app:v1.0.1
|
||
|
|
|
||
|
|
# 2. terraform.tfvars aktualisieren
|
||
|
|
# docker_image = "mylaravelregistry.azurecr.io/laravel-app:v1.0.1"
|
||
|
|
|
||
|
|
# 3. Terraform apply
|
||
|
|
terraform apply
|
||
|
|
|
||
|
|
# Oder direkt kubectl verwenden für schnelleres Update:
|
||
|
|
kubectl set image deployment/laravel-app \
|
||
|
|
laravel-app=mylaravelregistry.azurecr.io/laravel-app:v1.0.1 \
|
||
|
|
-n laravel-app
|
||
|
|
|
||
|
|
# Rollout Status prüfen
|
||
|
|
kubectl rollout status deployment/laravel-app -n laravel-app
|
||
|
|
```
|
||
|
|
|
||
|
|
### Rollback
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Rollout Historie anzeigen
|
||
|
|
kubectl rollout history deployment/laravel-app -n laravel-app
|
||
|
|
|
||
|
|
# Zu vorheriger Version zurückkehren
|
||
|
|
kubectl rollout undo deployment/laravel-app -n laravel-app
|
||
|
|
|
||
|
|
# Zu spezifischer Revision zurückkehren
|
||
|
|
kubectl rollout undo deployment/laravel-app --to-revision=2 -n laravel-app
|
||
|
|
```
|
||
|
|
|
||
|
|
### Replicas skalieren
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Über kubectl
|
||
|
|
kubectl scale deployment/laravel-app --replicas=3 -n laravel-app
|
||
|
|
|
||
|
|
# Über Terraform
|
||
|
|
# Ändere app_replicas in terraform.tfvars und führe aus:
|
||
|
|
terraform apply
|
||
|
|
```
|
||
|
|
|
||
|
|
## Troubleshooting
|
||
|
|
|
||
|
|
### Pods starten nicht
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Pod-Status prüfen
|
||
|
|
kubectl get pods -n laravel-app
|
||
|
|
|
||
|
|
# Detaillierte Pod-Informationen
|
||
|
|
kubectl describe pod <pod-name> -n laravel-app
|
||
|
|
|
||
|
|
# Pod-Logs anzeigen
|
||
|
|
kubectl logs <pod-name> -n laravel-app
|
||
|
|
|
||
|
|
# Vorherige Pod-Logs (bei CrashLoopBackOff)
|
||
|
|
kubectl logs <pod-name> -n laravel-app --previous
|
||
|
|
```
|
||
|
|
|
||
|
|
### Datenbank-Verbindungsprobleme
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Secrets prüfen
|
||
|
|
kubectl get secret laravel-app-db-credentials -n laravel-app -o yaml
|
||
|
|
|
||
|
|
# PostgreSQL Server Firewall prüfen
|
||
|
|
az postgres flexible-server firewall-rule list \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name <postgresql-server-name>
|
||
|
|
|
||
|
|
# Verbindung vom Pod aus testen
|
||
|
|
kubectl run -it --rm debug --image=postgres:16-alpine -n laravel-app -- \
|
||
|
|
psql "postgresql://user:pass@host:5432/database"
|
||
|
|
```
|
||
|
|
|
||
|
|
### Ingress funktioniert nicht
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Ingress Status prüfen
|
||
|
|
kubectl get ingress -n laravel-app
|
||
|
|
|
||
|
|
# Ingress Controller Logs
|
||
|
|
kubectl logs -n ingress-nginx -l app.kubernetes.io/component=controller
|
||
|
|
|
||
|
|
# LoadBalancer Service prüfen
|
||
|
|
kubectl get svc -n ingress-nginx
|
||
|
|
|
||
|
|
# Ingress Events prüfen
|
||
|
|
kubectl describe ingress laravel-app-ingress -n laravel-app
|
||
|
|
```
|
||
|
|
|
||
|
|
### SSL/TLS Zertifikat-Probleme
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# cert-manager Pods prüfen
|
||
|
|
kubectl get pods -n cert-manager
|
||
|
|
|
||
|
|
# Certificate Status prüfen
|
||
|
|
kubectl get certificate -n laravel-app
|
||
|
|
|
||
|
|
# Certificate Details
|
||
|
|
kubectl describe certificate laravel-app-tls -n laravel-app
|
||
|
|
|
||
|
|
# cert-manager Logs
|
||
|
|
kubectl logs -n cert-manager -l app=cert-manager
|
||
|
|
```
|
||
|
|
|
||
|
|
### Performance-Probleme
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Resource Usage prüfen
|
||
|
|
kubectl top pods -n laravel-app
|
||
|
|
kubectl top nodes
|
||
|
|
|
||
|
|
# HPA Status prüfen
|
||
|
|
kubectl get hpa -n laravel-app
|
||
|
|
|
||
|
|
# Events prüfen
|
||
|
|
kubectl get events -n laravel-app --sort-by='.lastTimestamp'
|
||
|
|
```
|
||
|
|
|
||
|
|
## Wartung
|
||
|
|
|
||
|
|
### Backups
|
||
|
|
|
||
|
|
PostgreSQL Flexible Server erstellt automatische Backups:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Backup-Konfiguration prüfen
|
||
|
|
az postgres flexible-server show \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name <postgresql-server-name> \
|
||
|
|
--query "{backupRetentionDays:backup.backupRetentionDays,geoRedundantBackup:backup.geoRedundantBackup}"
|
||
|
|
|
||
|
|
# Manuelles Backup erstellen
|
||
|
|
az postgres flexible-server backup create \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--name <postgresql-server-name> \
|
||
|
|
--backup-name manual-backup-$(date +%Y%m%d)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Updates
|
||
|
|
|
||
|
|
#### Terraform Updates
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Terraform Zustand aktualisieren
|
||
|
|
terraform refresh
|
||
|
|
|
||
|
|
# Änderungen planen
|
||
|
|
terraform plan
|
||
|
|
|
||
|
|
# Änderungen anwenden
|
||
|
|
terraform apply
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Laravel Updates
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Composer Dependencies aktualisieren
|
||
|
|
composer update
|
||
|
|
|
||
|
|
# NPM Dependencies aktualisieren
|
||
|
|
npm update
|
||
|
|
|
||
|
|
# Neues Image bauen und deployen
|
||
|
|
docker build -t mylaravelregistry.azurecr.io/laravel-app:v1.0.2 .
|
||
|
|
docker push mylaravelregistry.azurecr.io/laravel-app:v1.0.2
|
||
|
|
|
||
|
|
# Deployment aktualisieren
|
||
|
|
kubectl set image deployment/laravel-app \
|
||
|
|
laravel-app=mylaravelregistry.azurecr.io/laravel-app:v1.0.2 \
|
||
|
|
-n laravel-app
|
||
|
|
```
|
||
|
|
|
||
|
|
### Monitoring
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Log Analytics Workspace
|
||
|
|
az monitor log-analytics workspace show \
|
||
|
|
--resource-group trusted_ai_demo_rg \
|
||
|
|
--workspace-name <workspace-name>
|
||
|
|
|
||
|
|
# Azure Monitor für Container
|
||
|
|
# Im Azure Portal: AKS Cluster > Monitoring > Insights
|
||
|
|
|
||
|
|
# Prometheus Metrics (wenn aktiviert)
|
||
|
|
kubectl port-forward -n ingress-nginx \
|
||
|
|
svc/ingress-nginx-controller-metrics 10254:10254
|
||
|
|
# Dann: http://localhost:10254/metrics
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cleanup
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Einzelne Resources löschen
|
||
|
|
terraform destroy -target=kubernetes_deployment.app
|
||
|
|
terraform destroy -target=azurerm_postgresql_flexible_server.main
|
||
|
|
|
||
|
|
# Alles löschen
|
||
|
|
terraform destroy
|
||
|
|
|
||
|
|
# Namespace löschen (löscht alle Resources im Namespace)
|
||
|
|
kubectl delete namespace laravel-app
|
||
|
|
```
|
||
|
|
|
||
|
|
## Kosten-Optimierung
|
||
|
|
|
||
|
|
### Development/Staging
|
||
|
|
|
||
|
|
Für Dev/Staging Umgebungen kannst du Kosten sparen:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
# terraform.tfvars für Staging
|
||
|
|
postgresql_sku_name = "B_Standard_B1ms" # Burstable tier
|
||
|
|
postgresql_storage_mb = 32768 # 32 GB
|
||
|
|
app_replicas = 1 # Weniger Replicas
|
||
|
|
aks_node_pool_min_count = 1 # Weniger Nodes
|
||
|
|
```
|
||
|
|
|
||
|
|
### Production
|
||
|
|
|
||
|
|
Für Production empfohlen:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
postgresql_sku_name = "GP_Standard_D2s_v3" # General Purpose
|
||
|
|
postgresql_storage_mb = 131072 # 128 GB
|
||
|
|
postgresql_backup_retention_days = 35 # Längere Retention
|
||
|
|
app_replicas = 3 # Mehr Replicas
|
||
|
|
```
|
||
|
|
|
||
|
|
## Sicherheit
|
||
|
|
|
||
|
|
### Best Practices
|
||
|
|
|
||
|
|
1. **Secrets Management**:
|
||
|
|
- Verwende Azure Key Vault für Production
|
||
|
|
- Rotiere Passwörter regelmäßig
|
||
|
|
- Verwende starke, generierte Passwörter
|
||
|
|
|
||
|
|
2. **Network Security**:
|
||
|
|
- Aktiviere VNet Integration für PostgreSQL
|
||
|
|
- Verwende Private Endpoints
|
||
|
|
- Beschränke Firewall-Regeln
|
||
|
|
|
||
|
|
3. **SSL/TLS**:
|
||
|
|
- Aktiviere SSL für Production:
|
||
|
|
```hcl
|
||
|
|
ssl_enabled = true
|
||
|
|
ssl_issuer_email = "admin@yourdomain.com"
|
||
|
|
ingress_host = "app.yourdomain.com"
|
||
|
|
```
|
||
|
|
|
||
|
|
4. **RBAC**:
|
||
|
|
- Verwende Kubernetes RBAC
|
||
|
|
- Minimale Berechtigungen für Service Accounts
|
||
|
|
|
||
|
|
## Support und Kontakt
|
||
|
|
|
||
|
|
Bei Fragen oder Problemen:
|
||
|
|
|
||
|
|
1. Prüfe die [Troubleshooting](#troubleshooting) Sektion
|
||
|
|
2. Prüfe Kubernetes Events: `kubectl get events -n laravel-app`
|
||
|
|
3. Prüfe Logs: `kubectl logs -n laravel-app -l app=laravel-app`
|
||
|
|
|
||
|
|
## Anhang
|
||
|
|
|
||
|
|
### Nützliche Befehle
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Alle Resources in einem Namespace anzeigen
|
||
|
|
kubectl get all -n laravel-app
|
||
|
|
|
||
|
|
# Port-forward für lokalen Zugriff
|
||
|
|
kubectl port-forward -n laravel-app svc/laravel-app 8080:80
|
||
|
|
|
||
|
|
# Shell in einem Pod öffnen
|
||
|
|
kubectl exec -it -n laravel-app <pod-name> -- /bin/sh
|
||
|
|
|
||
|
|
# ConfigMap/Secret bearbeiten
|
||
|
|
kubectl edit configmap laravel-app-config -n laravel-app
|
||
|
|
|
||
|
|
# Resource Usage live monitoren
|
||
|
|
watch kubectl top pods -n laravel-app
|
||
|
|
|
||
|
|
# Cluster Info
|
||
|
|
kubectl cluster-info
|
||
|
|
kubectl get nodes -o wide
|
||
|
|
```
|
||
|
|
|
||
|
|
### Terraform State Management
|
||
|
|
|
||
|
|
Für Team-Arbeit solltest du Remote State verwenden:
|
||
|
|
|
||
|
|
```hcl
|
||
|
|
# backend.hcl
|
||
|
|
resource_group_name = "trusted_ai_demo_rg"
|
||
|
|
storage_account_name = "tfstate<random>"
|
||
|
|
container_name = "tfstate"
|
||
|
|
key = "laravel-app.terraform.tfstate"
|
||
|
|
```
|
||
|
|
|
||
|
|
```bash
|
||
|
|
# Backend initialisieren
|
||
|
|
terraform init -backend-config=backend.hcl
|
||
|
|
```
|