Kyma/Kubernetes avec ABAP Cloud : Developper des extensions cloud-native

Catégorie
Integration
Publié
Auteur
Johannes

SAP BTP Kyma Runtime apporte Kubernetes dans le monde SAP et permet le developpement cloud-native avec des conteneurs, des microservices et des fonctions serverless. En combinaison avec ABAP Cloud, des architectures hybrides puissantes emergent, ou les workloads Kubernetes communiquent de maniere transparente avec les services backend ABAP.

Qu’est-ce que Kyma/Kubernetes dans le contexte SAP ?

Kyma est la distribution Kubernetes geree de SAP sur la Business Technology Platform. Elle est basee sur le projet open source Kyma (github.com/kyma-project) et offre un environnement Kubernetes entierement gere avec des extensions specifiques SAP.

Composants principaux de Kyma

ComposantDescriptionIntegration SAP
Kubernetes ClusterOrchestration de conteneursGere par SAP
Istio Service MeshGestion du trafic, securitemTLS automatique
Serverless FunctionsLogique pilotee par evenementsNode.js, Python
EventingIntegration basee sur les evenementsCompatible SAP Event Mesh
API GatewayExposition d’API externesProtection OAuth2/JWT
Service CatalogConnexion aux services BTPXSUAA, Destination, etc.

Bases Kubernetes pour les developpeurs SAP

Kubernetes organise les applications en plusieurs niveaux d’abstraction :

┌─────────────────────────────────────────────────────────────────────┐
│ 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 : Comparaison

SAP BTP offre deux environnements d’execution pour le developpement personnalise. Le choix depend des exigences architecturales et de l’expertise de l’equipe.

AspectCloud FoundryKyma Runtime
Niveau d’abstractionPaaS (Platform as a Service)CaaS (Container as a Service)
Unite de deploiementBuildpacks (app packagee)Images conteneur (controle total)
Mise a l’echelleInstances d’appPod-Replicas, HPA
Configurationmanifest.yml, mta.yamlYAML Kubernetes, Helm Charts
ReseauCF RouterIstio Service Mesh
ServerlessNon (apps uniquement)Oui (Kyma Functions)
Service BindingCF Service BrokerKubernetes Secrets
Barriere d’entreeBasseMoyenne a haute
FlexibiliteLimiteeTres haute
SAP CAPSupport natifSupporte
Usage typiqueApps web classiquesMicroservices, gestionnaires d’evenements

Quand choisir Kyma ?

Kyma est le bon choix quand :

  • L’equipe a une expertise conteneur
  • Une architecture microservices avec beaucoup de petits services est visee
  • Des scenarios pilotes par les evenements sont realises avec des Functions
  • Des images conteneur existantes doivent etre deployees
  • Un controle fin sur les ressources et le reseau est requis

Architecture : Extension Kyma avec backend ABAP Cloud

Le diagramme suivant montre une extension Side-by-Side typique, ou une application Kyma utilise ABAP Cloud comme backend :

┌─────────────────────────────────────────────────────────────────────────────┐
│ 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) │ │ │
│ │ └───────────────────────────┘ │ │ └────────────────────────────┘ │ │
│ │ │ │ │ │
│ └─────────────────────────────────┘ └─────────────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────────────────────────┐ │
│ │ Services BTP partages │ │
│ │ ┌──────────┐ ┌──────────────┐ ┌─────────────┐ ┌───────────────┐ │ │
│ │ │ XSUAA │ │ Destination │ │ Event Mesh │ │ Connectivity │ │ │
│ │ │ (Auth) │ │ Service │ │ │ │ (SCC) │ │ │
│ │ └──────────┘ └──────────────┘ └─────────────┘ └───────────────┘ │ │
│ └──────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘

Configuration de deploiement : YAML Kubernetes

1. Deployment pour le service backend

deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sales-extension-backend
namespace: sales-extension
labels:
app: sales-extension
component: backend
spec:
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: 5

2. Service et API Rule

service.yaml
apiVersion: v1
kind: Service
metadata:
name: sales-extension-backend
namespace: sales-extension
spec:
selector:
app: sales-extension
component: backend
ports:
- port: 8080
targetPort: 8080
type: ClusterIP
---
# api-rule.yaml
apiVersion: gateway.kyma-project.io/v1beta1
kind: APIRule
metadata:
name: sales-extension-api
namespace: sales-extension
spec:
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/token

Service Binding : Connecter ABAP Cloud avec Kyma

La connexion a ABAP Cloud se fait via le SAP Destination Service. Les credentials de destination sont montes en tant que Kubernetes Secret.

Creer un Service Binding

service-binding.yaml
apiVersion: services.cloud.sap.com/v1
kind: ServiceBinding
metadata:
name: abap-destination-binding
namespace: sales-extension
spec:
serviceInstanceName: destination-instance
secretName: abap-destination
parameters:
# La destination doit exister dans le BTP Cockpit
destinationName: "ABAP_CLOUD_BACKEND"

Utiliser la Destination dans le code (Node.js)

src/abap-client.js
const axios = require('axios');
class AbapCloudClient {
constructor() {
// Credentials depuis Kubernetes Secret (Variables d'environnement)
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() {
// Mettre en cache le token jusqu'a peu avant expiration
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 pour la gestion des evenements

Les RAP Business Events peuvent etre transmis via SAP Event Mesh aux Kyma Functions :

function.yaml
apiVersion: serverless.kyma-project.io/v1alpha2
kind: Function
metadata:
name: order-created-handler
namespace: sales-extension
spec:
runtime: nodejs18
source:
inline:
source: |
const axios = require('axios');
module.exports = {
main: async function (event, context) {
console.log('Evenement recu:', JSON.stringify(event.data));
// Extraire les donnees d'evenement du format CloudEvents
const orderData = event.data;
const orderId = orderData.SalesOrderId;
const customerId = orderData.CustomerId;
// Notifier une API externe (ex. systeme CRM)
try {
await axios.post('https://crm-api.example.com/orders', {
sapOrderId: orderId,
customerId: customerId,
status: 'CREATED"
});
return { statusCode: 200, body: 'Notification envoyee' };
} catch (error) {
console.error('Notification CRM echouee:', 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: exact

Cas d’usage pratique : Extension Side-by-Side

Scenario : Calcul de remise specifique client

Une entreprise souhaite implementer une logique de remise specifique client qui :

  • Lit les donnees client depuis ABAP Cloud (donnees de base CRM)
  • Utilise un modele de machine learning pour la prediction de remise
  • Retourne les resultats en temps reel a l’application Fiori

Etapes d’implementation

1. ABAP Cloud : Service OData pour les donnees client

" CDS View pour les informations client
@EndUserText.label: 'Customer for Discount Calculation"
@AccessControl.authorizationCheck: #CHECK
define 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 : Service de remise avec integration ML

discount-service/src/index.js
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. Recuperer les donnees client depuis ABAP Cloud
const customer = await abapClient.getCustomer(customerId);
// 2. Appeler le modele ML pour la prediction de remise
const predictedDiscount = await mlPredictor.predict({
customerTier: customer.CustomerTier,
totalRevenue: customer.TotalRevenue,
ordersCount: customer.OrdersCount,
orderValue: parseFloat(orderValue)
});
// 3. Retourner le resultat
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 dans Fiori Elements

L’extension Kyma peut etre appelee via un Custom Controller dans l’application Fiori pour afficher la remise recommandee.

Bonnes pratiques pour Kyma avec ABAP Cloud

Securite

  • Activer la validation JWT dans les APIRules
  • Integration XSUAA pour une authentification coherente
  • Network Policies pour la communication Pod-a-Pod

Performance

  • Connection Pooling pour les connexions ABAP
  • Caching des tokens et des donnees frequemment consultees
  • Horizontal Pod Autoscaler pour la mise a l’echelle selon la charge

Monitoring

  • Prometheus/Grafana pour les metriques (integre dans Kyma)
  • Application Logging correle avec les logs ABAP
  • Distributed Tracing pour le suivi des requetes

Conclusion

La combinaison de Kyma/Kubernetes avec ABAP Cloud permet des architectures cloud-native modernes sans renoncer aux forces du backend ABAP. Alors que Cloud Foundry offre une entree plus facile, Kyma fournit une flexibilite maximale pour les scenarios microservices complexes.

Cas d’usage typiques :

  • Gestionnaires d’evenements pour les RAP Business Events
  • Passerelles API avec logique additionnelle
  • Integration ML et services externes
  • UIs personnalisees en tant qu’applications conteneurisees

La decision entre Cloud Foundry et Kyma devrait etre basee sur l’expertise de l’equipe, les exigences architecturales et la strategie a long terme. Pour les equipes avec une experience Kubernetes et des architectures microservices, Kyma est le choix naturel.