SAP BTP Kyma Runtime bringt Kubernetes in die SAP-Welt und ermöglicht Cloud-native Entwicklung mit Containern, Microservices und serverless Functions. In Kombination mit ABAP Cloud entstehen leistungsfähige hybride Architekturen, bei denen Kubernetes-Workloads nahtlos mit ABAP-Backend-Services kommunizieren.
Was ist Kyma/Kubernetes im SAP-Kontext?
Kyma ist SAPs managed Kubernetes-Distribution auf der Business Technology Platform. Es basiert auf dem Open-Source-Projekt Kyma (github.com/kyma-project) und bietet eine vollständig verwaltete Kubernetes-Umgebung mit SAP-spezifischen Erweiterungen.
Kernkomponenten von Kyma
| Komponente | Beschreibung | SAP-Integration |
|---|---|---|
| Kubernetes Cluster | Container-Orchestrierung | Managed by SAP |
| Istio Service Mesh | Traffic Management, Security | Automatische mTLS |
| Serverless Functions | Event-getriebene Logik | Node.js, Python |
| Eventing | Event-basierte Integration | SAP Event Mesh kompatibel |
| API Gateway | Externe API-Exposition | OAuth2/JWT-Schutz |
| Service Catalog | BTP-Service-Anbindung | XSUAA, Destination, etc. |
Kubernetes-Grundlagen für SAP-Entwickler
Kubernetes organisiert Anwendungen in mehreren Abstraktionsebenen:
┌─────────────────────────────────────────────────────────────────────┐│ Kyma Cluster │├─────────────────────────────────────────────────────────────────────┤│ Namespace: my-extension-app ││ ┌───────────────────────────────────────────────────────────────┐ ││ │ Deployment: backend-service │ ││ │ ┌─────────────────────────────────────────────────────────┐ │ ││ │ │ Pod (Replica 1) Pod (Replica 2) │ │ ││ │ │ ┌─────────────────┐ ┌─────────────────┐ │ │ ││ │ │ │ Container: │ │ Container: │ │ │ ││ │ │ │ node:18-alpine │ │ node:18-alpine │ │ │ ││ │ │ └─────────────────┘ └─────────────────┘ │ │ ││ │ └─────────────────────────────────────────────────────────┘ │ ││ └───────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────────────────────────────┐ ││ │ Service: backend-service (ClusterIP) │ ││ │ Port: 8080 → TargetPort: 8080 │ ││ └───────────────────────────────────────────────────────────────┘ ││ │ ││ ▼ ││ ┌───────────────────────────────────────────────────────────────┐ ││ │ API Rule: backend-api (External Access via Istio Gateway) │ ││ │ Host: backend.c-abc123.kyma.ondemand.com │ ││ └───────────────────────────────────────────────────────────────┘ │└─────────────────────────────────────────────────────────────────────┘Cloud Foundry vs Kyma Runtime: Vergleich
SAP BTP bietet zwei Runtime-Umgebungen für Custom Development. Die Wahl hängt von Architekturanforderungen und Team-Expertise ab.
| Aspekt | Cloud Foundry | Kyma Runtime |
|---|---|---|
| Abstraktionsebene | PaaS (Platform as a Service) | CaaS (Container as a Service) |
| Deployment-Einheit | Buildpacks (App wird gepackt) | Container Images (volle Kontrolle) |
| Skalierung | App-Instanzen | Pod-Replicas, HPA |
| Konfiguration | manifest.yml, mta.yaml | Kubernetes YAML, Helm Charts |
| Networking | CF Router | Istio Service Mesh |
| Serverless | Nein (nur Apps) | Ja (Kyma Functions) |
| Service Binding | CF Service Broker | Kubernetes Secrets |
| Einstiegshürde | Niedrig | Mittel bis hoch |
| Flexibilität | Eingeschränkt | Sehr hoch |
| SAP CAP | Native Unterstützung | Unterstützt |
| Typischer Einsatz | Klassische Web-Apps | Microservices, Event-Handler |
Wann Kyma wählen?
Kyma ist die richtige Wahl, wenn:
- Container-Expertise im Team vorhanden ist
- Microservice-Architektur mit vielen kleinen Services angestrebt wird
- Event-getriebene Szenarien mit Functions umgesetzt werden
- Bestehende Container-Images deployed werden sollen
- Feinkörnige Kontrolle über Ressourcen und Networking erforderlich ist
Architektur: Kyma Extension mit ABAP Cloud Backend
Das folgende Diagramm zeigt eine typische Side-by-Side Extension, bei der eine Kyma-Anwendung ABAP Cloud als Backend nutzt:
┌─────────────────────────────────────────────────────────────────────────────┐│ SAP Business Technology Platform │├─────────────────────────────────────────────────────────────────────────────┤│ ││ ┌─────────────────────────────────┐ ┌─────────────────────────────────┐ ││ │ ABAP Cloud (Steampunk) │ │ Kyma Runtime │ ││ │ │ │ │ ││ │ ┌───────────────────────────┐ │ │ ┌────────────────────────────┐ │ ││ │ │ RAP Business Object │ │ │ │ Frontend (React/Vue) │ │ ││ │ │ │ │ │ │ Container: nginx │ │ ││ │ │ ┌─────────────────────┐ │ │ │ └────────────────────────────┘ │ ││ │ │ │ CDS View Entity │ │ │ │ │ │ ││ │ │ │ ZI_SalesOrder │ │ │ │ ▼ │ ││ │ │ └─────────────────────┘ │ │ │ ┌────────────────────────────┐ │ ││ │ │ ┌─────────────────────┐ │ │ │ │ Backend Service │ │ ││ │ │ │ Behavior Definition │ │ │ │ │ Container: node:18 │ │ ││ │ │ │ (Validations, etc.) │ │ │ │ │ │ │ ││ │ │ └─────────────────────┘ │ │ │ │ - Business Logic │ │ ││ │ └───────────────────────────┘ │ │ │ - Data Transformation │ │ ││ │ │ │ │ - Caching │ │ ││ │ ┌───────────────────────────┐ │ │ └────────────────────────────┘ │ ││ │ │ OData V4 Service │ │ │ │ │ ││ │ │ /sap/opu/odata4/... │◄─┼────┼──────────────┘ │ ││ │ └───────────────────────────┘ │ │ HTTP/OData │ ││ │ │ │ │ ││ │ ┌───────────────────────────┐ │ │ ┌────────────────────────────┐ │ ││ │ │ RAP Business Events │──┼────┼─>│ Kyma Function │ │ ││ │ │ (Event Mesh) │ │ │ │ (Event Handler) │ │ ││ │ └───────────────────────────┘ │ │ └────────────────────────────┘ │ ││ │ │ │ │ ││ └─────────────────────────────────┘ └─────────────────────────────────┘ ││ ││ ┌──────────────────────────────────────────────────────────────────────┐ ││ │ Shared BTP Services │ ││ │ ┌──────────┐ ┌──────────────┐ ┌─────────────┐ ┌───────────────┐ │ ││ │ │ XSUAA │ │ Destination │ │ Event Mesh │ │ Connectivity │ │ ││ │ │ (Auth) │ │ Service │ │ │ │ (SCC) │ │ ││ │ └──────────┘ └──────────────┘ └─────────────┘ └───────────────┘ │ ││ └──────────────────────────────────────────────────────────────────────┘ ││ │└─────────────────────────────────────────────────────────────────────────────┘Deployment-Konfiguration: Kubernetes YAML
1. Deployment für Backend-Service
apiVersion: apps/v1kind: Deploymentmetadata: name: sales-extension-backend namespace: sales-extension labels: app: sales-extension component: backendspec: replicas: 2 selector: matchLabels: app: sales-extension component: backend template: metadata: labels: app: sales-extension component: backend spec: containers: - name: backend image: myregistry.io/sales-extension:1.0.0 ports: - containerPort: 8080 env: - name: ABAP_CLOUD_URL valueFrom: secretKeyRef: name: abap-destination key: url - name: NODE_ENV value: "production" resources: requests: memory: "256Mi" cpu: "100m" limits: memory: "512Mi" cpu: "500m" livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 52. Service und API Rule
apiVersion: v1kind: Servicemetadata: name: sales-extension-backend namespace: sales-extensionspec: selector: app: sales-extension component: backend ports: - port: 8080 targetPort: 8080 type: ClusterIP---# api-rule.yamlapiVersion: gateway.kyma-project.io/v1beta1kind: APIRulemetadata: name: sales-extension-api namespace: sales-extensionspec: gateway: kyma-gateway.kyma-system.svc.cluster.local host: sales-extension.c-abc123.kyma.ondemand.com service: name: sales-extension-backend port: 8080 rules: - path: /.* methods: ["GET", "POST", "PUT", "DELETE"] accessStrategies: - handler: jwt config: jwks_urls: - https://mysubaccount.authentication.eu10.hana.ondemand.com/token_keys trusted_issuers: - https://mysubaccount.authentication.eu10.hana.ondemand.com/oauth/tokenService Binding: ABAP Cloud mit Kyma verbinden
Die Anbindung an ABAP Cloud erfolgt über den SAP Destination Service. Die Destination-Credentials werden als Kubernetes Secret gemounted.
Service Binding erstellen
apiVersion: services.cloud.sap.com/v1kind: ServiceBindingmetadata: name: abap-destination-binding namespace: sales-extensionspec: serviceInstanceName: destination-instance secretName: abap-destination parameters: # Destination im BTP Cockpit muss existieren destinationName: "ABAP_CLOUD_BACKEND"Destination im Code verwenden (Node.js)
const axios = require('axios');
class AbapCloudClient { constructor() { // Credentials aus Kubernetes Secret (Environment Variables) this.baseUrl = process.env.ABAP_CLOUD_URL; this.clientId = process.env.ABAP_CLIENT_ID; this.clientSecret = process.env.ABAP_CLIENT_SECRET; this.tokenUrl = process.env.ABAP_TOKEN_URL; this.accessToken = null; this.tokenExpiry = null; }
async getAccessToken() { // Token cachen bis kurz vor Ablauf if (this.accessToken && this.tokenExpiry > Date.now() + 60000) { return this.accessToken; }
const response = await axios.post(this.tokenUrl, 'grant_type=client_credentials', { headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, auth: { username: this.clientId, password: this.clientSecret } });
this.accessToken = response.data.access_token; this.tokenExpiry = Date.now() + (response.data.expires_in * 1000); return this.accessToken; }
async getSalesOrders(filter = '') { const token = await this.getAccessToken(); const url = `${this.baseUrl}/sap/opu/odata4/sap/zsalesorder/srvd/sap/zsalesorder/0001/SalesOrder`;
const response = await axios.get(url, { headers: { 'Authorization': `Bearer ${token}`, 'Accept': 'application/json' }, params: { '$filter': filter } });
return response.data.value; }
async createSalesOrder(orderData) { const token = await this.getAccessToken(); const url = `${this.baseUrl}/sap/opu/odata4/sap/zsalesorder/srvd/sap/zsalesorder/0001/SalesOrder`;
const response = await axios.post(url, orderData, { headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' } });
return response.data; }}
module.exports = AbapCloudClient;Kyma Function für Event-Handling
RAP Business Events können über SAP Event Mesh an Kyma Functions weitergeleitet werden:
apiVersion: serverless.kyma-project.io/v1alpha2kind: Functionmetadata: name: order-created-handler namespace: sales-extensionspec: runtime: nodejs18 source: inline: source: | const axios = require('axios');
module.exports = { main: async function (event, context) { console.log('Received event:', JSON.stringify(event.data));
// Event-Daten aus CloudEvents-Format extrahieren const orderData = event.data; const orderId = orderData.SalesOrderId; const customerId = orderData.CustomerId;
// Externe API benachrichtigen (z.B. CRM-System) try { await axios.post('https://crm-api.example.com/orders', { sapOrderId: orderId, customerId: customerId, status: 'CREATED' });
return { statusCode: 200, body: 'Notification sent' }; } catch (error) { console.error('CRM notification failed:', error.message); return { statusCode: 500, body: error.message }; } } }; dependencies: | { "dependencies": { "axios": "^1.6.0" } } subscriptions: - name: order-events source: sap.s4.beh.salesorder.v1.SalesOrder.Created.v1 typeMatching: exactPraktischer Use Case: Side-by-Side Extension
Szenario: Kundenspezifische Rabattberechnung
Ein Unternehmen möchte eine kundenspezifische Rabattlogik implementieren, die:
- Kundendaten aus ABAP Cloud (CRM-Stammdaten) liest
- Machine-Learning-Modell für Rabattvorhersage nutzt
- Ergebnisse in Echtzeit an die Fiori-App zurückgibt
Implementierungsschritte
1. ABAP Cloud: OData Service für Kundendaten
" CDS View für Kundeninformationen@EndUserText.label: 'Customer for Discount Calculation'@AccessControl.authorizationCheck: #CHECKdefine view entity ZI_CustomerDiscount as select from zcustomer_db{ key customer_id as CustomerId, customer_name as CustomerName, customer_tier as CustomerTier, total_revenue as TotalRevenue, orders_count as OrdersCount, last_order_date as LastOrderDate}2. Kyma: Discount-Service mit ML-Integration
const express = require('express');const AbapCloudClient = require('./abap-client');const MLPredictor = require('./ml-predictor');
const app = express();const abapClient = new AbapCloudClient();const mlPredictor = new MLPredictor();
app.get('/api/discount/:customerId', async (req, res) => { try { const { customerId } = req.params; const { orderValue } = req.query;
// 1. Kundendaten aus ABAP Cloud abrufen const customer = await abapClient.getCustomer(customerId);
// 2. ML-Modell für Rabattvorhersage aufrufen const predictedDiscount = await mlPredictor.predict({ customerTier: customer.CustomerTier, totalRevenue: customer.TotalRevenue, ordersCount: customer.OrdersCount, orderValue: parseFloat(orderValue) });
// 3. Ergebnis zurückgeben res.json({ customerId: customerId, customerName: customer.CustomerName, suggestedDiscount: predictedDiscount, maxDiscount: getMaxDiscount(customer.CustomerTier) }); } catch (error) { res.status(500).json({ error: error.message }); }});
function getMaxDiscount(tier) { const limits = { 'GOLD': 25, 'SILVER': 15, 'BRONZE': 10 }; return limits[tier] || 5;}
app.listen(8080);3. Integration in Fiori Elements
Die Kyma-Extension kann über einen Custom Controller in der Fiori-App aufgerufen werden, um den empfohlenen Rabatt anzuzeigen.
Best Practices für Kyma mit ABAP Cloud
Sicherheit
- JWT-Validierung in APIRules aktivieren
- XSUAA-Integration für konsistente Authentifizierung
- Network Policies für Pod-zu-Pod-Kommunikation
Performance
- Connection Pooling für ABAP-Verbindungen
- Caching von Token und häufig abgerufenen Daten
- Horizontal Pod Autoscaler für lastabhängige Skalierung
Monitoring
- Prometheus/Grafana für Metriken (in Kyma integriert)
- Application Logging korreliert mit ABAP-Logs
- Distributed Tracing für Request-Verfolgung
Fazit
Die Kombination von Kyma/Kubernetes mit ABAP Cloud ermöglicht moderne Cloud-native Architekturen, ohne auf die Stärken des ABAP-Backends verzichten zu müssen. Während Cloud Foundry den einfacheren Einstieg bietet, liefert Kyma maximale Flexibilität für komplexe Microservice-Szenarien.
Typische Anwendungsfälle:
- Event-Handler für RAP Business Events
- API-Gateways mit zusätzlicher Logik
- ML-Integration und externe Services
- Custom UIs als Container-Anwendungen
Die Entscheidung zwischen Cloud Foundry und Kyma sollte basierend auf Team-Expertise, Architekturanforderungen und langfristiger Strategie getroffen werden. Für Teams mit Kubernetes-Erfahrung und Microservice-Architekturen ist Kyma die natürliche Wahl.