
Votre application tourne dans le cluster, mais vous ne pouvez pas y accéder. Kubernetes isole les pods du réseau extérieur par défaut — c’est voulu. Pour y accéder, vous disposez de 3 commandes complémentaires : kubectl expose crée un Service permanent, kubectl port-forward ouvre un tunnel temporaire vers un pod ou un service, et kubectl proxy donne accès à l’API Kubernetes via un proxy local. Ce guide vous aide à choisir la bonne commande et à l’utiliser correctement.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- Choisir entre
expose,port-forwardetproxyselon votre besoin - Créer un Service avec
kubectl exposeen choisissant le bon type (ClusterIP, NodePort, LoadBalancer) - Rediriger un port local vers un pod ou un service pour le dev/debug
- Accéder à l’API Kubernetes et aux dashboards internes via
kubectl proxy - Diagnostiquer les problèmes de connectivité et de routage
Quelle commande utiliser ?
Section intitulée « Quelle commande utiliser ? »Avant tout, identifiez votre besoin :
| Besoin | Commande | Durée | Ce que ça fait |
|---|---|---|---|
| Rendre une app accessible dans le cluster | kubectl expose --type=ClusterIP | Permanent | Crée un Service avec une IP interne stable |
| Rendre une app accessible hors du cluster | kubectl expose --type=NodePort ou LoadBalancer | Permanent | Crée un Service avec accès externe |
| Accéder à un pod/service depuis ma machine (dev, debug) | kubectl port-forward | Temporaire (durée de la commande) | Tunnel direct local → pod/service |
| Explorer l’API Kubernetes ou accéder à un dashboard | kubectl proxy | Temporaire (durée de la commande) | Proxy HTTP local vers l’API server |
kubectl expose : créer un Service
Section intitulée « kubectl expose : créer un Service »kubectl expose crée un objet Service qui devient le point d’entrée réseau permanent vers votre application. Le Service utilise les labels de la ressource ciblée pour trouver les pods à router.
kubectl expose <type> <nom> --port=<port-service> --target-port=<port-conteneur> --type=<type-service>--port: le port exposé par le Service (celui que les clients utiliseront)--target-port: le port sur lequel le conteneur écoute (défini dans le pod)--type: le type de Service à créer
Les 3 types de Services
Section intitulée « Les 3 types de Services »Le Service reçoit une IP interne accessible uniquement depuis l’intérieur du cluster. C’est le choix par défaut et le plus courant pour la communication entre microservices.
kubectl expose deploy api-gateway --port=80 --target-port=8080service/api-gateway exposedVérification :
kubectl get svc api-gatewayNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEapi-gateway ClusterIP 10.96.45.123 <none> 80/TCP 5sLe Service est accessible depuis n’importe quel pod du cluster via api-gateway.default.svc.cluster.local:80 ou simplement api-gateway:80 dans le même namespace.
Le Service ouvre un port fixe (30000-32767) sur chaque nœud du cluster. Tout trafic arrivant sur <IP-noeud>:<NodePort> est routé vers les pods.
kubectl expose deploy api-gateway --port=80 --target-port=8080 --type=NodePortNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEapi-gateway NodePort 10.96.45.123 <none> 80:31245/TCP 5sL’application est accessible sur http://<IP-de-nimporte-quel-noeud>:31245.
Le Service demande un load balancer externe au cloud provider (AWS ELB, GCP LB, Azure LB…). Il reçoit une IP publique ou un hostname DNS.
kubectl expose deploy api-gateway --port=80 --target-port=8080 --type=LoadBalancerNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGEapi-gateway LoadBalancer 10.96.45.123 203.0.113.42 80:31245/TCP 30sChoisir les bons ports
Section intitulée « Choisir les bons ports »La confusion entre --port et --target-port est l’erreur la plus fréquente. Voici comment les distinguer :
Client → [Service:port] → [Pod:targetPort]| Flag | Ce qu’il définit | Exemple |
|---|---|---|
--port | Le port du Service (côté client) | 80 — les autres pods appellent api-gateway:80 |
--target-port | Le port du conteneur (côté application) | 8080 — votre app écoute sur 8080 |
Si --target-port est omis, il prend la même valeur que --port.
Exposer avec un nom personnalisé
Section intitulée « Exposer avec un nom personnalisé »Par défaut, le Service prend le nom de la ressource exposée. Pour choisir un autre nom :
kubectl expose deploy api-gateway --port=80 --target-port=8080 --name=api-publicVérifier que le Service route correctement
Section intitulée « Vérifier que le Service route correctement »-
Vérifiez que le Service existe et a des endpoints
Fenêtre de terminal kubectl get svc api-gatewaykubectl get endpoints api-gatewaySi
ENDPOINTSest vide, le Service ne trouve aucun pod correspondant à son selector. -
Comparez les selectors du Service avec les labels des pods
Fenêtre de terminal # Selector du Servicekubectl get svc api-gateway -o jsonpath='{.spec.selector}'# Labels des podskubectl get pods --show-labelsLes labels des pods doivent correspondre exactement au selector du Service.
-
Testez la connectivité depuis un pod du cluster
Fenêtre de terminal kubectl run test-curl --rm -it --image=curlimages/curl -- \curl -s http://api-gateway:80
kubectl port-forward : tunnel temporaire pour le dev
Section intitulée « kubectl port-forward : tunnel temporaire pour le dev »kubectl port-forward crée un tunnel direct entre votre machine locale et un pod ou un service dans le cluster. Le tunnel reste actif tant que la commande tourne — coupez-la et l’accès disparaît.
Quand l’utiliser
Section intitulée « Quand l’utiliser »- Débugger une application qui n’est pas exposée à l’extérieur
- Accéder à un dashboard (Grafana, Prometheus, Kibana) sans créer de Service dédié
- Tester une API avant de la rendre accessible
- Accéder à une base de données depuis un outil local (DBeaver, pgAdmin…)
kubectl port-forward <type>/<nom> <port-local>:<port-distant> [-n namespace]Recettes courantes
Section intitulée « Recettes courantes »Accéder à un pod
Section intitulée « Accéder à un pod »kubectl port-forward pod/api-server-7d4b8c 8080:8080 -n prodForwarding from 127.0.0.1:8080 -> 8080Ouvrez http://localhost:8080 dans votre navigateur.
Accéder via un Service (recommandé)
Section intitulée « Accéder via un Service (recommandé) »Cibler un Service plutôt qu’un pod permet au port-forward de suivre automatiquement si le pod redémarre :
kubectl port-forward svc/grafana 3000:3000 -n monitoringRediriger plusieurs ports
Section intitulée « Rediriger plusieurs ports »kubectl port-forward pod/mon-app-7d4b8c 8080:8080 9090:9090 -n prodChoisir l’adresse locale d’écoute
Section intitulée « Choisir l’adresse locale d’écoute »Par défaut, le tunnel n’écoute que sur 127.0.0.1. Pour le rendre accessible depuis d’autres machines de votre réseau :
kubectl port-forward --address 0.0.0.0 svc/grafana 3000:3000 -n monitoringLaisser le système choisir le port local
Section intitulée « Laisser le système choisir le port local »Si le port 8080 est déjà pris sur votre machine :
kubectl port-forward svc/api-gateway :8080 -n prodLe :8080 (sans port local) laisse le système attribuer un port libre. La commande affiche le port choisi.
Workflow typique : accéder à un dashboard Prometheus
Section intitulée « Workflow typique : accéder à un dashboard Prometheus »-
Identifiez le Service Prometheus
Fenêtre de terminal kubectl get svc -n monitoring | grep prometheusprometheus-server ClusterIP 10.96.12.45 <none> 9090/TCP 30d -
Ouvrez le tunnel
Fenêtre de terminal kubectl port-forward svc/prometheus-server 9090:9090 -n monitoring -
Accédez au dashboard
Ouvrez
http://localhost:9090dans votre navigateur. -
Coupez le tunnel quand vous avez terminé avec
Ctrl+C.
kubectl proxy : accéder à l’API Kubernetes
Section intitulée « kubectl proxy : accéder à l’API Kubernetes »kubectl proxy démarre un serveur proxy HTTP local qui authentifie automatiquement vos requêtes vers l’API server Kubernetes. Vous pouvez ensuite explorer l’API REST avec curl, un navigateur, ou n’importe quel outil HTTP.
Quand l’utiliser
Section intitulée « Quand l’utiliser »- Explorer l’API Kubernetes (lister les ressources, vérifier les autorisations)
- Accéder aux dashboards exposés via l’API server (Kubernetes Dashboard)
- Développer un outil qui interagit avec l’API Kubernetes
kubectl proxy [--port=<port>] [--address=<adresse>]Démarrer le proxy
Section intitulée « Démarrer le proxy »kubectl proxy --port=8001Starting to serve on 127.0.0.1:8001Le proxy reste actif tant que la commande tourne. Arrêtez-le avec Ctrl+C.
Explorer l’API
Section intitulée « Explorer l’API »Une fois le proxy démarré, l’API Kubernetes est accessible sans token ni certificat :
# Lister les API disponiblescurl -s http://localhost:8001/api | python3 -m json.tool
# Lister les nœudscurl -s http://localhost:8001/api/v1/nodes | python3 -m json.tool
# Lister les pods d'un namespacecurl -s http://localhost:8001/api/v1/namespaces/prod/pods | python3 -m json.tool
# Obtenir un pod spécifiquecurl -s http://localhost:8001/api/v1/namespaces/prod/pods/api-server-7d4b8c | python3 -m json.toolAccéder à un Service via le proxy
Section intitulée « Accéder à un Service via le proxy »Le proxy expose aussi les Services de votre cluster via un chemin formaté :
http://localhost:8001/api/v1/namespaces/<namespace>/services/<service>[:<port>]/proxy/# Accéder au dashboard Kubernetescurl http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
# Accéder à Grafanacurl http://localhost:8001/api/v1/namespaces/monitoring/services/grafana:3000/proxy/proxy vs port-forward : quelle différence ?
Section intitulée « proxy vs port-forward : quelle différence ? »| Critère | kubectl proxy | kubectl port-forward |
|---|---|---|
| Ce qui est exposé | L’API Kubernetes complète | Un pod ou service spécifique |
| Protocole | HTTP uniquement | TCP (n’importe quel protocole) |
| Auth | Automatique (le proxy s’authentifie) | Automatique (kubectl s’authentifie) |
| Usage | Explorer l’API, accéder aux dashboards via l’API | Debug/dev, accéder à une app spécifique |
| URL d’accès | http://localhost:8001/api/v1/... | http://localhost:<port-local> |
| TCP brut (BD, gRPC…) | ❌ Non (HTTP only) | ✅ Oui |
Bonnes pratiques
Section intitulée « Bonnes pratiques »Choix du type de Service
Section intitulée « Choix du type de Service »| Environnement | Type recommandé | Pourquoi |
|---|---|---|
| Communication entre microservices | ClusterIP | Pas besoin d’accès externe, routage interne |
| Cluster de dev/test, accès depuis le réseau local | NodePort | Simple, pas de dépendance cloud |
| Production, accès public | LoadBalancer | IP stable, health checks, intégration cloud |
| Production avec routing avancé (TLS, path-based) | ClusterIP + Ingress | Plus flexible qu’un LB par Service |
Port-forward : discipline de dev
Section intitulée « Port-forward : discipline de dev »- Utilisez
svc/plutôt quepod/— le Service survit aux redémarrages de pods - Ne laissez pas tourner un port-forward oublié — il consomme une connexion API server
- Pour un accès régulier, créez un Service ou un Ingress plutôt que de relancer un port-forward chaque jour
- Documentez les commandes port-forward fréquentes dans le
READMEdu projet
Sécurité
Section intitulée « Sécurité »- Jamais
--address 0.0.0.0sur un réseau public (ni pour proxy, ni pour port-forward) kubectl proxy= accès complet au cluster avec vos droits. Traitez-le comme un accès admin- En production, préférez un Ingress Controller avec TLS plutôt qu’un NodePort ou proxy
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
error: no resources found (expose) | La ressource n’existe pas ou mauvais namespace | Vérifiez avec kubectl get <type> -n <ns> |
service already exists (expose) | Un Service du même nom existe déjà | Supprimez-le avec kubectl delete svc <nom> ou choisissez un autre nom (--name) |
| Service créé mais pas d’endpoints | Le selector du Service ne matche aucun pod | Comparez kubectl get svc <nom> -o jsonpath='{.spec.selector}' avec les labels des pods |
unable to listen on port (port-forward) | Le port local est déjà utilisé | Changez le port local : 9090:8080 ou utilisez :8080 pour un port aléatoire |
error forwarding port (port-forward) | Le pod n’est pas en état Running | Vérifiez kubectl get pod <nom> -n <ns> — attendez qu’il soit prêt |
| Port-forward se coupe tout seul | Le pod a redémarré ou a été supprimé | Ciblez le Service (svc/) plutôt que le pod. Relancez la commande |
address already in use (proxy) | Un autre processus utilise le port 8001 | Changez de port : kubectl proxy --port=8002 |
unauthorized (proxy) | Kubeconfig invalide ou expiré | Vérifiez avec kubectl cluster-info. Renouvelez vos credentials si nécessaire |
| Proxy : accès au Service retourne 503 | Le Service n’a pas d’endpoints ou le pod n’est pas prêt | Vérifiez kubectl get endpoints <svc> -n <ns> |
À retenir
Section intitulée « À retenir »kubectl exposecrée un Service permanent — choisissez le bon type : ClusterIP (interne), NodePort (dev/test), LoadBalancer (prod cloud).kubectl port-forwardcrée un tunnel temporaire local → pod/service — parfait pour le dev et le debug, mais pas pour la production.kubectl proxyexpose l’API Kubernetes en HTTP local — puissant pour l’exploration, mais dangereux si exposé sur le réseau.--port= port du Service (côté client),--target-port= port du conteneur (côté application).- Ciblez un Service (
svc/) plutôt qu’un pod pour un port-forward résilient aux redémarrages. - En production, préférez un Ingress Controller avec TLS plutôt que des NodePort ou des proxy.
- Pour un accès régulier, créez un Service ou un Ingress — ne compensez pas avec un port-forward quotidien.