Skip to content

Kubernetes Connector

The Kubernetes connector adds pod-level attribution to your egress data. Without it, traffic from an EKS cluster is attributed to the node (EC2 instance) that sent it; with it, each flow is attributed to the individual pod and workload.

The sensor is a small in-cluster Deployment that watches pod metadata and registers pod IP ↔ workload mappings with Multistax Outbound. It does not touch your traffic — forwarding still happens through the Multistax Outbound gateway in your VPC.

  • An EKS cluster with an OIDC provider (for IRSA).
  • The AWS connector already set up, so the /cloudphilos/outbound/api-key secret exists in your account.
  • Helm 3.

By default the AWS VPC CNI source-NATs pod traffic to the node’s IP, which makes pods indistinguishable from their node. Enable external SNAT so pod IPs are preserved on their way to the Multistax Outbound gateway (which performs the NAT instead):

Terminal window
kubectl set env daemonset -n kube-system aws-node AWS_VPC_K8S_CNI_EXTERNALSNAT=true

Or, if you manage the VPC CNI as an EKS addon:

{
"env": {
"AWS_VPC_K8S_CNI_EXTERNALSNAT": "true"
}
}

The sensor needs exactly one AWS permission:

Permission Resource scope Why we need it
secretsmanager:GetSecretValue /cloudphilos/outbound/api-key* Fetch the API key used to authenticate registrations to Multistax Outbound’s ingest endpoint.

Inside the cluster, the sensor only reads pod metadata (names, labels, IPs) to build the pod ↔ workload mapping. It never modifies cluster resources; the exact RBAC rules ship with the Helm chart.

Terraform:

data "aws_iam_policy_document" "outbound_sensor_assume" {
statement {
actions = ["sts:AssumeRoleWithWebIdentity"]
principals {
type = "Federated"
identifiers = [var.eks_oidc_provider_arn]
}
condition {
test = "StringEquals"
variable = "${var.eks_oidc_provider}:sub"
values = ["system:serviceaccount:outbound-system:outbound-k8s-sensor"]
}
condition {
test = "StringEquals"
variable = "${var.eks_oidc_provider}:aud"
values = ["sts.amazonaws.com"]
}
}
}
resource "aws_iam_role" "outbound_sensor" {
name = "cloudphilos-outbound-k8s-sensor-role"
assume_role_policy = data.aws_iam_policy_document.outbound_sensor_assume.json
}
resource "aws_iam_role_policy" "outbound_sensor" {
name = "cloudphilos-outbound-k8s-sensor-policy"
role = aws_iam_role.outbound_sensor.id
policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = "secretsmanager:GetSecretValue"
Resource = "arn:aws:secretsmanager:${var.region}:${var.account_id}:secret:/cloudphilos/outbound/api-key*"
}]
})
}

The in-app wizard generates the same role as a CloudFormation snippet if you prefer: open Networks → your network → Kubernetes and press Connect on the cluster’s row.

Terminal window
helm repo add cloudphilos https://charts.cloudphilos.net
helm repo update
helm install outbound-k8s-sensor cloudphilos/outbound-k8s-sensor \
--namespace outbound-system \
--create-namespace \
--set env.clusterName=<eks-cluster-name> \
--set env.awsRegion=<region> \
--set env.apiKeySecretName=/cloudphilos/outbound/api-key \
--set serviceAccount.roleArn=arn:aws:iam::<account-id>:role/cloudphilos-outbound-k8s-sensor-role

env.clusterName must match the EKS cluster name exactly — Multistax Outbound joins on it to report the cluster as connected. Leave it out and pods are still reported, but the cluster never shows as connected.

The chart deploys a single-replica Deployment with minimal footprint (requests: 10m CPU / 64Mi memory) under the outbound-k8s-sensor service account.

Terminal window
kubectl get pods -n outbound-system
kubectl logs -n outbound-system deploy/outbound-k8s-sensor

On Networks → your network → Kubernetes, the cluster’s row turns to Connected as soon as the sensor’s first registration arrives. That is the quickest confirmation that the API key, the IAM role and the network all line up, and it does not wait for the cluster to send any egress.

Within a few minutes, egress from cluster workloads should appear in the dashboard attributed to pods and workloads rather than nodes.

Terminal window
helm uninstall outbound-k8s-sensor -n outbound-system

Egress attribution falls back to node level; traffic itself is unaffected. If you also disable AWS_VPC_K8S_CNI_EXTERNALSNAT, do so only if the node-SNAT path is what you want going forward.