Déployer Oracle Kubernetes Engine (OKE) pour la production : Meilleures pratiques et directives

Présentation

Il s'agit du troisième tutoriel de notre série d'automatisation d'Oracle Cloud Infrastructure Kubernetes Engine (OKE), en s'appuyant sur les concepts présentés dans le deuxième tutoriel, Déployez Oracle Cloud Infrastructure Kubernetes Engine (OKE) à l'aide des modules Terraform avancés. Dans ce guide, nous mettons l'accent sur les déploiements OKE prêts pour la production et explorons les meilleures pratiques clés qui améliorent la fiabilité des grappes, optimisent les coûts et simplifient les opérations. Nous présenterons certaines des meilleures pratiques à l'aide de Terraform tout en soulignant les pièges courants rencontrés par les utilisateurs lors de la création de grappes.

Importance du déploiement d'OKE dans un VCN existant

La création d'une grappe OKE de niveau production nécessite une planification minutieuse des processus de réseau, de positionnement de noeud et opérationnels. Le déploiement dans un réseau en nuage virtuel (VCN) existant permet à votre grappe de s'intégrer de façon transparente à des sous-réseaux, à des tables de routage et à des règles de sécurité préconfigurés. Cela réduit les frais généraux opérationnels, assure la cohérence avec l'infrastructure de votre organisation et permet à plusieurs charges de travail ou grappes de coexister efficacement au sein du même réseau.

Les paramètres Terraform clés lors du déploiement dans un VCN existant sont les suivants :

Vous pouvez également définir is_vcn_created = true pour provisionner un nouveau réseau lors du déploiement d'un nouvel environnement entièrement nouveau. Après une opération terraform apply réussie, Terraform saisit les OCID du VCN nouvellement créé et de ses sous-réseaux dans les sorties. Ces valeurs peuvent être réutilisées dans des déploiements futurs en définissant is_vcn_created = false et en référençant les OCID enregistrés dans votre fichier terraform.tfvars, ce qui permet à Terraform d'utiliser le réseau existant au lieu d'en créer un nouveau. L'exécution de terraform plan à ce stade confirme que le VCN et les sous-réseaux courants sont conservés, évitant ainsi toute modification d'infrastructure inutile.

Avec la base réseau en place, ce tutoriel se concentre sur un ensemble de meilleures pratiques orientées vers la production visant à rendre les clusters OKE plus résilients, évolutifs et plus faciles à utiliser. En appliquant ces pratiques, les clients peuvent déployer des grappes OKE hautement disponibles, rentables et alignées sur les politiques organisationnelles, les normes de gouvernance et les exigences opérationnelles de production. Téléchargez le dernier code à partir d'ici oke_advanced_module.zip.

Meilleures pratiques OKE : Lignes directrices prêtes pour la production

1. Utilisez le cyclage de noeud pour mettre à niveau les groupes de noeuds OKE.

Le cyclage de noeud est une stratégie de mise à niveau continue sûre qui met à jour les images de noeud, les versions de Kubernetes ou les configurations système sans perturber les charges de travail. Le cycle des noeuds est important car il permet aux grappes d'évoluer en toute sécurité au fil du temps, en appliquant des correctifs ou des mises à niveau sans incidence sur les charges de travail de production. Pour les clients, cela réduit les risques opérationnels, assure une disponibilité continue pendant les mises à niveau et permet aux charges de travail de s'exécuter de manière fiable tout en conservant les dernières versions. OKE prend en charge deux types :

Des paramètres tels que maximum_surge et maximum_unavailable contrôlent l'équilibre entre la vitesse et la disponibilité des mises à niveau. Pour les mises à niveau sans temps d'arrêt, réglez maximum_surge = 1 et maximum_unavailable = 0, en vous assurant qu'un nouveau noeud est en ligne avant de remplacer l'ancien. Ce qui suit illustre un exemple de cyclage de noeud avec l'augmentation maximale 1 et l'indisponibilité maximale 0.

