Minikube环境中Kubernetes Pod内部访问正常但外部通过Service访问报400错误的排查求助
Hey there! Let's walk through debugging this 400 Bad Request error you're seeing when accessing your service from outside the pod. The fact that curl localhost:8000 works inside the pod tells us the app itself is running—so the issue is likely related to how requests are being routed or how your app handles external requests.
Step 1: Verify Service-Pod Endpoint Association
First, make sure your Service is correctly linked to your Pods. Run these commands to check:
# Check if the Service has endpoints pointing to your Pod kubectl get endpoints currency-service # Get detailed info about the Service, including endpoints and port config kubectl describe service currency-service
You should see the IP address of your running Pod listed under Endpoints. If not, double-check that the selector in your Service matches the labels on your Pod (yours look correct, but it's worth confirming).
Step 2: Simulate External Request Headers Inside the Pod
A common cause of 400 errors with Python WSGI apps (like Django/Flask) is Host header validation. When you access the app from outside, the request includes a Host header with the Minikube IP and nodePort (e.g., 192.168.99.100:30001), but your app might not be configured to accept this Host.
Test this by replicating the external request inside the Pod:
kubectl exec -it <pod-name> -- curl -H "Host: 192.168.99.100:30001" localhost:8000
If this returns a 400 error too, you've found the root cause—your app's Host allowlist is missing the Minikube IP/nodePort combination.
Fix for Host Header Issues
- For Django: Update the
ALLOWED_HOSTSsetting in yoursettings.pyto include the Minikube IP (e.g.,ALLOWED_HOSTS = ['192.168.99.100', 'localhost']) or use['*']for testing (never use*in production!). - For Flask: If you're using extensions like Flask-Talisman or custom Host validation, adjust the allowed hosts. For basic Flask apps, ensure you're running the app with
app.run(host='0.0.0.0', port=8000)(which you're probably already doing since the pod works internally) and relax any Host checks for testing.
Step 3: Clarify Service Port Configuration
Your initial Service config looks valid for NodePort, but let's clear up the port field roles to avoid confusion:
port: The port the Service exposes inside the Kubernetes cluster (other pods use this to access the service).targetPort: The port your app is listening on inside the Pod (must matchcontainerPortin your Deployment).nodePort: Optional—if you specify it, it must be in the range30000-32767(Minikube's default nodePort range). If you omit it, Kubernetes will auto-assign a valid port.
A valid NodePort Service config could look like this (either with or without nodePort):
kind: Service apiVersion: v1 metadata: name: currency-service spec: selector: first_deploy_key: first_deploy_value ports: - protocol: TCP port: 8001 # Cluster-internal port targetPort: 8000 # Pod's container port nodePort: 30001 # Optional: manually assigned nodePort (30000-32767) type: NodePort
Step 4: Additional Debugging Steps
If the above doesn't resolve the issue, try these:
- Port-forward directly to the Pod: Bypass the Service entirely to test external access to the app:
Then runkubectl port-forward <pod-name> 8000:8000curl localhost:8000on your local machine. If this works, the problem is definitely with how the Service is handling requests (or the app's Host header for the Service's IP/port). If it still returns 400, focus on debugging the app itself. - Check Pod logs: Look for detailed error messages from your app:
Python apps like Django will often log exactly which Host was rejected, which can confirm the Host header issue.kubectl logs <pod-name> - Test Service access from inside the cluster: Access the Service using its cluster IP to see if the error occurs there too:
If this returns 400, the app is rejecting the cluster IP as a valid Host, so you'll need to add that to your app's allowlist as well.# Get the Service's cluster IP kubectl get service currency-service # Access it from inside the Pod kubectl exec -it <pod-name> -- curl <cluster-ip>:8001
内容的提问来源于stack exchange,提问作者mohammad

