Network model
Default-deny is the floor
Section titled “Default-deny is the floor”Every namespace inside a Kestrel tenant starts under a default-deny NetworkPolicy distributed by Capsule’s GlobalTenantResource. New namespaces inherit it the moment they are created — there is no window in which a fresh namespace is wide open.
Default-deny means exactly what it says: a Pod you create cannot receive traffic and cannot send traffic until an explicit allow rule permits it. This is the opposite of a default Kubernetes cluster, where Pods can reach each other freely until a NetworkPolicy narrows the traffic down.
On top of default-deny, the tenant chart distributes four pre-approved allow rules that are always in effect in every namespace your tenant owns. They cover the traffic everyone needs, so the floor is “nothing works” but the practical starting state is “the four things every workload needs work, and everything else is blocked until you write your own rule”.
The four allow rules
Section titled “The four allow rules”- DNS — Pods can egress to the cluster DNS service (
kube-system/kube-dns) on UDP and TCP port 53. This is what makes in-cluster service discovery work, so a name likemy-service.my-namespaceresolves inside your pods without any extra rule. - Intra-tenant — Pods can talk to other Pods in the same tenant: any namespace carrying the
capsule.clastix.io/tenant: <your-tenant>label is reachable from any other namespace in the same tenant. Cross-tenant pod-to-pod traffic is blocked. - Traefik ingress — The Traefik ingress controller pods (running in the
traefiknamespace) can reach your pods on whatever port yourIngressresource points at. This is what makes external HTTP and HTTPS routing work — Traefik sits at the edge, terminates TLS, and forwards to the backend Service you named. - Monitoring scrape — The cluster Prometheus (running in the
monitoringnamespace) can reach your pods on their metrics ports. This is what makes Grafana tenant dashboards work; you do not have to write an allow rule for the scrape path.
Adding tenant-scoped allow rules
Section titled “Adding tenant-scoped allow rules”For traffic that does not match one of the four rules — for example, a Pod in your tenant that wants to talk to a Pod in a different tenant, a Pod that should accept traffic from a specific external CIDR, or a Pod that needs to reach an external endpoint such as an S3 bucket or a public API — you create your own NetworkPolicy in the target namespace. There is no general egress allow on Kestrel: outbound traffic to anything other than cluster DNS is blocked until you write an explicit egress rule. The rule is additive: it does not remove the default-deny posture, it just opens a lane on top of it.
The exact shape of a tenant-scoped NetworkPolicy (pod selectors, ingress/egress blocks, the namespaceSelector tricks for cross-namespace-same-tenant traffic) is covered in NetworkPolicy in practice. The one-line rule is: write a NetworkPolicy in the destination namespace, select the destination Pod, and allow the source you need. The Ingress on Kestrel page covers the external HTTP/HTTPS path through Traefik in more detail.
What is blocked and why
Section titled “What is blocked and why”Cross-tenant pod-to-pod traffic is blocked by default because a tenant is the boundary of trust on Kestrel — RCS treats two tenants as two different teams with no implicit sharing. If two tenants need to cooperate on a workflow, open a ticket and RCS will add an explicit allow.
A handful of service and ingress shapes are blocked at a different layer — the Capsule admission webhook — not at the NetworkPolicy layer. The distinction matters because the error you see in kubectl output tells you which layer rejected you:
LoadBalancerandNodePortservices are rejected at admission time, not at packet-routing time. See Known limitations.- Wildcard Ingress hostnames are rejected at admission time. See Known limitations.
If a packet gets through to your Pod and is then dropped, the problem is NetworkPolicy. If the manifest itself is rejected before the Pod even exists, the problem is Capsule admission. The two failure modes look similar in the dashboard but the fix paths are different, so the layer that rejected you is worth noting.