1. Answers
  2. Configuring Kubernetes with MetalLB and Envoy Proxy

How do I configure Kubernetes with MetalLB and Envoy Proxy?

In this guide, we will configure a Kubernetes cluster with MetalLB and Envoy Proxy using Pulumi. MetalLB provides a network load balancer implementation for Kubernetes, and Envoy Proxy is a powerful edge and service proxy designed for cloud-native applications.

Key Points:

  • Install and configure MetalLB in a Kubernetes cluster.
  • Deploy Envoy Proxy as a gateway.
  • Configure a LoadBalancer service to use MetalLB and route traffic through Envoy.
import * as pulumi from "@pulumi/pulumi";
import * as k8s from "@pulumi/kubernetes";

// Define the MetalLB namespace
const metallbNamespace = new k8s.core.v1.Namespace("metallb", {
    metadata: { name: "metallb-system" },
});

// Deploy MetalLB using the official manifest
const metallbManifest = new k8s.yaml.ConfigFile("metallbManifest", {
    file: "https://raw.githubusercontent.com/metallb/metallb/v0.9.6/manifests/metallb.yaml",
    transformations: [
        (obj: any) => {
            if (obj.kind === "Namespace" && obj.metadata.name === "metallb-system") {
                obj.metadata = metallbNamespace.metadata;
            }
        },
    ],
});

// Define a config map for MetalLB IP address pool
const ipAddressPool = new k8s.core.v1.ConfigMap("ipAddressPool", {
    metadata: {
        namespace: metallbNamespace.metadata.name,
        name: "config",
    },
    data: {
        "config": `
        address-pools:
        - name: default
          protocol: layer2
          addresses:
          - 192.168.1.240-192.168.1.250
        `,
    },
}, { dependsOn: metallbManifest });

// Define the Envoy Proxy deployment
const envoyDeployment = new k8s.apps.v1.Deployment("envoy", {
    metadata: { namespace: metallbNamespace.metadata.name },
    spec: {
        selector: { matchLabels: { app: "envoy" } },
        replicas: 1,
        template: {
            metadata: { labels: { app: "envoy" } },
            spec: {
                containers: [{
                    name: "envoy",
                    image: "envoyproxy/envoy:v1.18.3",
                    ports: [{ containerPort: 8080 }],
                    volumeMounts: [{
                        name: "envoy-config",
                        mountPath: "/etc/envoy",
                    }],
                }],
                volumes: [{
                    name: "envoy-config",
                    configMap: { name: "envoy-config" },
                }],
            },
        },
    },
});

// Define the Envoy Proxy service
const envoyService = new k8s.core.v1.Service("envoy", {
    metadata: { namespace: metallbNamespace.metadata.name },
    spec: {
        type: "LoadBalancer",
        selector: { app: "envoy" },
        ports: [{ port: 80, targetPort: 8080 }],
    },
}, { dependsOn: ipAddressPool });

// Define the Envoy Proxy config map
const envoyConfig = new k8s.core.v1.ConfigMap("envoy-config", {
    metadata: { namespace: metallbNamespace.metadata.name },
    data: {
        "envoy.yaml": `
        static_resources:
          listeners:
          - name: listener_0
            address:
              socket_address:
                address: 0.0.0.0
                port_value: 8080
            filter_chains:
            - filters:
              - name: envoy.filters.network.http_connection_manager
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                  stat_prefix: ingress_http
                  route_config:
                    name: local_route
                    virtual_hosts:
                    - name: local_service
                      domains: ["*"]
                      routes:
                      - match: { prefix: "/" }
                        route: { cluster: service_backend }
                  http_filters:
                  - name: envoy.filters.http.router
          clusters:
          - name: service_backend
            connect_timeout: 0.25s
            type: LOGICAL_DNS
            lb_policy: ROUND_ROBIN
            load_assignment:
              cluster_name: service_backend
              endpoints:
              - lb_endpoints:
                - endpoint:
                    address:
                      socket_address:
                        address: 127.0.0.1
                        port_value: 80
        `,
    },
}, { dependsOn: envoyDeployment });

Summary

In this guide, we configured a Kubernetes cluster with MetalLB and Envoy Proxy using Pulumi. We created the necessary namespaces, deployed MetalLB and Envoy Proxy, and set up a LoadBalancer service with MetalLB to route traffic through Envoy Proxy. This setup provides a powerful and flexible solution for managing network traffic in Kubernetes.

Deploy this code

Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.

Sign up

New to Pulumi?

Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.

Sign up