Python应用容器化后Kubernetes Pod内外IP通信方案问询
Alright, let's walk through how to containerize your Python Hug/Waitress app (plus the two associated applications) and orchestrate them with Kubernetes, while making sure Pods can communicate both internally (within the cluster) and externally (from outside the cluster).
First, we need to package each app into a Docker image. Let's start with your Python app:
Python App Dockerfile
Create a Dockerfile in your app's root directory:
# Use a slim Python base image FROM python:3.9-slim # Set working directory WORKDIR /app # Copy requirements first to leverage Docker cache COPY requirements.txt . # Install dependencies (make sure waitress and hug are in requirements.txt) RUN pip install --no-cache-dir -r requirements.txt # Copy your application code COPY . . # Expose the port your app listens on EXPOSE 8000 # Command to start the app (note we listen on 0.0.0.0 to accept external container connections) CMD ["waitress-serve", "--host=0.0.0.0", "--port=8000", "__hug_wsgi__"]
Important: Update your original code to listen on
0.0.0.0instead of127.0.0.1—this lets the app accept connections from outside the container.
For your two associated applications, create similar Dockerfiles tailored to their tech stack (e.g., Node.js, Go, another Python service). The core steps are: use an appropriate base image, install dependencies, copy code, expose the correct port, and define the start command.
Once the Dockerfiles are ready, build and push the images to a container registry (like Docker Hub, AWS ECR, or a private registry):
# Build the Python app image docker build -t your-registry/python-hug-app:v1 . # Push to the registry docker push your-registry/python-hug-app:v1
Repeat this process for the other two apps.
Now we'll define Kubernetes resources to deploy and manage your apps. Let's start with a namespace to isolate your workloads (optional but recommended for cleaner organization):
2.1 Create a Namespace
Save this as namespace.yaml:
apiVersion: v1 kind: Namespace metadata: name: app-cluster
Apply it with:
kubectl apply -f namespace.yaml
2.2 Deployments for Each App
Deployments ensure your apps run reliably, scale as needed, and self-heal if Pods fail. Here's the deployment for your Python app (python-app-deployment.yaml):
apiVersion: apps/v1 kind: Deployment metadata: name: python-hug-app namespace: app-cluster spec: replicas: 2 # Start with 2 replicas for high availability selector: matchLabels: app: python-hug-app template: metadata: labels: app: python-hug-app spec: containers: - name: python-hug-app image: your-registry/python-hug-app:v1 ports: - containerPort: 8000 resources: requests: cpu: "100m" memory: "128Mi" limits: cpu: "200m" memory: "256Mi"
Create similar deployments for your two associated apps, updating the name, labels, image, and containerPort as needed. Apply each deployment with:
kubectl apply -f python-app-deployment.yaml
2.3 Services for Communication
Services provide stable network endpoints for your Pods. We'll use different service types for internal and external access.
Internal Access (Pod-to-Pod)
For internal communication between your apps, use a ClusterIP service (the default type). This gives your app a stable DNS name that other Pods can use, even if Pod IPs change.
Save this as python-app-service.yaml:
apiVersion: v1 kind: Service metadata: name: python-hug-service namespace: app-cluster spec: type: ClusterIP selector: app: python-hug-app ports: - protocol: TCP port: 8000 targetPort: 8000
Create similar ClusterIP services for the other two apps. Now, any Pod in the cluster can access your Python app using the DNS name: python-hug-service.app-cluster.svc.cluster.local:8000.
External Access
If you need to access your apps from outside the Kubernetes cluster, choose one of these options:
Option 1: NodePort Service
Maps a service port to a fixed port on every cluster node. Update the service spec to:
spec: type: NodePort selector: app: python-hug-app ports: - protocol: TCP port: 8000 targetPort: 8000 nodePort: 30080 # Choose a port between 30000-32767
You can now access the app via [Node-IP]:30080.
Option 2: LoadBalancer Service (Cloud Environments)
If you're using a cloud-managed Kubernetes cluster (EKS, GKE, AKS), this will provision a cloud load balancer with a public external IP:
spec: type: LoadBalancer selector: app: python-hug-app ports: - protocol: TCP port: 8000 targetPort: 8000
Get the external IP with kubectl get services -n app-cluster, then access the app via [External-IP]:8000.
Option 3: Ingress (For Domain-Based Access)
For more flexible routing (e.g., using custom domains), set up an Ingress Controller (like NGINX Ingress) first, then define an Ingress resource:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: app-ingress namespace: app-cluster annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: python-app.your-domain.com http: paths: - path: / pathType: Prefix backend: service: name: python-hug-service port: number: 8000 # Add rules for your other two apps here (e.g., host: app2.your-domain.com)
You'll need to point your domain's DNS records to the Ingress Controller's external IP.
To test internal connectivity, exec into one of your Pods and curl another app's service:
# Get the name of a Pod from one of your apps kubectl get pods -n app-cluster # Exec into the Pod kubectl exec -it <pod-name> -n app-cluster -- /bin/bash # Curl the Python app's service to confirm communication curl python-hug-service.app-cluster.svc.cluster.local:8000
This should return the app's response, confirming internal connectivity.
For external access, test using the NodePort, LoadBalancer IP, or Ingress domain depending on your setup.
- Avoid using Pod IPs directly: Pod IPs are ephemeral—they change when Pods restart or scale. Always use Service DNS names for stable internal communication.
- Add Health Checks: Include liveness and readiness probes in your Deployments to ensure Kubernetes automatically restarts unhealthy Pods and only sends traffic to ready Pods.
- Network Policies: If you need to restrict traffic between Pods, define NetworkPolicy resources to allow only authorized communication between your apps.
内容的提问来源于stack exchange,提问作者Ahmad Hijazi

