Routing external traffic into the cluster to a specific pod
TypeScriptRouting external traffic to a specific pod in a Kubernetes cluster typically involves creating an Ingress resource. An Ingress is a collection of rules that allows inbound connections to reach the cluster services. It can be configured to give services externally-reachable URLs, load balance traffic, terminate SSL/TLS, and offer name-based virtual hosting.
Here's a step-by-step breakdown of the process:
-
Defining a Service: Before you can route external traffic to a pod, you need to define a Kubernetes Service, which is an abstraction that defines a logical set of pods and a policy by which to access them (sometimes this pattern is called a micro-service).
-
Creating an Ingress Resource: Ingress resources require an Ingress controller to be running within the cluster. Common Ingress controllers are nginx, traefik, or HAProxy. The Ingress resource defines the rules that route external HTTP(S) traffic to services within the cluster.
-
DNS and Ingress: Externally, DNS will need to be configured to point to the external IP address of the Ingress controller.
Below is an example of how you would define an Ingress resource using Pulumi and TypeScript to route external traffic to a specific service that exposes a pod. Before using this, make sure that your cluster has an Ingress controller deployed.
import * as k8s from "@pulumi/kubernetes"; const namespaceName = 'my-namespace'; // Adjust this to match the namespace of your service // Define the service this Ingress routes traffic to. const myService = new k8s.core.v1.Service("my-service", { metadata: { namespace: namespaceName, name: "my-service" // the name should match your actual service's name }, spec: { type: "ClusterIP", // A ClusterIP service is a default kubernetes service offering ports: [{ port: 80, // Adjust this port to match the port your app listens on targetPort: 8080, // Adjust the targetPort to the container port your app is running on protocol: "TCP", }], selector: { app: "my-app" // This should match the label of your app's pod } }, }); // Define an Ingress resource that routes external traffic to the above service. const myIngress = new k8s.networking.v1.Ingress("my-ingress", { metadata: { namespace: namespaceName, // Add any annotations typically required by the ingress controller here annotations: { "nginx.ingress.kubernetes.io/rewrite-target": "/", // Specific for nginx ingress controller }, }, spec: { rules: [{ host: "myapp.example.com", // Replace with your desired domain http: { paths: [{ path: "/", pathType: "Prefix", backend: { service: { name: myService.metadata.name, port: { number: 80, // Should match the port specified in the Service definition }, }, }, }], }, }], }, }); // Export the Ingress's address to access it from the internet. export const ingressAddress = myIngress.status.loadBalancer.ingress[0].hostname;
This program creates a Kubernetes Service (
myService
) that targets a set of pods labeled withapp: my-app
. The Ingress (myIngress
) defined in this program sets up a rule to route all traffic frommyapp.example.com
to themyService
service on port 80. The annotation"nginx.ingress.kubernetes.io/rewrite-target": "/"
is specific for nginx ingress controller, so ensure to change it according to the ingress controller you use.Please make sure that
myapp.example.com
resolves to your Ingress controller. You might need to configure this in your DNS provider. The program exports aningressAddress
, that will give you the external address to which you'll point your DNS record.Keep in mind, if you are running in a cloud provider like AWS, GCP, or Azure, the process might involve additional steps such as configuring a LoadBalancer
-