1. Using kubernetes rabbitmq.com with k8s.nginx.org

    TypeScript

    To deploy an instance of RabbitMQ on a Kubernetes cluster and expose it using the NGINX Ingress Controller, you will utilize a combination of Kubernetes resources. This process involves creating a RabbitMQ deployment, a corresponding service, and then an ingress resource managed by NGINX to expose the RabbitMQ service externally.

    Here's what you need to set up RabbitMQ and expose it via NGINX:

    1. RabbitMQ Deployment: This defines a set of pods running RabbitMQ. It will manage the RabbitMQ stateful workload on your cluster.
    2. Service: A Kubernetes Service is an abstraction which defines a logical set of Pods and a policy by which to access them. The service will target the RabbitMQ pods for internal communication.
    3. NGINX Ingress: The Ingress Controller will create a rule to forward external traffic to the RabbitMQ service. We'll use annotations to customize its behavior.

    Let's begin with the TypeScript program:

    import * as k8s from "@pulumi/kubernetes"; // Create a namespace for the RabbitMQ deployment if you want to isolate it within the cluster const namespace = new k8s.core.v1.Namespace("rabbitmq", { metadata: { name: "rabbitmq", }, }); // Deploy RabbitMQ using a StatefulSet or Deployment const rabbitmqDeployment = new k8s.apps.v1.Deployment("rabbitmq-deployment", { metadata: { namespace: namespace.metadata.name, }, spec: { selector: { matchLabels: { app: "rabbitmq", }, }, replicas: 1, template: { metadata: { labels: { app: "rabbitmq", }, }, spec: { containers: [ { name: "rabbitmq", image: "rabbitmq:3-management", ports: [ { name: "http", containerPort: 15672 }, // Management UI { name: "amqp", containerPort: 5672 }, // AMQP protocol ], }, ], }, }, }, }, { dependsOn: [namespace] }); // Expose RabbitMQ internally within the cluster using a ClusterIP service const rabbitmqService = new k8s.core.v1.Service("rabbitmq-service", { metadata: { namespace: namespace.metadata.name, }, spec: { selector: { app: "rabbitmq", }, ports: [ { name: "http", port: 15672, targetPort: "http" }, { name: "amqp", port: 5672, targetPort: "amqp" }, ], }, }, { dependsOn: [rabbitmqDeployment] }); // Define an NGINX ingress to expose RabbitMQ HTTP management UI externally const rabbitmqIngress = new k8s.networking.v1.Ingress("rabbitmq-ingress", { metadata: { namespace: namespace.metadata.name, annotations: { // Use the NGINX Ingress Controller "kubernetes.io/ingress.class": "nginx", // Additional annotations for custom behavior can be added here }, }, spec: { rules: [{ http: { paths: [{ path: "/rabbitmq", // External path to access RabbitMQ pathType: "Prefix", backend: { service: { name: rabbitmqService.metadata.name, port: { number: 15672, // Management UI port }, }, }, }], }, }], // If you want to enable TLS using cert-manager // tls: [{ // hosts: ["rabbitmq.example.com"], // secretName: "rabbitmq-tls", // }], }, }, { dependsOn: [rabbitmqService] });

    Explanation

    • We initiate the deployment by creating a namespace called rabbitmq to house our resources.
    • We then deploy RabbitMQ as a container within a Kubernetes Deployment. The deployment manages the pods running RabbitMQ.
      • The image used is rabbitmq:3-management which includes the management UI.
      • Two ports are specified: one for the AMQP protocol (5672) and another for the management UI (15672).
    • A Kubernetes Service of type ClusterIP is defined to expose the RabbitMQ Deployment within the cluster. This service makes RabbitMQ accessible to other pods inside the cluster through the specified ports.
    • An NGINX ingress resource is created to expose the RabbitMQ Service to external traffic.
      • The path /rabbitmq is used as an example of the external path that routes to the RabbitMQ management UI.
      • Additional annotations can be added to customize the behavior of the ingress controller.

    Important Notes

    • Before running this Pulumi program, ensure that an NGINX Ingress Controller is already installed in the cluster since the ingress resource relies on this existing controller to handle external traffic.
    • If you want to enable HTTPS connections to the RabbitMQ management UI, you'll need to set up TLS certificates. You can manage certificates with tools like cert-manager. In the ingress definition, tls section is commented out. You would uncomment and populate it with the correct host and the name of the Kubernetes TLS secret containing the certificate information.
    • Ensure that you have a domain name that points to the ingress controller's external IP to use the rabbitmq.example.com hostname, or modify the host to match your DNS setup.
    • For production deployments, consider using a StatefulSet instead of a Deployment for RabbitMQ since it often requires stable storage and unique network identifiers.

    Please adjust the given code to fit into your actual requirements regarding configuration, persistence, and networking.