Networking
Your namespace is not open to the world in either direction. Nothing in a manifest tells you where the edges are, so they are worth knowing before you design around them.
Inbound
| From | Reaches your pods? |
|---|---|
| The shared gateway | Yes. This is what makes an HTTPRoute work |
| Other pods in your namespace | Yes, freely, on any port |
| Another customer's namespace | No |
| The public internet, directly | No. Only through the gateway |
There is no way to expose a raw TCP port to the internet. NodePort and LoadBalancer services are rejected, and the way out is an HTTPRoute on the shared gateway, see Gateway API.
Because pods inside your namespace reach each other without restriction, a database, cache or internal API belongs in the namespace with the application that uses it, addressed by its Service name:
postgresql://app-db-rw:5432/mydb
redis://cache:6379
http://myapp:80Outbound on paid plans
Effectively open, with two exceptions.
Port 25 is blocked, on every plan including paid ones. Connecting directly to a recipient's mail server does not work. Send through a mail provider's submission port or their HTTP API instead; submission ports such as 587 are not affected on a paid plan. If you do not have a provider yet, ITSH Email accepts submission on 587. This is the most common surprise on this page.
The cloud metadata address is unreachable. SDKs that try to auto-discover cloud credentials will stall against it before falling back to whatever you configured, which shows up as a few seconds of startup delay. Configure credentials explicitly rather than letting the library probe.
Everything else works: HTTP and HTTPS, external databases on their own ports, message brokers, SSH to your own hosts, DNS.
Outbound on the free tier
Much narrower. A free namespace may only reach:
- HTTP (80) and HTTPS (443), anywhere
- DNS
- the Kubernetes API
- other pods in its own namespace
Everything else is dropped without an error, so the symptom is a hang and then a timeout. In particular, an external database, cache or message broker on its own port is unreachable and there is no way around it. Run the dependency inside your namespace, or move to a paid plan. See Free tier.
Reaching the Kubernetes API from a pod
This works, but only if the pod runs as your namespace's own service account.
The default service account has no permissions
A pod that does not set serviceAccountName runs as default, which is granted nothing at all: every API call comes back Forbidden. You also cannot fix that by binding a role yourself, because creating roles and role bindings is not permitted.
Name your namespace's service account on the pod instead. It is named after the namespace:
spec:
serviceAccountName: <your-namespace>With that set, the in-cluster configuration client libraries expect is present, and the pod has exactly the access described on Permissions and policies, no more.
What's next
- Gateway API for getting traffic in
- Outbound connections fail if something cannot connect