1. Routing external HTTP traffic to multiple services

    TypeScript

    Routing external HTTP traffic to multiple services typically involves using a load balancer or a similar mechanism that can distribute incoming network traffic across several servers or services. In Kubernetes, for example, this is achieved using an Ingress resource, which provides HTTP and HTTPS routing to services within the cluster based on path matching.

    Let's create a simple scenario in which you have a Kubernetes cluster and you want to route external HTTP traffic to two different services. We will write a Pulumi program in TypeScript to do exactly this. For the sake of this example, let's assume we have two services running in our cluster: service-one and service-two. We want to route traffic to service-one if the path starts with /one and service-two if it starts with /two.

    Here's what we'll do step-by-step:

    1. Declare a Service for each of the two backend services.
    2. Create an Ingress resource that defines how to route the traffic based on the URL path.
    3. For each path, specify the backend Service and the port which the traffic should be forwarded to.

    First, I'll demonstrate how to declare the two Services that exist within your Kubernetes cluster. Both services are assumed to be exposed on port 80.

    Then, I'll show you how to define an Ingress object that listens for external HTTP traffic and routes it to the appropriate service based on the URL path.

    Here's the Pulumi program:

    import * as k8s from "@pulumi/kubernetes"; // Create a Kubernetes Service for 'service-one'. const serviceOne = new k8s.core.v1.Service("service-one", { metadata: { name: "service-one" }, spec: { selector: { app: "service-one" }, ports: [{ port: 80, targetPort: "http" }], }, }); // Create a Kubernetes Service for 'service-two'. const serviceTwo = new k8s.core.v1.Service("service-two", { metadata: { name: "service-two" }, spec: { selector: { app: "service-two" }, ports: [{ port: 80, targetPort: "http" }], }, }); // Create an Ingress resource that routes traffic to service-one and service-two based on the URL path. const ingress = new k8s.networking.v1.Ingress("ingress", { metadata: { name: "example-ingress", }, spec: { rules: [ { http: { paths: [ { path: "/one", pathType: "Prefix", backend: { service: { name: serviceOne.metadata.name, port: { number: 80 }, }, }, }, { path: "/two", pathType: "Prefix", backend: { service: { name: serviceTwo.metadata.name, port: { number: 80 }, }, }, }, ], }, }, ], }, }); // Export the ingress' IP to access it from the Internet export const ingressIp = ingress.status.loadBalancer.ingress[0].ip;

    In this program:

    • We use @pulumi/kubernetes package, which allows us to declare Kubernetes resources in a Pulumi program.
    • We declared two Kubernetes services (serviceOne and serviceTwo) to represent our existing services.
    • We created an Ingress resource that listens for HTTP traffic on paths /one and /two. Traffic on /one is routed to service-one and /two to service-two.
    • We export the ingress IP so that we can know what IP address is assigned to the Ingress and access our services via the Internet.

    The Ingress controller must be running in your environment for the Ingress resource to work. Many Kubernetes clusters come with an Ingress controller pre-installed, or you can install one like nginx or traefik. The controller will make use of the rules specified in the Ingress resource to route traffic accordingly.

    For official documentation on the Ingress resource, you can visit:

    Make sure to apply this configuration using Pulumi by running pulumi up in the terminal, after setting up your Pulumi project and installing the required dependencies. This program assumes that you have access to a Kubernetes cluster and the @pulumi/kubernetes package is already configured.