Configurez le nombre de pods, les ressources, la planification et l'isolation des nœuds pour éviter les pannes de CoreDNS en mode non géré.
En mode non géré, la disponibilité et les performances de CoreDNS dépendent du nombre de pods, des limites de ressources, de la planification et de la distribution des nœuds. Les paramètres par défaut conviennent aux petits clusters ; les charges de travail de production nécessitent un ajustement fin.
Impacts potentiels
Une configuration incorrecte ou des ressources insuffisantes pour CoreDNS entraînent deux catégories de problèmes :
Disponibilité : une planification incorrecte crée des points de défaillance uniques au niveau du nœud ou de la zone. Des ressources insuffisantes provoquent l'éviction des pods et des pannes DNS.
Performances : la contention des ressources sur des nœuds partagés augmente la latence de réponse. Une charge élevée des nœuds entraîne une perte de paquets I/O et des échecs de requêtes DNS.
Ajuster le nombre de pods CoreDNS
Étant donné que l'UDP ne dispose pas de mécanisme de retransmission, la réduction du nombre de pods ou le redémarrage de CoreDNS — en particulier lorsque des défauts IPVS provoquent une perte de paquets — peuvent déclencher des délais d'expiration ou des échecs de résolution DNS à l'échelle du cluster, durant jusqu'à cinq minutes. Consultez la section Dépannage des problèmes de résolution DNS.
N'utilisez pas l'autoscaling horizontal des pods (HPA) ni CronHPA pour CoreDNS. Les réductions fréquentes du nombre de pods provoquent des échecs de résolution.
Évaluer la pression DNS
Avant d'ajuster le nombre de réplicas, évaluez la pression DNS. Des outils tels que DNSPerf permettent de mesurer la charge DNS.
Si vous ne pouvez pas mesurer directement la pression DNS, suivez ces recommandations :
Exécutez au moins 2 pods CoreDNS avec des limites de ressources d'au moins 1 cœur et 1 Go de mémoire.
Les QPS de résolution DNS évoluent linéairement avec la consommation CPU. Avec NodeLocal DNSCache, chaque cœur CPU gère plus de 10 000 requêtes par seconde (QPS). Les besoins en QPS varient considérablement selon les charges de travail ; surveillez donc l'utilisation maximale du CPU de chaque pod CoreDNS. Si un pod dépasse un cœur pendant les heures de pointe, augmentez le nombre de réplicas.
En l'absence de données de charge, commencez avec 1 pod pour 8 nœuds comme référence de base.
L'augmentation du nombre de pods n'est efficace que si les nœuds disposent de ressources suffisantes. Si la mémoire des nœuds est faible, ajoutez des nœuds ou augmentez les ressources par nœud.
Une fois que vous connaissez le nombre cible de réplicas, utilisez l'ajustement automatique (recommandé) ou mettez à l'échelle manuellement.
Configurer l'ajustement automatique (recommandé)
Le composant cluster-proportional-autoscaler ajuste les réplicas CoreDNS en fonction de la taille du cluster. Contrairement au HPA, il ne s'appuie pas sur les métriques CPU et n'effectue pas de réductions perturbatrices. Le ratio par défaut est de 1 pod pour 8 nœuds.
Formule de calcul du nombre de réplicas : replicas = max(ceil(cores × 1/coresPerReplica), ceil(nodes × 1/nodesPerReplica)). Les paramètres min et max limitent le nombre entre 2 et 100.
Déployez l'autoscaler :
apiVersion: apps/v1
kind: Deployment
metadata:
name: dns-autoscaler
namespace: kube-system
labels:
k8s-app: dns-autoscaler
spec:
selector:
matchLabels:
k8s-app: dns-autoscaler
template:
metadata:
labels:
k8s-app: dns-autoscaler
spec:
serviceAccountName: admin
containers:
- name: autoscaler
image: registry.cn-hangzhou.aliyuncs.com/acs/cluster-proportional-autoscaler:1.8.4
resources:
requests:
cpu: "200m"
memory: "150Mi"
command:
- /cluster-proportional-autoscaler
- --namespace=kube-system
- --configmap=dns-autoscaler
- --nodelabels=type!=virtual-kubelet
- --target=Deployment/coredns
- --default-params={"linear":{"coresPerReplica":64,"nodesPerReplica":8,"min":2,"max":100,"preventSinglePointFailure":true}}
- --logtostderr=true
- --v=9
Mettre à l'échelle manuellement
Pour définir un nombre spécifique de réplicas :
kubectl scale --replicas=<target> deployment/coredns -n kube-system # Replace <target> with the target number of pods.
Ajuster les spécifications des pods CoreDNS
Dans un cluster ACK Pro, la configuration par défaut des pods CoreDNS est la suivante :
| Ressource | Limite par défaut |
|---|---|
| CPU | Aucune limite |
| Mémoire | 2 GiB |
Définissez la limite CPU à 4096m (minimum 1024m) en fonction de votre utilisation de pointe observée.
La modification des spécifications des pods CoreDNS entraîne leur redémarrage, ce qui peut provoquer de brèves pointes de latence DNS ou des échecs. Effectuez cette opération pendant les heures creuses.
Connectez-vous à la console ACK . Dans le volet de navigation de gauche, cliquez sur Clusters .
Sur la page Clusters , cliquez sur le nom du cluster cible. Dans le volet de navigation de gauche, cliquez sur Add-ons .
Sous l'onglet Networking , recherchez CoreDNS et cliquez sur Configuration .
-
Modifiez la configuration CoreDNS et cliquez sur OK .
Dans la boîte de dialogue CoreDNS Parameter Settings , configurez les paramètres suivants :
MemoryRequest : la demande de mémoire, par exemple
100Mi.CpuRequest : la demande de CPU, par exemple
100m.MemoryLimit : la limite de mémoire, par exemple
2Gi. Si la limite de mémoire est trop basse, le pod risque d'être arrêté (OOMKilled).CpuLimit : la limite de CPU. Nous vous recommandons de la définir au double de la valeur de CpuRequest.
NodeSelector : le libellé de sélection de nœud. Par exemple, définissez Key sur
kubernetes.io/oset Value surlinux.
Déployer sur un pool de nœuds dédié
Un pool de nœuds dédié isole CoreDNS des autres charges de travail et évite la contention des ressources.
La replanification des pods CoreDNS entraîne leur redémarrage, ce qui peut provoquer de brèves pointes de latence DNS ou des échecs. Effectuez cette opération pendant les heures creuses.
Créer un pool de nœuds dédié
Lors de la création du pool de nœuds, respectez les consignes suivantes :
CoreDNS sollicite intensivement le réseau, mais peu le calcul. Utilisez des instances optimisées pour le réseau, avec une taille recommandée de 4 cœurs et 8 Go de mémoire.
Le pool de nœuds doit comporter au moins 2 nœuds, car CoreDNS exécute 2 pods par défaut.
Ajoutez une taint et un libellé pour empêcher l'exécution d'autres pods sur ces nœuds. Par exemple, utilisez
system-addon: system-addoncomme paire clé-valeur de taint et comme libellé, avecEffectdéfini surNoSchedule.
Consultez la section Créer et gérer des pools de nœuds .
Planifier les pods CoreDNS sur le pool de nœuds
Sur la page Add-ons , recherchez la carte CoreDNS et cliquez sur Configuration .
-
Dans la section NodeSelector , ajoutez le libellé du pool de nœuds dédié.
Ne supprimez pas les libellés NodeSelector existants.
-
Dans la section Tolerations , ajoutez une tolérance correspondant à la taint du pool de nœuds.
Ajoutez une entrée de tolérance dans Tolerations : définissez effect sur
NoSchedule, key sursystem-addon, operator surEqualet value sursystem-addon. -
Cliquez sur OK , puis vérifiez que les pods CoreDNS s'exécutent sur les nœuds dédiés :
kubectl -n kube-system get pod -o wide --show-labels | grep coredns
Utiliser des politiques de planification pour la haute disponibilité
Pour protéger la disponibilité DNS, CoreDNS utilise deux politiques de planification par défaut :
Anti-affinité de pod (niveau nœud) : empêche l'exécution de deux pods CoreDNS sur le même nœud. En cas de panne d'un nœud, le DNS reste disponible sur les autres nœuds.
Planification consciente de la topologie (niveau zone) : répartit les pods CoreDNS entre les zones de disponibilité, évitant ainsi les points de défaillance uniques au niveau de la zone que l'anti-affinité de pod seule ne peut pas résoudre.
Ces politiques s'appliquent uniquement lors de la planification initiale. Si les configurations des nœuds ou des zones changent, localisez le déploiement coredns dans la console ACK et cliquez sur Redeploy .
Anti-affinité de pod
CoreDNS utilise une règle d'anti-affinité requiredDuringSchedulingIgnoredDuringExecution pour empêcher deux pods CoreDNS de partager un nœud. Cela nécessite au moins 2 nœuds disposant de ressources suffisantes, à l'exclusion :
k8s.aliyun.com: true— nœuds avec la mise à l'échelle automatique des nœuds activéetype: virtual-kubelet— nœuds virtuelsalibabacloud.com/lingjun-worker: true— nœuds Lingjun
La configuration d'affinité par défaut est la suivante :
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
# virtual nodes have this label
- key: type
operator: NotIn
values:
- virtual-kubelet
# lingjun worker nodes have this label
- key: alibabacloud.com/lingjun-worker
operator: NotIn
values:
- "true"
preferredDuringSchedulingIgnoredDuringExecution:
- preference:
matchExpressions:
# autoscaled nodes have this label
- key: k8s.aliyun.com
operator: NotIn
values:
- "true"
weight: 100
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: k8s-app
operator: In
values:
- kube-dns
topologyKey: kubernetes.io/hostname
Planification consciente de la topologie
Par défaut, CoreDNS utilise la planification consciente de la topologie pour répartir les pods entre les zones. Le paramètre whenUnsatisfiable: DoNotSchedule applique cette règle : les pods ne seront pas planifiés si la condition d'équilibre des zones ne peut pas être satisfaite.
Pour que cela fonctionne de manière fiable :
Votre cluster doit disposer de nœuds dans au moins 2 zones différentes, chacune contenant au moins 1 nœud avec suffisamment de ressources pour CoreDNS.
Tous les nœuds doivent posséder le libellé
topology.kubernetes.io/zone(appliqué par défaut). Des libellés manquants ou incohérents entraînent des échecs de planification ou une répartition inégale.Mettez à jour votre cluster vers la version v1.27 ou ultérieure et CoreDNS vers la version v1.12.1.3 ou ultérieure. Les versions antérieures du cluster ne prennent pas en charge matchLabelKeys ; ainsi, une mise à jour progressive de CoreDNS peut aboutir à une répartition inégale des pods entre les zones, voire laisser certaines zones non couvertes. Consultez la configuration
matchLabelKeysdécrite ci-dessous.
Les versions de CoreDNS antérieures à la v1.12.1.3 utilisent cette contrainte de répartition topologique :
topologySpreadConstraints:
- labelSelector:
matchLabels:
k8s-app: kube-dns
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
La différence de nombre de pods entre deux zones quelconques ne peut pas dépasser maxSkew (par défaut 1). Le sélecteur labelSelector compte les pods des ReplicaSets nouveaux et anciens ; ainsi, pour respecter maxSkew=1 , le planificateur favorise les zones ayant le moins de pods au total. Après l'arrêt des anciens pods, les nouveaux pods peuvent se concentrer dans quelques zones.
CoreDNS v1.12.1.3 et versions ultérieures corrige ce problème grâce à matchLabelKeys (Kubernetes v1.27+) :
topologySpreadConstraints:
- labelSelector:
matchLabels:
k8s-app: kube-dns
matchLabelKeys:
- pod-template-hash
nodeTaintsPolicy: Honor
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
L'ajout de matchLabelKeys: [pod-template-hash] limite la contrainte au ReplicaSet actuel, de sorte que les mises à jour progressives répartissent les pods uniformément entre les zones.