Maison > développement back-end > Golang > PnR : orchestration de conteneurs basée sur l'intention de configuration avec l'abstraction de la plate-forme Go

PnR : orchestration de conteneurs basée sur l'intention de configuration avec l'abstraction de la plate-forme Go

DDD
Libérer: 2024-12-30 16:35:14
original
811 Les gens l'ont consulté

PnR: Configuration-Intention Driven Container Orchestration with Go

Avez-vous déjà souhaité que l'orchestration de conteneurs soit plus flexible que les chaînes de dépendances statiques mais plus simple que Kubernetes ? Découvrez PnR (Prompt and Response) - une approche basée sur la configuration qui exploite les puissantes capacités d'abstraction de la plate-forme Go pour orchestrer les conteneurs en fonction des états de préparation réels plutôt que de simples dépendances.

La puissance de l'abstraction de la plateforme Go

Avant de plonger dans PnR, comprenons pourquoi Go est particulièrement bien adapté à l'orchestration de conteneurs multiplateforme :

  1. Interface API Docker unifiée : la bibliothèque client Docker de Go fournit une interface cohérente sur Windows, Linux et macOS via des connexions socket spécifiques à la plate-forme :

    • Les systèmes Unix utilisent /var/run/docker.sock
    • Windows utilise des canaux nommés
    • La fonction client.NewClientWithOpts() gère automatiquement ces différences
  2. Prise en charge native de la concurrence : les goroutines et les canaux de Go permettent une surveillance efficace des conteneurs :

    • Le contrôle de santé de chaque conteneur s'exécute simultanément
    • La boucle d'intention coordonne plusieurs conteneurs sans bloquer
    • Les mises à jour d'état protégées par mutex empêchent les conditions de concurrence
  3. Gestion du réseau multiplateforme : le package net de Go résume les détails du réseau spécifiques à la plate-forme :

    • Les vérifications de l'état TCP fonctionnent de la même manière sur tous les systèmes d'exploitation
    • Les clients HTTP gèrent la résolution DNS spécifique à la plate-forme
    • La liaison de port utilise une syntaxe cohérente quelle que soit la plate-forme

Le concept de base : configuration sur code

PnR orchestre les conteneurs à travers trois composants clés :

  1. Configuration du domaine (JSON)
  2. Vérifications de santé indépendantes de la plate-forme
  3. Gestion de l'état d'exécution

Voyons cela en action avec une pile Web typique : MongoDB, serveur API et client Web.

Structure de configuration du domaine

{
    "name": "dev_stack",
    "cpuxs": {
        "stack_startup": {
            "design_chunks": [
                {
                    "name": "mongodb",
                    "gatekeeper": {
                        "system_ready": {
                            "prompt": "Is system ready?",
                            "response": ["yes"],
                            "tv": "Y"
                        }
                    },
                    "flowout": {
                        "mongodb_ready": {
                            "prompt": "Is MongoDB ready?",
                            "response": ["yes"],
                            "tv": "Y"
                        }
                    },
                    "health_check": {
                        "type": "tcp",
                        "port_key": "27017",
                        "timeout_seconds": 2,
                        "status_mapping": {
                            "success": {
                                "key": "mongodb_ready",
                                "response": ["yes"],
                                "tv": "Y"
                            },
                            "failure": {
                                "key": "mongodb_ready",
                                "response": ["no"],
                                "tv": "N"
                            }
                        }
                    },
                    "container": {
                        "name": "pnr_mongodb",
                        "image": "mongo:latest",
                        "ports": {
                            "27017": "27017"
                        }
                    }
                }
            ]
        }
    }
}
Copier après la connexion
Copier après la connexion

Gestion des conteneurs indépendante de la plate-forme

Le cœur de PnR est sa gestion des conteneurs indépendante de la plate-forme. Voici comment cela fonctionne :

func (il *ContainerIntentionLoop) Execute() error {
    // Create platform-specific network
    _, err := il.dockerClient.NetworkCreate(il.ctx, "pnr_network", types.NetworkCreate{})
    if err != nil {
        return fmt.Errorf("failed to create network: %v", err)
    }

    for {
        // Update runtime state
        if err := il.updateRTStateFromRuntime(); err != nil {
            return err
        }

        allCompleted := true
        anyExecuting := false

        // Process each container
        for i := range il.cpux.DesignChunks {
            chunk := &il.cpux.DesignChunks[i]

            // Container state machine
            switch chunk.Status {
            case "completed":
                continue
            case "executing":
                anyExecuting = true
                allCompleted = false
                if il.checkChunkCompletion(chunk) {
                    chunk.Status = "completed"
                }
            case "", "ready":
                allCompleted = false
                if il.checkGatekeeper(chunk) {
                    if err := il.startContainer(chunk); err != nil {
                        return err
                    }
                    chunk.Status = "executing"
                    anyExecuting = true
                }
            }
        }

        // Check termination conditions
        if allCompleted {
            return nil
        }
        if !anyExecuting && !allCompleted {
            return fmt.Errorf("no progress possible - execution stalled")
        }

        time.Sleep(5 * time.Second)
    }
}
Copier après la connexion
Copier après la connexion

Bilans de santé multiplateformes

PnR implémente des contrôles de santé indépendants de la plate-forme à l'aide des bibliothèques standard de Go :