OKENodepoolupgraded

Pour déclencher la mise à niveau d'une grappe OKE existante qui mène au cyclage de noeud :

Dans votre fichier terraform.tfvars :

Exécutez ensuite terraform plan

Vous devriez voir la sortie comme suit :

Lorsque vous exécutez terraform apply, OKE commence à exécuter les groupes de noeuds un noeud à la fois à l'aide de la stratégie BOOT_VOLUME_REPLACE. Dans ce mode, seul le volume de démarrage du noeud est remplacé alors que l'instance de calcul sous-jacente reste la même. Par conséquent, la mise à niveau du nœud est effectuée en place, et les attributs de réseau tels que l'adresse IP privée restent inchangés comme ci-dessous :

OKEclusterUpgrading OKEclusterUpgrading OKEclusterUpgrading

Pour exécuter des cycles de noeuds à l'aide de l'option INSTANCE_REPLACE, réglez cycle_modes à INSTANCE_REPLACE pour qu'OKE exécute les groupes de noeuds un noeud à la fois. Dans ce mode, chaque noeud est supprimé et recréé de A à Z, y compris l'instance de calcul et son volume de démarrage. Par conséquent, la mise à niveau des noeuds applique tous les attributs mis à jour, tels qu'une nouvelle version de Kubernetes ou des modifications de forme, mais des attributs de réseau tels que l'adresse IP privée peuvent changer. Cette approche garantit un nœud entièrement actualisé avec les dernières configurations, offrant une couverture de mise à jour maximale tout en maintenant la disponibilité des grappes au moyen de remplacements non simultanés, comme indiqué ci-dessous :

OKEclusterUpgrading OKEclusterUpgrading

2. Utiliser le marquage OCI sur les noeuds de travail et les équilibreurs de charge OKE pour effectuer le suivi des coûts

Lors de l'exécution de charges de travail Kubernetes dans Oracle Cloud Infrastructure (OCI), il est essentiel de comprendre d'où proviennent vos coûts. Le marquage est la clé. OCI vous permet d'appliquer des marqueurs définis et à structure libre à chaque ressource, y compris les grappes OKE, les noeuds de travail, les équilibreurs de charge et les volumes persistants. Cela est important car il permet de produire des rapports détaillés sur les coûts, de faciliter la vérification et de responsabiliser l'utilisation du nuage. Pour les clients, le service de marquage fournit des informations sur les charges de travail qui consomment le plus de ressources, améliore la transparence des coûts et prend en charge les décisions d'optimisation pour contrôler les dépenses en nuage.

Pourquoi le marquage est important :

# Cluster-level tagging
cluster_freeform_tag_key   = "Environment"
cluster_freeform_tag_value = "Development"

# Node pool-level tagging
node_pool_freeform_tag_key   = "LOB"
node_pool_freeform_tag_value = "DevOps Tech"

# Bastion host tagging
freeform_tags = {
  project     = "devops"
  environment = "production"}

# Defined tagging
defined_tags = { 
  “Corporate_Standard.CostCenter”  = “Finance-123"
  “Corporate_Standard.Environment” = “Production” }

Avec ces marqueurs en place, vous pouvez générer des rapports de coût détaillés dans OCI Cost Analysis, identifier les charges de travail qui consomment le plus de ressources et prendre des décisions éclairées sur l'évolutivité ou l'optimisation.

3. Séparez les sous-réseaux de point d'extrémité d'API, de noeud, d'équilibreur de charge et de pods (le cas échéant).

Une bonne conception du réseau est une bonne pratique dans OKE car elle améliore la sécurité, les performances et l'évolutivité. La séparation des points d'extrémité d'API, des noeuds de travail, des pods, des équilibreurs de charge et des hôtes bastion dans des sous-réseaux distincts isole le trafic critique, permet des tables de routage personnalisées ou des groupes de sécurité de réseau et empêche un type de trafic d'interférer avec un autre. Cette approche est essentielle pour maintenir une communication sécurisée, un routage prévisible et une forte isolation des ressources dans les environnements de production.

