Introduction
Les Kubernetes CronJobs exécutent des Pods de courte durée selon un horaire. Contrairement à des Deployments persistants, ces Pods peuvent échouer silencieusement entre deux runs. Les erreurs réseau en sont une cause fréquente : résolution DNS, Services et ports du cluster, NetworkPolicies, ou contrôles d'egress au niveau des nœuds et du cloud. Leur nature éphémère rend le diagnostic plus délicat.
Cet article montre comment dépanner le réseau des CronJobs avec un rayon d'impact minimal. Vous allez inventorier l'environnement, construire un chemin de test sûr, exécuter des vérifications ciblées (DNS, ports, Services), valider les résultats et restaurer proprement en cas d'erreur. Tout est conçu pour être pratique et reproductible, que vous opériez avec Docker, GitLab CI/CD, de l'automatisation Python ou des scripts Bash.
Remarque SEO (mots-clés préservés) : Kubernetes CronJobs networking, Kubernetes CronJobs DNS, Kubernetes CronJobs ports, Kubernetes CronJobs connectivity, Kubernetes CronJobs network troubleshooting.
Inventaire des versions et de l'environnement
Avant de changer quoi que ce soit, collectez les faits. Cela évite de deviner et aide à traiter le bon niveau.
Prérequis :
- Accès kubectl au cluster et aux namespaces concernés
- Capacité à créer un namespace temporaire et à appliquer des manifestes
- Familiarité de base avec CronJob, Job, Pod
Commandes d'inventaire :
- Identifier les versions Kubernetes et kubectl :
kubectl version --short- Lister les nœuds et indices CNI (les labels fournisseurs suggèrent parfois le CNI et le mode réseau) :
kubectl get nodes -o wide- Confirmer la présence de CoreDNS et noter l'image :
kubectl -n kube-system get deploy coredns -o yaml | grep -i image- Vérifier si des NetworkPolicies sont en vigueur (Calico, Cilium, etc.) :
kubectl get pods -A | grep -Ei "calico|cilium|weave|ovn|antrea"- Noter les namespaces et les CronJobs existants :
kubectl get nskubectl get cronjobs -A
Pour chaque CronJob cible, sauvegardez le spec avant toute modification :
kubectl -n YOUR_NS get cronjob YOUR_CRON -o yaml > YOUR_CRON.backup.yaml
Consignez :
- Version de Kubernetes et type d'hébergement (cloud/on‑prem)
- Version de CoreDNS
- Présence de contrôleurs de NetworkPolicy
- Si l'egress est contrôlé par NetworkPolicy, firewall des nœuds ou groupes de sécurité cloud
Chemin de configuration sûr
Utilisez un pilote étroit et mesurable afin d'observer les résultats sans impacter la production.
- Créer un namespace de test isolé :
kubectl create ns jobs-test
- Créer un CronJob de sondage minimal avec labels explicites et politiques conservatrices. Cet exemple exécute des requêtes DNS, une requête HTTPS externe, et une sonde de port vers un Service. Adaptez les cibles à votre environnement.
Exemple de manifeste :
apiVersion: batch/v1
kind: CronJob
metadata:
name: net-check
namespace: jobs-test
spec:
schedule: "*/10 * * * *"
concurrencyPolicy: Forbid
startingDeadlineSeconds: 60
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
backoffLimit: 0
template:
metadata:
labels:
app: net-check
spec:
restartPolicy: Never
containers:
- name: busybox
image: busybox:1.36
command: ["sh","-lc"]
args:
- |
set -eu
echo "DNS test..."
nslookup kubernetes.default.svc.cluster.local || exit 12
nslookup example.com || exit 13
echo "HTTP test..."
wget -q --spider --timeout=5 https://example.com || exit 14
echo "Port test to a Service (hypothetical)..."
nc -vz -w5 my-service.my-namespace.svc.cluster.local 5432 || true
echo "All checks attempted"
Notes :
- L'image est choisie pour sa simplicité. Si une commande manque, changez d'outil ou lancez un Pod de diagnostic ad‑hoc (voir plus bas).
- La sonde de port utilise un Service et un port hypothétiques. Remplacez par une cible réelle du cluster.
backoffLimit: 0évite les multiples relances qui encombrent les logs.concurrencyPolicy: Forbidempêche les chevauchements lors de tests répétés.
- Optionnel : ajouter une NetworkPolicy ciblée pour confirmer/infirmer vos hypothèses DNS/egress. Commencez étroit, élargissez au besoin. Cet exemple autorise le DNS vers CoreDNS (par namespace) et la sortie TCP/443 vers Internet. Serrez
ipBlockà vos CIDR d'egress réels si possible.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns-and-https
namespace: jobs-test
spec:
podSelector:
matchLabels:
app: net-check
policyTypes:
- Egress
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
- to:
- ipBlock:
cidr: 0.0.0.0/0
ports:
- protocol: TCP
port: 443
- Appliquer et lancer un Job ponctuel immédiatement pour éviter d'attendre le planning :
kubectl -n jobs-test apply -f net-check.yamlkubectl -n jobs-test create job --from=cronjob/net-check net-check-now
- Observer la sortie et le code retour :
kubectl -n jobs-test logs job/net-check-nowkubectl -n jobs-test get job net-check-now -o jsonpath='{.status.succeeded}{"\n"}'
- Pour des tests interactifs, exécuter un Pod de diagnostic ad‑hoc et vérifier la résolution et la connectivité :
kubectl -n jobs-test run diag --rm -it --image=busybox:1.36 --restart=Never -- sh- Dans le shell :
cat /etc/resolv.confnslookup kubernetes.default.svc.cluster.localnslookup example.comwget -q --spider --timeout=5 https://example.comnc -vz -w5 my-service.my-namespace.svc.cluster.local 5432
Vérification et diagnostics
Changez une seule variable à la fois et interprétez méthodiquement :
- Confirmer que le Job a bien tourné
Attendu en cas de succès : status.succeeded=1, pas d'atteinte du backoff, Pod en phase Succeeded.
kubectl -n jobs-test get jobskubectl -n jobs-test describe job net-check-now
- Examiner les événements et logs du Pod
Cherchez des timeouts, connection refused, ou erreurs de résolution.
kubectl -n jobs-test get pods -l job-name=net-check-nowkubectl -n jobs-test describe pod POD_NAMEkubectl -n jobs-test logs POD_NAME
- Contrôles DNS
Attendu : peu ou pas de SERVFAIL ou timeout corrélés à l'heure d'exécution du Job.
- Inspecter la configuration resolver depuis un Pod similaire :
kubectl -n jobs-test exec -it DEPLOYMENT_OR_POD -- cat /etc/resolv.conf- Avec
ndots=5, un nom court commeexample.compeut déclencher plusieurs recherches via le search path. Utilisez un point final (ex.example.com.) ou un FQDN complet pour éviter des délais dans des Pods de courte durée. - Vérifier la santé de CoreDNS et les erreurs de requêtes :
kubectl -n kube-system logs deploy/coredns --tail=200 | grep -Ei "timeout|servfail|refused|dns" || true
- Services et Endpoints (cibles intra‑cluster)
Attendu : le Service possède au moins un endpoint. Des endpoints vides indiquent des Pods non Ready ou un selector incorrect.
kubectl -n my-namespace get svc my-service -o widekubectl -n my-namespace get endpoints my-service -o wide
- NetworkPolicies
Attendu : s'il y a un « default‑deny egress », autorisez explicitement le DNS et les destinations requises.
- Lister les politiques dans le namespace du CronJob et celui de la cible :
kubectl -n jobs-test get networkpolicykubectl -n my-namespace get networkpolicy- Examiner les règles susceptibles de sélectionner les Pods du CronJob (labels/namespace) :
kubectl -n jobs-test describe networkpolicy NAME
- Egress et firewalls nœud/cloud
Attendu : les nœuds atteignent les adresses externes requises sur les ports nécessaires.
- Si le DNS fonctionne mais que l'HTTPS externe échoue, vérifiez si l'egress est restreint :
- Cloud : le groupe de sécurité ou firewall des nœuds doit autoriser TCP/443 et UDP/TCP/53 sortants.
- On‑prem : les firewalls des nœuds doivent autoriser UDP/TCP/53 vers CoreDNS et les ports externes nécessaires, avec NAT disponible.
- Sanité kube‑proxy et routage
Attendu : pas d'erreurs iptables/ipvs récurrentes au moment du run.
- Si un Service ClusterIP est injoignable alors que des endpoints existent, suspectez kube‑proxy ou le routage. Vérifiez les logs kube‑proxy (souvent dans kube‑system) :
kubectl -n kube-system logs -l k8s-app=kube-proxy --tail=200
Symptômes courants, causes probables et contrôles
| Symptom ou log | Cause probable | À vérifier |
|---|---|---|
| no such host | Échec DNS ou egress DNS bloqué | nslookup dans le Pod ; logs CoreDNS ; NetworkPolicy UDP/TCP 53 |
| i/o timeout | Egress bloqué ou cible distante indisponible | Firewall cloud/nœud ; règles ipBlock ; alternative traceroute (curl/wget -m) |
| connection refused | Port fermé ou mauvais Service/port | Service .spec.ports, Endpoints, listener de l'app |
| Endpoints vides | Selectors erronés ou Pods non Ready | Selector du Service ; labels Pods ; readiness |
| BackoffLimitExceeded | Échec persistant ou timeouts trop courts | Panne réseau sous-jacente ; ajuster délais du script |
Exemples de sorties attendues (exemples construits)
- Succès DNS :
nslookup example.comServer: 10.96.0.10Address: 10.96.0.10:53Name: example.comAddress: 93.184.216.34- Succès HTTPS :
wget -q --spider --timeout=5 https://example.comretourne le code 0- Sonde de port vers un Service (hypothétique) :
nc -vz -w5 my-service.my-namespace.svc.cluster.local 5432affiche succeeded ou expire si bloqué
Ajuster le périmètre en sécurité
- Si le DNS échoue, autorisez d'abord uniquement UDP/TCP 53 vers kube‑system (CoreDNS). Évitez d'ouvrir
0.0.0.0/0avant d'avoir prouvé son utilité. - Si l'HTTPS externe est requis, n'autorisez que des CIDR connus ou passez par un proxy si disponible.
- Étiquetez toujours le Pod template du CronJob (par ex.
app: net-check) pour cibler précisément vos NetworkPolicies.
Modes de panne et récupération
- Mettre en pause/arrêter rapidement
- Suspendre un CronJob pour empêcher de nouveaux Jobs :
kubectl -n jobs-test patch cronjob net-check -p '{"spec": {"suspend": true}}'- Supprimer les Jobs en attente :
kubectl -n jobs-test delete job -l job-name=net-check
- Rétablir les manifestes
- Restaurer un CronJob depuis la sauvegarde :
kubectl -n YOUR_NS apply -f YOUR_CRON.backup.yaml- Revenir en arrière sur la NetworkPolicy (supprimer la politique de test ou réappliquer la version précédente) :
kubectl -n jobs-test delete networkpolicy allow-dns-and-https
- Réduire le rayon d'impact
- Utilisez
backoffLimit: 0et des timeouts courts (ex.wget --timeout=5) dans les Jobs de test pour éviter les blocages longs. - Préférez
concurrencyPolicy: Forbidpour éviter les chevauchements qui peuvent stresser les services en aval.
- Vérifier le rétablissement
- Après un rollback, exécuter un Job ponctuel pour confirmer le retour à la normale :
kubectl -n jobs-test create job --from=cronjob/net-check net-check-verifykubectl -n jobs-test logs job/net-check-verify- S'assurer que les CronJobs de production sont intacts :
kubectl -n PROD_NS get jobs --sort-by=.metadata.creationTimestamp | tail -n 5
Causes racines typiques et remèdes
| Cause racine | Remède minimal | Vérification |
|---|---|---|
| Default‑deny egress bloque le DNS | Autoriser UDP/TCP 53 vers kube‑system | nslookup kubernetes.default.svc.cluster.local réussit |
| Nom de Service ou port erroné | Corriger le DNS Service ou le port et redéployer | nc -vz vers nom: port correct aboutit |
| Egress externe bloqué | Ouvrir TCP/443 (ou port requis) vers des CIDR autorisés | wget --spider https://target.example retourne 0 |
| Lenteurs resolver (search path) | Utiliser FQDN/point final ; réduire les recherches | Latence DNS en baisse ; Job sort plus tôt |
| Endpoints manquants (labels) | Corriger le selector du Service | kubectl get endpoints montre des adresses prêtes |
Checklist d'exploitation
| Étape | Commande/action | Résultat attendu |
|---|---|---|
| Sauvegarder le CronJob | kubectl -n NS get cronjob NAME -o yaml > NAME.bak.yaml | Fichier de backup créé |
| Créer le namespace test | kubectl create ns jobs-test | Namespace présent |
| Appliquer le CronJob test | kubectl -n jobs-test apply -f net-check.yaml | CronJob créé |
| Run ponctuel | kubectl -n jobs-test create job --from=cronjob/net-check net-check-now | Job créé |
| Récupérer les logs | kubectl -n jobs-test logs job/net-check-now | Traces DNS/HTTP visibles |
| Inspecter les événements | kubectl -n jobs-test describe pod POD | Erreurs/succès clairs |
| Logs CoreDNS | kubectl -n kube-system logs deploy/coredns --tail=200 | Pas de timeouts/SERVFAIL au run |
| Vérifier Endpoints | kubectl -n APP_NS get endpoints SVC | Endpoints non vides |
| Appliquer egress policy | kubectl -n jobs-test apply -f allow-dns-and-https.yaml | Politique appliquée |
| Relancer et vérifier | kubectl -n jobs-test create job --from=cronjob/net-check net-check-again | Succès ou échec plus clair |
| Suspendre si besoin | kubectl -n jobs-test patch cronjob net-check -p '{"spec":{"suspend":true}}' | Nouveaux Jobs stoppés |
| Rollback policy | kubectl -n jobs-test delete networkpolicy allow-dns-and-https | Politique retirée |
Conclusion
Les CronJobs sont particulièrement sensibles aux frictions réseau du fait de leur brièveté et de leur planification. La voie la plus efficace vers la cause racine : démarrer par un pilote étroit et observable, inventorier l'environnement, exécuter un CronJob de diagnostic, puis tester dans l'ordre DNS, Endpoints/Services et egress. Ajustez les NetworkPolicies avec précision, préférez les FQDN pour éviter les écueils du resolver, et gardez des backoffs/timeouts conservateurs pendant les tests. En cas de problème, suspendez le CronJob, restaurez vos manifestes ou politiques à partir des sauvegardes, puis confirmez par un Job ponctuel. Adoptez la checklist de ce guide comme runbook : pour chaque nouveau CronJob dépendant du réseau, créez une variante de diagnostic, prouvez la connectivité en isolation, et seulement ensuite planifiez‑le. Ainsi, les incidents restent contenus, les correctifs rapides et les résultats prévisibles.