{
    "name": "dev_stack",
    "cpuxs": {
        "stack_startup": {
            "design_chunks": [
                {
                    "name": "mongodb",
                    "gatekeeper": {
                        "system_ready": {
                            "prompt": "Is system ready?",
                            "response": ["yes"],
                            "tv": "Y"
                        }
                    },
                    "flowout": {
                        "mongodb_ready": {
                            "prompt": "Is MongoDB ready?",
                            "response": ["yes"],
                            "tv": "Y"
                        }
                    },
                    "health_check": {
                        "type": "tcp",
                        "port_key": "27017",
                        "timeout_seconds": 2,
                        "status_mapping": {
                            "success": {
                                "key": "mongodb_ready",
                                "response": ["yes"],
                                "tv": "Y"
                            },
                            "failure": {
                                "key": "mongodb_ready",
                                "response": ["no"],
                                "tv": "N"
                            }
                        }
                    },
                    "container": {
                        "name": "pnr_mongodb",
                        "image": "mongo:latest",
                        "ports": {
                            "27017": "27017"
                        }
                    }
                }
            ]
        }
    }
}
Copier après la connexion
Copier après la connexion

Avantages clés

  1. Véritable support multiplateforme : fonctionne de manière identique sur Windows, Linux et macOS
  2. Basé sur la configuration : toute la logique d'orchestration dans domain.json
  3. Container Agnostic : aucune modification de conteneur spécifique au PnR n'est nécessaire
  4. Vérifications de santé flexibles : TCP, HTTP et extensible à d'autres protocoles
  5. Visibilité de l'état : Effacer les mises à jour d'état via les fichiers d'exécution
  6. Exécution simultanée : gestion efficace des conteneurs parallèles

Commencer

Le code complet est disponible ici : Github

Conditions préalables

  1. Installer Go (1.19 ou version ultérieure) :

  2. Installer Docker

Structure du projet

func (il *ContainerIntentionLoop) Execute() error {
    // Create platform-specific network
    _, err := il.dockerClient.NetworkCreate(il.ctx, "pnr_network", types.NetworkCreate{})
    if err != nil {
        return fmt.Errorf("failed to create network: %v", err)
    }

    for {
        // Update runtime state
        if err := il.updateRTStateFromRuntime(); err != nil {
            return err
        }

        allCompleted := true
        anyExecuting := false

        // Process each container
        for i := range il.cpux.DesignChunks {
            chunk := &il.cpux.DesignChunks[i]

            // Container state machine
            switch chunk.Status {
            case "completed":
                continue
            case "executing":
                anyExecuting = true
                allCompleted = false
                if il.checkChunkCompletion(chunk) {
                    chunk.Status = "completed"
                }
            case "", "ready":
                allCompleted = false
                if il.checkGatekeeper(chunk) {
                    if err := il.startContainer(chunk); err != nil {
                        return err
                    }
                    chunk.Status = "executing"
                    anyExecuting = true
                }
            }
        }

        // Check termination conditions
        if allCompleted {
            return nil
        }
        if !anyExecuting && !allCompleted {
            return fmt.Errorf("no progress possible - execution stalled")
        }

        time.Sleep(5 * time.Second)
    }
}
Copier après la connexion
Copier après la connexion

Installation

func (il *ContainerIntentionLoop) checkChunkCompletion(chunk *DesignChunk) bool {
    // Platform-agnostic container status check
    isRunning, err := il.isContainerRunning(chunk.Container.Name)
    if !isRunning {
        il.updateChunkStatus(chunk, false)
        return false
    }

    // Health check based on configuration
    status := false
    switch chunk.HealthCheck.Type {
    case "tcp":
        addr := fmt.Sprintf("localhost:%s", chunk.Container.Ports[chunk.HealthCheck.PortKey])
        conn, err := net.DialTimeout("tcp", addr, timeout)
        if err == nil {
            conn.Close()
            status = true
        }

    case "http":
        url := fmt.Sprintf("http://localhost:%s%s", 
            chunk.Container.Ports[chunk.HealthCheck.PortKey],
            chunk.HealthCheck.Path)
        resp, err := client.Get(url)
        if err == nil {
            status = (resp.StatusCode == chunk.HealthCheck.ExpectedCode)
        }
    }

    il.updateChunkStatus(chunk, status)
    return status
}
Copier après la connexion

Construire et exécuter

pnr-orchestrator/
├── main.go
├── containers.go
├── config/
│   └── domain.json
└── runtime/          # Created automatically
Copier après la connexion

Au-delà des simples dépendances

Composition Docker traditionnelle :

# Create project directory
mkdir pnr-orchestrator
cd pnr-orchestrator

# Initialize Go module
go mod init pnr-orchestrator

# Install dependencies
go get github.com/docker/docker/client
go get github.com/docker/docker/api/types
go get github.com/docker/go-connections/nat
Copier après la connexion

L'orchestration intelligente de PnR :

# Option 1: Direct run
go run main.go containers.go

# Option 2: Build and run separately
go build
./pnr-orchestrator   # Unix/Linux/Mac
pnr-orchestrator.exe # Windows
Copier après la connexion

La principale différence ? PnR garantit la disponibilité réelle du service sur n'importe quelle plate-forme, pas seulement le démarrage du conteneur.

Prochaines étapes

  1. Explorez des modèles d'orchestration plus complexes
  2. Ajouter des types de vérification de l'état personnalisés
  3. Mettre en œuvre un arrêt et un nettoyage progressifs
  4. Créer des conseils d'optimisation spécifiques à la plate-forme

PnR démontre comment les fortes capacités d'abstraction de la plateforme Go peuvent créer des outils d'orchestration de conteneurs multiplateformes robustes sans sacrifier la simplicité ou la puissance.

Faites-moi savoir dans les commentaires si vous souhaitez voir plus d'exemples ou si vous avez des questions sur les implémentations spécifiques à la plateforme !

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:dev.to
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal