Tous les produits
Search
Centre de documentation

Container Service for Kubernetes:Best practice for Linux graphics applications

Dernière mise à jour :Aug 11, 2026

Exécutez des applications graphiques Linux accélérées par GPU dans des conteneurs sur ACK en configurant le système de fenêtrage X (Xorg) comme serveur d'affichage.

Contexte

Le système de fenêtrage X (également appelé X ou X11), développé initialement au MIT en 1984, fournit une interface graphique utilisateur fenêtrée pour les systèmes d'exploitation de type Unix. Il repose sur une architecture client/serveur :

X window system architecture

  • Serveur X -- S'exécute sur la machine locale, interagit avec les pilotes de périphériques, capture les entrées matérielles (écran, clavier et souris) et effectue le rendu graphique.

  • Client X -- Communique avec le serveur X via un réseau TCP/IP. Les clients X ne disposent pas de leur propre capacité de rendu graphique. Ils envoient des demandes de dessin au serveur X et reçoivent les données d'affichage en retour.

  • Gestionnaire de fenêtres -- Isole les clients X les uns des autres afin d'éviter les conflits d'opérations.

Xorg est une version majeure du protocole X. Les sections suivantes décrivent comment utiliser Xorg pour exécuter des applications graphiques Linux conteneurisées avec un rendu GPU.

Prérequis

Avant de commencer, assurez-vous de disposer des éléments suivants :

  • Un cluster ACK doté de nœuds équipés de GPU

  • Une instance ECS avec un GPU NVIDIA (ce guide utilise le type d'instance ecs.gn6v-c8g1.2xlarge équipé d'un GPU NVIDIA Tesla V100)

  • Alibaba Cloud Linux 2.1903 ou un système d'exploitation compatible sur l'hôte

  • Docker Engine version 19.3.15 ou ultérieure

  • kubectl configuré pour accéder à votre cluster

Choisir une solution

Le système de fenêtrage X suit une architecture client/serveur où le serveur X gère tout le rendu graphique. Pour exécuter une application graphique conteneurisée, un serveur X doit être disponible dans l'environnement d'exécution du conteneur. Étant donné que le système de fenêtrage X est un composant de l'espace utilisateur et non une partie du noyau Linux, les instances ECS Linux ne l'incluent pas par défaut.

Deux approches sont disponibles :

Solution Fonctionnement Idéal pour
Exécuter le serveur X sur l'hôte Installez et exécutez Xorg sur le nœud hôte. Les conteneurs se connectent au serveur X de l'hôte via un socket Unix partagé et des variables d'environnement. Plusieurs applications graphiques partageant le même GPU sur un seul hôte. L'affichage DISPLAY de l'hôte est partagé entre tous les conteneurs.
Exécuter le serveur X dans le conteneur Installez et exécutez Xorg entièrement dans le conteneur. Aucune modification n'est requise sur l'hôte. Une seule application graphique par hôte (un GPU par hôte). Le rendu GPU est exclusif à ce conteneur.

Solution 1 : Exécuter le serveur X sur l'hôte

Étape 1 : Installer et démarrer Xorg sur l'hôte

  1. Installez le serveur Xorg :

       yum install xorg-x11-server-Xorg
  2. Trouvez l'ID de bus PCI de votre GPU : La sortie inclut une ligne similaire à celle-ci. Notez l'ID de bus pour l'étape suivante.

       nvidia-xconfig --query-gpu-info
       PCI BusID : PCI:0:7:0
  3. Générez un fichier de configuration Xorg. Remplacez <bus-id> par l'ID de bus PCI obtenu à l'étape précédente : Cette opération crée un fichier xorg.conf avec une résolution d'affichage virtuel de 1920x1080.

       nvidia-xconfig -a --virtual=1920x1080 --allow-empty-initial-configuration --no-use-display-device --enable-all-gpus --busid "<bus-id>" -o xorg.conf
  4. Lancez le serveur Xorg sur l'affichage :10 :

       Xorg -dpi 96 -noreset -nolisten tcp +extension GLX +extension RANDR +extension RENDER +extension DOUBLE-BUFFER -logfile xorg-10.log -config xorg.conf -verbose :10 &
  5. Définissez la variable d'environnement DISPLAY :

       export DISPLAY=:10

Étape 2 : Vérifier le rendu GPU sur l'hôte

  1. Installez glxgears :

       yum install glx-utils
  2. Exécutez glxgears pour tester le rendu GPU : Sortie attendue : Si la sortie affiche une valeur FPS (par exemple, 10880 frames in 5.0 seconds = 2175.920 FPS), le rendu GPU fonctionne correctement.

       glxgears -info
       Running synchronized to the vertical refresh.  The framerate should be
       approximately the same as the monitor refresh rate.
       GL_RENDERER   = Tesla V100-SXM2-16GB/PCIe/SSE2
       GL_VERSION    = 4.6.0 NVIDIA 460.91.03
       GL_VENDOR     = NVIDIA Corporation
       ...
       10880 frames in 5.0 seconds = 2175.920 FPS