Les clients bénéficient d'une grappe plus sécurisée, plus gérable et plus résiliente qui peut s'adapter efficacement et gérer les pics ou les attaques de trafic sans aucune incidence sur les charges de travail. Plus bas se trouve l'extrait de code terrform.tfvars qui vous permet de définir des blocs CIDR pour les sous-réseaux.

k8apiendpoint_private_subnet_cidr_block       = "REPLACE_WITH_YOUR_CIDR"   # API endpoint subnet
workernodes_private_subnet_cidr_block         = "REPLACE_WITH_YOUR_CIDR"   # Worker nodes subnet
pods_private_subnet_cidr_block                = "REPLACE_WITH_YOUR_CIDR"   # Pod subnet (CNI)
serviceloadbalancers_public_subnet_cidr_block = "REPLACE_WITH_YOUR_CIDR"   # Load balancer subnet
bastion_public_subnet_cidr_block              = "REPLACE_WITH_YOUR_CIDR"   # Bastion host subnet

Dans cet exercice, vous allez améliorer la sécurité, simplifier la gestion du réseau et rendre votre grappe plus résiliente aux pics de trafic ou aux attaques.

4. Utiliser un groupe de noeuds par architecture de domaine de disponibilité lors de l'utilisation du composant d'ajustement automatique de grappe

Dans OCI, chaque domaine de disponibilité a une capacité indépendante. Bien que les groupes de noeuds puissent couvrir plusieurs domaines de disponibilité pour améliorer la haute disponibilité, ce n'est pas recommandé lorsque l'ajustement automatique de grappe est activé. L'ajustement automatique requiert de la capacité dans tous les domaines de disponibilité sélectionnés et peut échouer si un domaine de disponibilité manque de ressources.

Pour éviter cela, les groupes de noeuds doivent être configurés pour utiliser un seul domaine de disponibilité lorsque l'ajustement automatique est activé. Si la capacité n'est pas disponible dans un domaine de disponibilité, le composant d'ajustement automatique peut ajuster un groupe de noeuds alternatif dans un autre domaine de disponibilité.

Exemple de configuration de groupe de noeuds :

availability_domains = [
      "REPLACE_WITH_YOUR_AD"
    ]

Exemple de configuration d'ajustement automatique de grappe :

cluster_autoscaler_config = {
  node_mapping = {
    key = "nodes"
    value = "1:5:ocid1.nodepool....."
  }
}

5. Groupes de noeuds distincts pour différentes exigences de charge de travail (x86, ARM, GPU)

Utilisez des groupes de noeuds distincts pour les charges de travail nécessitant des formes de calcul différentes, telles que x86, ARM ou GPU. Cette approche améliore l'utilisation des ressources, l'efficacité de la programmation et le comportement d'ajustement automatique en s'assurant que chaque charge de travail s'exécute sur l'infrastructure la plus appropriée.

Les pods sont programmés vers les groupes de noeuds appropriés à l'aide d'étiquettes de noeud, de sélecteurs, d'affinités ou de teintes et de tolérances, ce qui permet à Kubernetes de placer des charges de travail sur des noeuds dotés de l'architecture ou des capacités requises.

En combinant des groupes de noeuds dédiés avec un positionnement explicite des pods, les clients bénéficient d'une performance prévisible, d'une évolutivité efficace et d'une gestion de grappe simplifiée. Dans cet exemple, des groupes de noeuds distincts sont créés pour les formes Intel et AMD, ce qui garantit un positionnement optimal de la charge de travail et des opérations de grappe résilientes.

