Blog

Portworx sur OpenShift : stockage enterprise pour workloads critiques

OpenShift
Portworx
Stockage
Kubernetes
Enterprise

Déploiement et configuration de Portworx sur OpenShift pour les workloads stateful critiques. Installation via l'Operator, StorageClasses avancées, PX-Security, disaster recovery et optimisation des performances pour bases de données et Kafka.

5 février 2025

Portworx : le stockage enterprise pour Kubernetes

Portworx (PX) est une plateforme de stockage cloud-native développée par Pure Storage, conçue pour les workloads stateful critiques en production : bases de données (PostgreSQL, MySQL, MongoDB, Cassandra), files de messages (Kafka), et autres applications à fort I/O.

Par rapport aux solutions open-source, Portworx apporte :

  • IOPS élevé avec optimisation NVMe et accélération matérielle
  • PX-Security — chiffrement des volumes, RBAC stockage, authentification
  • Disaster Recovery (PX-DR) — réplication synchrone/asynchrone entre clusters
  • Auto-pilote — scaling automatique des volumes et des pools de stockage
  • PX-Backup — backup et restauration centralisés avec granularité namespace
  • Stork (Storage Orchestration Runtime for Kubernetes) — ordonnanceur qui co-localise pods et données

Architecture Portworx

┌─────────────────────────────────────────────┐
│              OpenShift Cluster               │
│                                              │
│  Node 1          Node 2          Node 3      │
│  ┌──────────┐   ┌──────────┐   ┌──────────┐ │
│  │ PX Agent │   │ PX Agent │   │ PX Agent │ │
│  │  (DaemonSet)│  │  (DaemonSet)│  │  (DaemonSet)│ │
│  └────┬─────┘   └────┬─────┘   └────┬─────┘ │
│       │              │              │        │
│  /dev/sdb        /dev/sdb       /dev/sdb     │
│  NVMe SSD        NVMe SSD       NVMe SSD     │
│                                              │
│         Portworx Storage Pool                │
│         (réplication x3)                     │
└─────────────────────────────────────────────┘

            PX-KVDB (etcd interne)

Prérequis

  • OpenShift 4.x
  • Disques raw non formatés sur chaque nœud worker (recommandé : NVMe SSD)
  • Licence Portworx Enterprise ou Essentials
  • Accès au registre registry.connect.redhat.com
# Vérifier les disques disponibles sur les nœuds
oc debug node/<nom-noeud> -- chroot /host lsblk -d | grep -v loop

Installation via l’Operator Portworx

1. Créer le namespace et les secrets de licence

oc new-project portworx

# Secret pour la licence Portworx
oc create secret generic px-license \
  --from-literal=px-license-secret=<votre-clé-licence> \
  -n portworx

2. Installer l’Operator depuis OperatorHub

apiVersion: operators.coreos.com/v1alpha1
kind: Subscription
metadata:
  name: portworx-certified
  namespace: portworx
spec:
  channel: stable
  name: portworx-certified
  source: certified-operators
  sourceNamespace: openshift-marketplace

3. Créer le StorageCluster

apiVersion: core.libopenstorage.org/v1
kind: StorageCluster
metadata:
  name: portworx-cluster
  namespace: portworx
  annotations:
    portworx.io/install-source: "https://install.portworx.com/?kbver=..."
spec:
  image: portworx/oci-monitor:3.1.4
  imagePullPolicy: Always
  kvdb:
    internal: true                  # KVDB interne (recommandé pour < 10 nœuds)
  cloudStorage:
    deviceSpecs:
      - type: gp3                   # Sur AWS — adapter selon le cloud/bare-metal
        size: 500
        iops: 3000
  secretsProvider: k8s
  stork:
    enabled: true
    args:
      webhook-controller: "true"
  autopilot:
    enabled: true
  monitoring:
    prometheus:
      enabled: true
      exportMetrics: true
  security:
    enabled: true
    auth:
      selfSigned:
        tokenLifetime: 24h
        sharedSecret: "mon-secret-partage-fort"
  env:
    - name: PX_IMAGE
      value: portworx/px-base-enterprise:3.1.4

Suivre le déploiement :

oc get pods -n portworx -w
oc get storagecluster portworx-cluster -n portworx

StorageClasses avancées

StorageClass pour base de données (haute performance)

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: px-db-high-perf
provisioner: pxd.portworx.com
parameters:
  repl: "3"                           # Réplication triple
  priority_io: "high"                 # I/O haute priorité
  io_profile: "db"                    # Profil optimisé base de données
  cow_ondemand: "false"               # Désactiver Copy-on-Write pour les DB
  sharedv4: "false"
  secure: "true"                      # Chiffrement du volume
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
# StorageClass pour Kafka (optimisée séquentiel)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: px-kafka
provisioner: pxd.portworx.com
parameters:
  repl: "3"
  priority_io: "high"
  io_profile: "sequential"
  journal: "true"                     # Journal dédié pour Kafka
allowVolumeExpansion: true
reclaimPolicy: Retain
volumeBindingMode: WaitForFirstConsumer
---
# StorageClass pour données partagées (ReadWriteMany)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: px-shared
provisioner: pxd.portworx.com
parameters:
  repl: "3"
  sharedv4: "true"                    # Accès concurrent multi-pods
  sharedv4_svc_type: ClusterIP
allowVolumeExpansion: true
reclaimPolicy: Retain

PX-Security : chiffrement et RBAC stockage

Chiffrement avec des secrets Kubernetes

# Stocker la clé de chiffrement dans un Secret
apiVersion: v1
kind: Secret
metadata:
  name: px-vol-encryption-key
  namespace: production
type: Opaque
stringData:
  encryption_key: "cle-de-chiffrement-32-caracteres!!"
# PVC avec chiffrement
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ma-bdd-chiffree
  namespace: production
  annotations:
    px/secret-name: px-vol-encryption-key
    px/secret-namespace: production
    px/secret-key: encryption_key
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: px-db-high-perf
  resources:
    requests:
      storage: 100Gi

Stork : ordonnancement hyperconvergé

Stork est le scheduler Portworx qui garantit la co-localisation des pods avec leurs données (hyper-convergence) et gère les snapshots et migrations.

# Forcer l'ordonnancement Stork pour un StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
  namespace: production
spec:
  schedulerName: stork               # <-- utiliser Stork
  replicas: 1
  selector:
    matchLabels:
      app: postgresql
  template:
    metadata:
      labels:
        app: postgresql
    spec:
      containers:
        - name: postgres
          image: postgres:16
          env:
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
          volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: postgres-data
      spec:
        accessModes: [ReadWriteOnce]
        storageClassName: px-db-high-perf
        resources:
          requests:
            storage: 100Gi

Snapshots 3DSnap (cohérence applicative)

Portworx permet des snapshots cohérents multi-volumes via GroupVolumeSnapshot :

apiVersion: stork.libopenstorage.org/v1alpha1
kind: GroupVolumeSnapshot
metadata:
  name: snap-mongodb-cluster
  namespace: production
spec:
  pvcSelector:
    matchLabels:
      app: mongodb                    # Snapshote tous les PVC MongoDB ensemble
  options:
    timeoutSeconds: "300"

Autopilot : scaling automatique des volumes

Autopilot surveille les volumes et les scale automatiquement quand ils approchent de la capacité.

apiVersion: autopilot.libopenstorage.org/v1alpha1
kind: AutopilotRule
metadata:
  name: volume-expand-rule
spec:
  selector:
    matchLabels:
      app: postgresql
  namespaceSelector:
    matchLabels:
      autopilot: "enabled"
  conditions:
    expressions:
      - key: volume.usage_pct            # % d'utilisation du volume
        operator: Gt
        values:
          - "80"
  actions:
    - name: openstorage.io.action.volume/resize
      params:
        scalepercentage: "50"           # Augmenter de 50%
        maxsize: "1Ti"                  # Maximum 1 Ti

Disaster Recovery inter-clusters

Configurer PX-DR (réplication asynchrone)

# Cluster primaire
apiVersion: stork.libopenstorage.org/v1alpha1
kind: ClusterPair
metadata:
  name: cluster-dr-paris
  namespace: kube-system
spec:
  config:
    clusterId: cluster-paris-prod
    ip: 10.0.0.1
    port: 9001
    token: <token-cluster-dr>
---
# Migration schedule : toutes les heures
apiVersion: stork.libopenstorage.org/v1alpha1
kind: MigrationSchedule
metadata:
  name: migration-production
  namespace: production
spec:
  template:
    spec:
      clusterPair: cluster-dr-paris
      includeResources: true
      startApplications: false
      namespaces:
        - production
  schedulePolicyName: every-1-hour

Monitoring avec Prometheus et Grafana

Portworx expose des métriques Prometheus nativement. Importer le dashboard officiel :

# Vérifier que les métriques sont exposées
oc get svc -n portworx | grep metrics

# Les métriques clés à surveiller
# - px_volume_iops_total
# - px_volume_read_latency_seconds
# - px_volume_write_latency_seconds
# - px_pool_stats_used_bytes
# - px_cluster_disk_used_percent

Dashboard Grafana ID : portworx-volume-metrics (ID 10000 sur grafana.com)


Conclusion

Portworx est la référence pour le stockage enterprise sur OpenShift. Sa richesse fonctionnelle (PX-Security, Autopilot, PX-DR, Stork), ses performances sur workloads database/Kafka, et son intégration profonde avec OpenShift en font le choix incontournable pour les organisations avec des exigences SLA élevées. Son coût de licence est compensé par la réduction des opérations manuelles et la fiabilité apportée en production.