Étape 3 : Déployer un Pod qui se connecte au serveur X de l'hôte

  1. Créez un fichier nommé gui-app.yaml : Remplacez les espaces réservés suivants :

    Espace réservé Description Exemple
    <node-name> Le nom du nœud sur lequel Xorg est en cours d'exécution cn-hangzhou.192.168.0.1
    <your-image>:<tag> L'image de conteneur de votre application graphique myapp:latest
    <your-command> La commande pour démarrer votre application /usr/bin/myapp
       apiVersion: v1
       kind: Pod
       metadata:
         name: gui-app
         namespace: default
       spec:
         # Schedule the Pod to the node where Xorg is running.
         nodeName: <node-name>
         containers:
           # Specify the container image of your Linux graphics application.
         - image: <your-image>:<tag>
           name: app-name
           command: [<your-command>]
           # Pass the DISPLAY variable to the container through a ConfigMap.
           envFrom:
             - configMapRef:
                 name: display-config
           # Mount the X11 Unix socket directory so the container can reach the host X server.
           volumeMounts:
             - mountPath: /tmp/.X11-unix
               name: unix-display
           securityContext:
             privileged: true
         restartPolicy: Always
         volumes:
           - name: unix-display
             hostPath:
               path: /tmp/.X11-unix
       ---
       apiVersion: v1
       kind: ConfigMap
       metadata:
          name: display-config
          namespace: default
       data:
          DISPLAY: unix:10.0
  2. Déployez le Pod :

       kubectl apply -f gui-app.yaml

Étape 4 : Installer le pilote GPU dans le conteneur

Les instances ECS de type ecs.gn6v-c8g1.2xlarge utilisent le GPU NVIDIA V100. Le pilote GPU est préinstallé sur l'hôte, mais les bibliothèques de pilotes de l'espace utilisateur doivent également être installées dans le conteneur. Incluez ces commandes dans votre Dockerfile pour assurer la reproductibilité :

wget https://storage.googleapis.com/nvidia-drivers-us-public/GRID/GRID12.3/NVIDIA-Linux-x86_64-460.91.03-grid.run

chmod a+x NVIDIA-Linux-x86_64-460.91.03-grid.run

apt-get update && apt-get install -y kmod

./NVIDIA-Linux-x86_64-460.91.03-grid.run -a -q --ui=none --no-kernel-module
L'indicateur --no-kernel-module ignore l'installation du module kernel car le pilote GPU est déjà chargé sur l'hôte. Seules les bibliothèques de l'espace utilisateur sont installées dans le conteneur.

Étape 5 : Vérifier le rendu GPU dans le conteneur

  1. Installez glxgears dans le conteneur (basé sur Ubuntu) :

       apt install mesa-utils
  2. Testez le rendu GPU : Sortie attendue : Si la sortie affiche une valeur FPS, le rendu GPU fonctionne correctement dans le conteneur.

       glxgears -info
       GL_RENDERER   = Tesla V100-SXM2-16GB/PCIe/SSE2
       GL_VERSION    = 4.6.0 NVIDIA 460.91.03
       GL_VENDOR     = NVIDIA Corporation
       ...
       11119 frames in 5.0 seconds = 2223.799 FPS

Solution 2 : Exécuter le serveur X dans le conteneur

Cette approche installe et exécute Xorg entièrement dans le conteneur, sans nécessiter de configuration du serveur X côté hôte.

Étape 1 : Installer et démarrer Xorg dans le conteneur

Exécutez les commandes suivantes à l'intérieur du conteneur. Incluez-les dans votre Dockerfile pour assurer la reproductibilité :

# Install Xorg
apt update && apt install -y xorg

# Generate the Xorg configuration file.
# Replace <bus-id> with your GPU PCI bus ID (run nvidia-xconfig --query-gpu-info to find it).
nvidia-xconfig -a --virtual=1920x1080 --allow-empty-initial-configuration --no-use-display-device --enable-all-gpus --busid "<bus-id>" -o xorg.conf

# Start the D-Bus daemon (required by Xorg)
/etc/init.d/dbus start

# Launch Xorg on display :10
Xorg -dpi 96 -noreset -nolisten tcp +extension GLX +extension RANDR +extension RENDER +extension DOUBLE-BUFFER -logfile xorg-10.log -config xorg.conf -verbose :10 &

# Set the display
export DISPLAY=:10

Étape 2 : Installer le pilote GPU dans le conteneur

Suivez les mêmes étapes d'installation du pilote GPU que pour la Solution 1, Étape 4.

Étape 3 : Déployer un Pod avec une demande de ressource GPU

  1. Créez un fichier nommé gui-app-gpu.yaml : > Remarque : Contrairement à la Solution 1, ce manifeste de Pod ne monte pas le répertoire du socket X11 ni ne référence de ConfigMap, car le serveur X s'exécute à l'intérieur du conteneur lui-même.

       apiVersion: v1
       kind: Pod
       metadata:
         name: gui-app-gpu
         namespace: default
       spec:
         containers:
           # Specify the container image of your Linux graphics application.
         - image: <your-image>:<tag>
           name: app-name
           command: [<your-command>]
           resources:
             limits:
               # Request one GPU. The scheduler automatically places the Pod on a node that has an available GPU.
               nvidia.com/gpu: 1
           securityContext:
             privileged: true
         restartPolicy: Always
  2. Déployez le Pod :

       kubectl apply -f gui-app-gpu.yaml

Étape 4 : Vérifier le rendu GPU

Exécutez glxgears à l'intérieur du conteneur :

glxgears -info

Sortie attendue :

GL_RENDERER   = Tesla V100-SXM2-16GB/PCIe/SSE2
GL_VERSION    = 4.6.0 NVIDIA 460.91.03
GL_VENDOR     = NVIDIA Corporation
...
140060 frames in 5.0 seconds = 28011.809 FPS

Si la sortie affiche une valeur FPS, le rendu GPU fonctionne correctement.

La Solution 2 offre généralement un débit FPS plus élevé que la Solution 1, car le GPU est exclusivement dédié à l'application graphique du conteneur, sans surcharge liée au partage de l'affichage.