worker_node_pools = {
  AMD_node_pool = {
    name               = "node_pool_one"                # Node pool name
    shape              = "VM.Standard.E5.Flex"          # Compute shape
    shape_config = {
      memory = 16                                       # Memory (GB)
      ocpus  = 1                                        # OCPUs
    }
    boot_volume_size   = 50                             # Boot volume size (GB)
    operating_system   = "Oracle-Linux"                 # OS for worker nodes
    kubernetes_version = "v1.33"                        # Node Kubernetes version
    source_type        = "IMAGE"                        # Source type for image
    node_labels = {
      Trigger = "Nodes_Cycling_0"                       # Node label
    }
    availability_domains = [                            # Availability_domain setting
      "REPLACE_WITH_YOUR_AD"
    ]                                                   # ADs for node distribution
    number_of_nodes          = 1                        # Number of worker nodes
    pv_in_transit_encryption = false                    # Boot volume in-transit encryption
    node_cycle_config = {
      node_cycling_enabled = true                       # Enable node cycling by default
      maximum_surge        = 1                          # Number of surge nodes
      maximum_unavailable  = 0                          # Max unavailable nodes
      cycle_modes          = ["BOOT_VOLUME_REPLACE"]    # cycle_modes"BOOT_VOLUME_REPLACE" or "INSTANCE_REPLACE"

    }
    ssh_key = "REPLACE_WITH_YOUR_KEY"                   # SSH public key for workers nodes
  }
  Intel_node_pool = {
    name               = "node_pool_two"                # Node pool name
    shape              = "VM.Standard2.8"      	        # Compute shape
    shape_config = {
      memory = 120                                      # Memory (GB)
      ocpus  = 8                                        # OCPUs
    }
    boot_volume_size   = 50                             # Boot volume size (GB)
    operating_system   = "Oracle-Linux"                 # OS for worker nodes
    kubernetes_version = "v1.33"                        # Node Kubernetes version
    source_type        = "IMAGE"                        # Source type for image
    node_labels = {
      Trigger = "Nodes_Cycling_0"                       # Node label
    }
    availability_domains = [                            # Availability_domain setting
      "REPLACE_WITH_YOUR_AD"  
    ]                                                   # ADs for node distribution
    number_of_nodes          = 1                        # Number of worker nodes
    pv_in_transit_encryption = false                    # Boot volume in-transit encryption
    node_cycle_config = {
      node_cycling_enabled = true                       # Enable node cycling by default
      maximum_surge        = 1                          # Number of surge nodes
      maximum_unavailable  = 0                          # Max unavailable nodes
      cycle_modes          = ["BOOT_VOLUME_REPLACE"]    # cycle_modes"BOOT_VOLUME_REPLACE" or "INSTANCE_REPLACE"

    }
    ssh_key = "REPLACE_WITH_YOUR_KEY"                   # SSH public key for workers nodes
  }

}

Après l'exécution de terraform apply, votre grappe OKE affichera deux groupes de noeuds distincts :

OKEtwonodepools OKEIntelnodepool OKEAMDnodepool

6. Utiliser Cloud-Init pour la personnalisation de noeud

Les scripts Cloud-init sont essentiels pour automatiser la configuration des noeuds de travail dans OKE, afin de garantir la cohérence de la configuration du système d'exploitation, de l'installation des ensembles et du réglage du système sur tous les noeuds. L'intégration de cloud-init à Terraform vous permet de provisionner automatiquement les nœuds au démarrage, rendant les déploiements reproductibles, vérifiables et prêts pour la production. Consultez ce document Utilisation de scripts d'initialisation cloud-init personnalisés pour configurer des noeuds gérés pour plus d'informations sur les scripts cloud-init.

Dans le code Terraform fourni, chaque groupe de noeuds référence un script cloud-init à l'aide du paramètre cloud_init_path. Les clients peuvent modifier le contenu de cloud-init-general.sh en fonction de leurs exigences, en suivant les directives dans le document ci-dessus. Dans cette démo, nous utilisons le script de démarrage par défaut fourni dans la documentation référencée. Les clients peuvent également modifier l'emplacement du script cloud-init en mettant à jour le paramètre cloud_init_path, comme illustré ci-dessous :

cloud_init_path = "cloud-init-general.sh"

