--- title: ReplicaSet content_type: concept weight: 10 --- Un ReplicaSet (ensemble de réplicas en français) a pour but de maintenir un ensemble stable de Pods à un moment donné. Cet objet est souvent utilisé pour garantir la disponibilité d'un certain nombre identique de Pods. ## Comment un ReplicaSet fonctionne Un ReplicaSet est défini avec des champs, incluant un selecteur qui spécifie comment identifier les Pods qu'il peut posséder, un nombre de replicas indiquant le nombre de Pods qu'il doit maintenir et un modèle de Pod spécifiant les données que les nouveaux Pods que le replicatSet va créer jusqu'au nombre de replicas demandé. Un ReplicaSet va atteindre son objectif en créant et supprimant des Pods pour atteindre le nombre de réplicas désirés. Quand un ReplicaSet a besoin de créer de nouveaux Pods, il utilise alors son Pod template. Le lien d'un ReplicaSet à ses Pods est fait par le champ [metadata.ownerReferences](/docs/concepts/workloads/controllers/garbage-collection/#owners-and-dependents), qui spécifie la ressource de l'objet par lequel il est détenu. Tous les Pods acquis par un ReplicaSet ont leurs propres informations d'identification de leur Replicaset, avec leur propre champ ownerReferences. C'est par ce lien que le ReplicaSet connait l'état des Pods qu'il maintient et agit en fonction de ces derniers. Un ReplicaSet identifie des nouveaux Pods à acquérir en utilisant son selecteur. Si il y a un Pod qui n'a pas de OwnerReference ou que OwnerReference n'est pas un controller et qu'il correspond à un sélecteur de ReplicaSet, il va immédiatement être acquis par ce ReplicaSet. ## Quand utiliser un ReplicaSet ? Un ReplicaSet garantit qu’un nombre spécifié de réplicas de Pod soient exécutés à un moment donné. Cependant, un Deployment est un concept de plus haut niveau qui gère les ReplicaSets et fournit des mises à jour déclaratives aux Pods ainsi que de nombreuses autres fonctionnalités utiles. Par conséquent, nous vous recommandons d’utiliser des Deployments au lieu d’utiliser directement des ReplicaSets, sauf si vous avez besoin d'une orchestration personnalisée des mises à jour ou si vous n'avez pas besoin de mises à jour. Cela signifie qu'il est possible que vous n'ayez jamais besoin de manipuler des objets ReplicaSet : utilisez plutôt un déploiement et définissez votre application dans la section spec. ## Exemple {{< codenew file="controllers/frontend.yaml" >}} Enregistrer ce manifeste dans `frontend.yaml` et le soumettre à un cluster Kubernetes va créer le ReplicaSet défini et les pods qu’il gère. ```shell kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml ``` Vous pouvez ensuite récupérer les ReplicaSets actuellement déployés : ```shell kubectl get rs ``` Et voir le frontend que vous avez créé : ```shell NAME DESIRED CURRENT READY AGE frontend 3 3 3 6s ``` Vous pouvez également vérifier l'état du ReplicaSet : ```shell kubectl describe rs/frontend ``` Et vous verrez une sortie similaire à : ```shell Name: frontend Namespace: default Selector: tier=frontend,tier in (frontend) Labels: app=guestbook tier=frontend Annotations: Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=guestbook tier=frontend Containers: php-redis: Image: gcr.io/google_samples/gb-frontend:v3 Port: 80/TCP Requests: cpu: 100m memory: 100Mi Environment: GET_HOSTS_FROM: dns Mounts: Volumes: Events: FirstSeen LastSeen Count From SubobjectPath Type Reason Message --------- -------- ----- ---- ------------- -------- ------ ------- 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-qhloh 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-dnjpy 1m 1m 1 {replicaset-controller } Normal SuccessfulCreate Created pod: frontend-9si5l ``` Et enfin, vous pourrez afficher les Pods déployés : ```shell kubectl get Pods ``` Vous devriez voir des informations sur les Pods avec une sortie similaire à : ```shell NAME READY STATUS RESTARTS AGE frontend-9si5l 1/1 Running 0 1m frontend-dnjpy 1/1 Running 0 1m frontend-qhloh 1/1 Running 0 1m ``` Vous pouvez également vérifier que la OwnerReference de ces pods est définie sur le frontend ReplicaSet. Pour ce faire, récupérez le yaml de l’un des pods : ```shell kubectl get pods frontend-9si5l -o yaml ``` La sortie sera similaire à celle-ci, avec les informations de l'interface ReplicaSet frontend définies dans le champ ownerReferences des métadonnées: ```shell apiVersion: v1 kind: Pod metadata: creationTimestamp: 2019-01-31T17:20:41Z generateName: frontend- labels: tier: frontend name: frontend-9si5l namespace: default ownerReferences: - apiVersion: extensions/v1beta1 blockOwnerDeletion: true controller: true kind: ReplicaSet name: frontend uid: 892a2330-257c-11e9-aecd-025000000001 ... ``` ## Acquisitions de Pod en dehors du template Bien que vous puissiez créer des pods manuellement sans problème, il est fortement recommandé de s’assurer que ces pods n'ont pas de labels correspondant au sélecteur de l’un de vos ReplicaSets. Car un ReplicaSet n’est pas limité à posséder les pods spécifiés par son modèle - il peut acquérir d’autres pods de la manière spécifiée dans les sections précédentes. Prenez l'exemple précédent de ReplicaSet, ainsi que les pods spécifiés dans le manifeste suivant : {{< codenew file="pods/pod-rs.yaml" >}} Ces pods n’ayant pas de contrôleur (ni d’objet) en tant que référence propriétaire, ils correspondent au sélecteur de du ReplicaSet frontend, ils seront donc immédiatement acquis par ce ReplicaSet. Supposons que vous créiez les pods une fois le ReplicaSet frontend déployé et qui a déjà déployé ses replicas de Pods initiaux afin de remplir son exigence de nombre de replicas : ```shell kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml ``` Les nouveaux pods seront acquis par le ReplicaSet, puis immédiatement terminés car le ReplicaSet dépasserait alors le compte désiré. En récupérant les pods : ```shell kubectl get Pods ``` La sortie montre que les nouveaux pods sont soit déjà terminés, soit en voie de l'être : ```shell NAME READY STATUS RESTARTS AGE frontend-9si5l 1/1 Running 0 1m frontend-dnjpy 1/1 Running 0 1m frontend-qhloh 1/1 Running 0 1m pod2 0/1 Terminating 0 4s ``` Cependant, si vous créez d'abord les pods : ```shell kubectl apply -f https://kubernetes.io/examples/pods/pod-rs.yaml ``` Et puis créez le ReplicaSet : ```shell kubectl apply -f https://kubernetes.io/examples/controllers/frontend.yaml ``` Vous verrez que le ReplicaSet a acquis les pods et n'a créé que les nouveaux Pods manquants, conformément à ses spécifications, jusqu'au nombre souhaité de Pods. En récupérant les Pods : ```shell kubectl get Pods ``` La sortie va donner : ```shell NAME READY STATUS RESTARTS AGE frontend-pxj4r 1/1 Running 0 5s pod1 1/1 Running 0 13s pod2 1/1 Running 0 13s ``` De cette manière, un ReplicaSet peut avoir un ensemble de Pods hétérogène. ## Écrire un manifest de ReplicaSet Comme avec tous les autres objets API Kubernetes, un ReplicaSet a besoin des champs `apiVersion`, `kind` et `metadata`. Pour ReplicaSets, l'attribut `kind` est toujours ReplicaSet. Dans Kubernetes 1.9, la version de l'API `apps/v1` pour le type ReplicaSet est la version actuelle et activée par défaut. La version de l'API `apps/v1beta2` est obsolète. Reportez-vous aux premières lignes de l'exemple `frontend.yaml` pour obtenir des conseils. Un ReplicaSet a également besoin de [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status). ### Pod Template L'attribut `.spec.template` est un [modèle de pod](/docs/concepts/workloads/Pods/pod-overview/#pod-templates) qui requiert d'avoir des labels. Dans notre exemple `frontend.yaml`, nous avons un label : `tier: frontend`. Il faut faire attention à ne pas avoir des selecteurs que d'autres controllers utilisent, afin d'éviter que le ReplicaSet n'adopte ce pod. Pour le champ [restart policy](/docs/concepts/workloads/Pods/pod-lifecycle/#restart-policy), `.spec.template.spec.restartPolicy`, la seule valeur autorisée est `Always`, qui est la valeur par défaut. ### Sélecteur de Pod Le champ `.spec.selector` est un [label selector](/docs/concepts/overview/working-with-objects/labels/). Tel que discuté [précédemment](#how-a-replicaset-works), ce sont les labels utilisés pour identifier les Pods potentiels à acquérir. Dans notre exemple avec `frontend.yaml`, le sélecteur était : ```shell matchLabels: tier: frontend ``` Dans le ReplicaSet, `.spec.template.metadata.labels` doit correspondre à `spec.selector`, ou sinon il sera rejeté par l'API. {{< note >}} Pour 2 ReplicaSets spécifiant le même `.spec.selector` mais différents `.spec.template.metadata.labels` et `.spec.template.spec`, chaque ReplicaSet ignore les pods créés par l'autre ReplicaSet. {{< /note >}} ### Replicas Vous pouvez spécifier le nombre de pods à exécuter simultanément en définissant `.spec.replicas`. Le ReplicaSet va créer/supprimer ses pods pour correspondre à ce nombre. Si vous ne spécifiez pas `.spec.replicas`, la valeur par défaut est 1. ## Travailler avec des ReplicaSets ### Suppression d'un ReplicaSet et de ses pods Pour supprimer un ReplicaSet et tous ses pods, utilisez [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete). The [Garbage collector](/docs/concepts/workloads/controllers/garbage-collection/) supprime automatiquement tous les pods associés par défaut. Lors de l’utilisation de l’API REST ou de la bibliothèque `client-go`, vous devez définir `propagationPolicy` sur `Background` ou `Foreground` dans l'option -d. Par exemple : ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ > -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \ > -H "Content-Type: application/json" ``` ### Supprimer juste un ReplicaSet Vous pouvez supprimer un ReplicaSet sans affecter ses pods à l’aide de [`kubectl delete`](/docs/reference/generated/kubectl/kubectl-commands#delete) avec l'option `--cascade=false`. Lorsque vous utilisez l'API REST ou la bibliothèque `client-go`, vous devez définir `propagationPolicy` sur `Orphan`. Par exemple : ```shell kubectl proxy --port=8080 curl -X DELETE 'localhost:8080/apis/extensions/v1beta1/namespaces/default/replicasets/frontend' \ > -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \ > -H "Content-Type: application/json" ``` Une fois l’original supprimé, vous pouvez créer un nouveau ReplicaSet pour le remplacer. Tant que l'ancien et le nouveau `.spec.selector` sont identiques, le nouveau adoptera les anciens Pods. Cependant, le ReplicaSet ne fera aucun effort pour que les pods existants correspondent à un nouveau Pod template. Pour mettre à jour les Pods à une nouvelle spec de manière contrôlée, utilisez un [Deployment](/docs/concepts/workloads/controllers/deployment/#creating-a-deployment), car les ReplicaSets ne supportent pas de rolling update directement. ### Isoler les pods d'un ReplicaSet Vous pouvez supprimer les pods d'un ReplicaSet en modifiant leurs labels. Cette technique peut être utilisée pour enlever les pods pour le débogage, récupération de données, etc. Les pods ainsi supprimés seront automatiquement remplacés (en supposant que le nombre de réplicas n’est pas également modifié). ### Scaling d'un ReplicaSet Un ReplicaSet peut facilement être scalé en mettant simplement à jour le champ `.spec.replicas`. Le contrôleur ReplicaSet garantit que le nombre souhaité de pods avec un sélecteur de label correspondant soient disponibles et opérationnels. ### ReplicaSet en tant que Horizontal Pod Autoscaler Target Un ReplicaSet peut également être une cible pour [Horizontal Pod Autoscalers (HPA)](/docs/tasks/run-application/horizontal-pod-autoscale/). Un ReplicaSet peut être mis à l'échelle automatiquement par un HPA. Voici un exemple HPA qui cible le ReplicaSet que nous avons créé dans l'exemple précédent. {{< codenew file="controllers/hpa-rs.yaml" >}} Enregistrer ce manifeste dans `hpa-rs.yaml` et le soumettre à un cluster Kubernetes devrait créer le HPA défini qui scale automatiquement le ReplicaSet cible en fonction de l'utilisation du processeur des pods répliqués. ```shell kubectl apply -f https://k8s.io/examples/controllers/hpa-rs.yaml ``` Vous pouvez aussi utiliser la commande `kubectl autoscale` pour accomplir la même chose. (et c'est plus facile !) ```shell kubectl autoscale rs frontend --max=10 ``` ## Alternatives au ReplicaSet ### Deployment (recommandé) Le [`Deployment`](/docs/concepts/workloads/controllers/deployment/) est un object qui peut posséder les ReplicaSets et les mettres à jour ainsi que leurs Pods de façon déclarative, côté serveur et avec des rolling updates. Alors que les ReplicaSets peuvent être utilisés indépendamment, ils sont principalement utilisés aujourd'hui par Deployments comme mécanisme pour orchestrer la création, suppresion et mises à jour des Pods. Lorsque vous utilisez des Deployments, vous n’aurez plus à vous soucier de la gestion des ReplicaSets ainsi créés. Les déploiements possèdent et gèrent leurs ReplicaSets. C'est pourquoi il est recommandé d’utiliser les déploiements lorsque vous voulez des ReplicaSets. ### Pods nus Contrairement au cas où un utilisateur a créé directement des pods, un ReplicaSet remplace les pods supprimés ou terminés pour quelque raison que ce soit, par exemple en cas de défaillance d'un nœud ou de maintenance de nœud perturbateur, telle qu'une mise à jour kernel. Pour cette raison, nous vous recommandons d'utiliser un ReplicaSet même si votre application ne nécessite qu'un seul pod. Pensez-y de la même manière qu’un superviseur de processus, mais il supervise plusieurs pods sur plusieurs nœuds au lieu de processus individuels sur un seul nœud. Un ReplicaSet délègue les redémarrages de conteneurs locaux à un agent du nœud (par exemple, Kubelet ou Docker). ### Job Utilisez un [`Job`](/docs/concepts/jobs/run-to-completion-finite-workloads/) au lieu d'un ReplicaSet pour les pods qui doivent se terminer seuls (c'est à dire des batch jobs). ### DaemonSet Utilisez un [`DaemonSet`](/docs/concepts/workloads/controllers/daemonset/) au lieu d’un ReplicaSet pour les pods qui fournissent une fonction au niveau du noeud, comme le monitoring ou la gestion des logs de ce noeud. Ces pods ont une durée de vie qui est liée durée de vie d’une machine : le pod doit être en cours d’exécution sur la machine avant le démarrage des autres Pods et sont sûrs de se terminer lorsque la machine est prête à être redémarrée/arrêtée. ### ReplicationController Les ReplicaSets sont les successeurs de [_ReplicationControllers_](/docs/concepts/workloads/controllers/replicationcontroller/). Les deux servent le même objectif et se comportent de la même manière, à la différence près que ReplicationController ne prend pas en charge les les exigences de sélecteur décrites dans le [labels user guide](/docs/concepts/overview/working-with-objects/labels/#label-selectors). En tant que tels, les ReplicaSets sont préférés aux ReplicationControllers.