Cela garantit que lors du provisionnement des noeuds ou du cycle des noeuds, chaque noeud nouveau ou remplacé est initialisé de manière cohérente avec la configuration système requise. Combiné à Terraform, cloud-init permet d'appliquer automatiquement les scripts contrôlés par version, éliminant ainsi les tâches manuelles de post-provisionnement.

Principaux avantages pour les noeuds de travail :

7. Améliorer les fonctionnalités OKE à l'aide de modules complémentaires

Les modules complémentaires OKE étendent les capacités des grappes aux fins d'observabilité, de mise à l'échelle, de sécurité et de gestion du trafic. À l'aide de Terraform, vous pouvez activer ou désactiver des modules complémentaires de manière sélective en fonction des exigences de charge de travail et en réduisant l'utilisation des ressources :

kubernetes_dashboard_enabled       = false
metrics_server_enabled             = false
cluster_autoscaler_enabled         = false
certificate_manager_enabled        = false
istio_enabled                      = false
native_ingress_controller_enabled  = false

Les add-ons communs et leurs avantages :

Meilleures pratiques pour les modules complémentaires :

8. Utilisez l'authentification/la détection OIDC si les ressources externes ont besoin d'accéder aux grappes k8s.

Intégrez la détection OIDC à des fournisseurs d'identité externes (tels qu'Okta ou Azure AD) si les développeurs ou les outils d'automatisation en dehors d'OCI doivent s'authentifier auprès de votre grappe Kubernetes. Cela permet une gestion centralisée des identités et un accès fédéré sans avoir à gérer les utilisateurs Kubernetes locaux ou à distribuer les fichiers kubeconfig. Cette approche est particulièrement utile lorsque les outils d'intégration et de développement en continu externes tels que les actions GitHub ont besoin d'accéder à la grappe ou lorsque les charges de travail de la grappe doivent s'intégrer en toute sécurité à des services externes tels que le service de chambre forte HashiCorp. En s'appuyant sur OIDC, les organisations peuvent appliquer des politiques d'authentification cohérentes, simplifier la gestion des accès et réduire les frais généraux opérationnels de rotation des données d'identification tout en maintenant des limites de sécurité strictes.

9. Utiliser des groupes de sécurité de réseau au lieu des listes de sécurité

Les groupes de sécurité de réseau sont préférés aux listes de sécurité traditionnelles lors de la sécurisation des grappes OKE. Les groupes de sécurité de réseau permettent des règles de sécurité plus granulaires, flexibles et réutilisables qui peuvent être attachées directement à des ressources spécifiques telles que des noeuds de travail, des équilibreurs de charge ou des pods. Cela les rend mieux adaptés aux environnements Kubernetes dynamiques où les ressources évoluent fréquemment ou changent. En revanche, les listes de sécurité s'appliquent au niveau du sous-réseau et sont conçues pour englober des réseaux en nuage virtuels ou des sous-réseaux entiers, ce qui offre moins de contrôle lors de la mise en oeuvre d'exigences de sécurité applicative détaillées. L'utilisation de groupes de sécurité de réseau améliore l'hygiène de la sécurité, simplifie la gestion des règles et permet un isolement plus strict entre les composants du cluster.

10. Activer l'observabilité avec OCI Logging Analytics et les mesures OKE

Intégrez OKE à OCI Logging Analytics et Monitoring pour obtenir une visibilité complète de la performance des grappes et des charges de travail. Logging Analytics fournit une agrégation de journaux avancée, une analyse et une détection d'anomalies, tandis que le service de surveillance collecte des mesures à partir du plan de contrôle Kubernetes et des noeuds de travail. Ensemble, ces services permettent aux équipes de visualiser les tendances, de résoudre les problèmes plus rapidement et de configurer des alertes pour une gestion proactive. Cette solution est particulièrement adaptée aux clients à la recherche d'une plate-forme d'observabilité native OCI qui masque les complexités de l'ingestion, du stockage et de l'analyse des journaux, tout en s'intégrant de façon transparente à d'autres services OCI.

11. Utilisez l'identité de charge de travail si les pods ont besoin d'accéder aux ressources OCI.

Lors de l'authentification auprès d'OCI, les clés d'API sont couramment utilisées, mais ces données d'identification sont de longue durée et nécessitent un stockage persistant, ce qui les rend difficiles à gérer en toute sécurité à grande échelle. Alors que les principaux d'instance et de ressource l'améliorent en permettant aux instances ou aux services de calcul d'assumer leur propre identité, OKE Workload Identity étend ce concept en permettant aux pods Kubernetes individuels d'assumer leur propre identité OCI. En activant l'identité de charge de travail OCI, les pods peuvent accéder en toute sécurité aux services OCI tels que le stockage d'objets ou la journalisation à l'aide des politiques IAM, sans avoir à coder en dur les données d'identification ni à compter sur les autorisations au niveau du noeud. Cela fournit un contrôle d'accès détaillé, vérifiable et sécurisé, qui est essentiel pour les environnements Kubernetes multilocataires de niveau production.

12. Utilisez la taille de sous-réseau appropriée pour les noeuds et les pods OKE.

Il est recommandé de planifier correctement les blocs CIDR de sous-réseau, car chaque noeud requiert une adresse IP principale et des adresses IP secondaires supplémentaires pour les pods. Les petits sous-réseaux peuvent rapidement entraîner l'épuisement des adresses IP, ce qui empêche la mise à l'échelle ou les mises à niveau. Ceci est important pour maintenir la stabilité des grappes et soutenir la croissance. Les clients bénéficient en s'assurant que les grappes peuvent s'adapter de manière prévisible, en évitant les perturbations opérationnelles et en prenant en charge les charges de travail futures sans nécessiter de refonte du réseau. Pour les environnements de production, allouez des blocs CIDR plus volumineux et consultez le guide de dimensionnement du sous-réseau OKE pour vous assurer que votre VCN peut prendre en charge les demandes de charge de travail courantes et futures.

13. Utiliser le service de récupération après sinistre de pile complète pour sauvegarder la grappe k8s

L'utilisation de la récupération après sinistre de pile complète pour OCI pour la grappe OKE est une meilleure pratique, car elle protège la configuration, les applications et la mise en réseau de la grappe grâce à un basculement et à une restauration coordonnés entre les régions. Ceci est important pour la continuité des activités et la conformité en cas de pannes régionales ou de défaillances du système. Les clients bénéficient de temps d'arrêt réduits, d'une reprise rapide et de la certitude que les charges de travail critiques restent opérationnelles, même en cas de sinistre.

Pour plus d'informations, voir Automatiser les plans de permutation et de basculement pour le moteur Kubernetes OCI (avec état) avec la récupération après sinistre de pile complète pour OCI

Étapes suivantes :

Terraform rend le provisionnement OKE cohérent, automatisé et évolutif. En suivant les meilleures pratiques telles que le marquage OCI, la séparation des sous-réseaux et la configuration de noeuds normalisée, vos grappes restent sécurisées, organisées et transparentes pour les coûts. Dans le prochain blogue, nous allons nous appuyer sur ces bases pour explorer les opérations guidées par l'intelligence artificielle et montrer comment intégrer Oracle AIOps, activer l'observabilité alimentée par l'intelligence artificielle et créer un plan OKE de bout en bout pour les charges de travail d'intelligence artificielle. Restez à l'affût de notre prochaine session LiveLabs, où vous pourrez acquérir une expérience pratique de ces techniques et expérimenter les déploiements OKE dans un environnement en direct.

Remerciements

Ressources d'apprentissage supplémentaires

Explorez d'autres laboratoires sur le site docs.oracle.com/learn ou accédez à plus de contenu d'apprentissage gratuit sur le canal Oracle Learning YouTube. De plus, visitez education.oracle.com/learning-explorer pour devenir un explorateur Oracle Learning.

Pour obtenir la documentation sur le produit, visitez Oracle Help Center.