Can a Kubernetes Pod use a Secret or PersistentVolumeClaim from another namespace, and how does it reach a Service in another namespace?
answer
- references carry only a name
- looked up where the pod lives
- the network is flat
- namespace appears in the Service name
- policy, not namespace, blocks traffic
basics
~20 sNo. A Kubernetes Pod can only reference Secrets, ConfigMaps, PVCs and ServiceAccounts in its own namespace, because those fields hold a bare name. Services are different: any pod can reach one in another namespace by <svc>.<ns>.svc.cluster.local unless NetworkPolicy blocks it.
solid answer
~40 sObject references from a pod are **local**: `secretName`, `configMap.name`, `persistentVolumeClaim.claimName`, `serviceAccountName` and `imagePullSecrets` hold only a name, and the name is looked up in the pod's own namespace. There is no namespace field to fill in, so a pod in `portal` cannot mount `db-creds` from `records-shared`; you copy or generate the Secret in `portal`. Ingress backends and a Service's label selector are local in the same way. **Network reachability is not local.** A Service in namespace `data` is reachable from any namespace as `records-db.data` or the fully qualified `records-db.data.svc.cluster.local` on a cluster using the default domain, and the short name `records-db` only works from inside `data`. Namespaces do not block traffic; an enforced NetworkPolicy does.
code
yaml · 25 linesapiVersion: v1
kind: Pod
metadata:
name: portal
namespace: portal
spec:
serviceAccountName: portal
containers:
- name: app
image: registry.example.com/records-portal:4.12.3
env:
- name: DB_HOST
value: records-db.data.svc.cluster.local
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-creds
key: password
volumeMounts:
- name: uploads
mountPath: /var/lib/portal/uploads
volumes:
- name: uploads
persistentVolumeClaim:
claimName: portal-uploadsgo deeper
Remember that a pod can only use Secrets, ConfigMaps and claims from its own namespace, and that other namespaces' Services are reached by a longer name.
Explain why the reference types carry only a name, the three name forms of a Service, and why the pod network ignores namespaces unless NetworkPolicy is enforced.
Diagnose wrong-namespace lookups quickly, and replace ad hoc Secret copies with generated per-namespace copies that follow rotation.
Decide where shared dependencies live and how credentials reach each namespace, and pair every namespace split with the network rules that make it mean something.
## Two different kinds of "crossing a namespace" People ask "can I use something from another namespace?" about two unrelated things: 1. **API object references**: a field in one object that names another object, such as a pod naming the Secret to mount. 2. **Network traffic**: a process in one pod opening a connection to a Service or pod elsewhere. Kubernetes treats them oppositely. Object references are confined to the namespace; network traffic is not. ## Object references are namespace-local Most references in a Pod spec use a type that carries only a `name`. The API documentation for these fields says it outright, for example "the name of the secret in the pod's namespace" and "a PersistentVolumeClaim in the same namespace as the pod". Because there is no `namespace` field, there is nothing to point elsewhere. | Reference in a Pod | Field | Looked up in | |---|---|---| | Secret volume | `volumes[].secret.secretName` | the pod's namespace | | Secret or ConfigMap env | `env[].valueFrom.secretKeyRef.name`, `configMapKeyRef.name` | the pod's namespace | | Claim | `volumes[].persistentVolumeClaim.claimName` | the pod's namespace | | Identity | `serviceAccountName` | the pod's namespace | | Registry credentials | `imagePullSecrets[].name` | the pod's namespace | The same rule shows up elsewhere: - A **Service's label selector** only matches pods in the Service's own namespace. - An **Ingress** backend names a Service that must be in the Ingress's namespace. - **Owner references** from a namespaced object must point to an owner in the same namespace (or to a cluster-scoped owner). What happens when the name does not exist locally: - A pod whose env var reads a missing Secret sits in `CreateContainerConfigError`. - A pod mounting a missing Secret stays in `ContainerCreating` with `FailedMount` events. - A pod naming a missing claim stays `Pending`. The confusing case is when `kubectl get secret db-creds` succeeds because your context points at a different namespace from the pod's. Always check with `-n <pod-namespace>`. ### The exception: cluster-scoped objects point in A cluster-scoped object may carry a full reference. A `PersistentVolume`'s `spec.claimRef` names both namespace and name, which is how a cluster-wide volume binds to one namespaced claim. Some add-on APIs also allow deliberate cross-namespace references with an explicit grant object in the target namespace; Gateway API's `ReferenceGrant` is one. Core pod references have no such mechanism. ### What to do instead - **Copy or generate per namespace.** Create the Secret in each namespace that needs it, ideally from its source of truth by a tool or controller, not by a one-off `kubectl get -o yaml | kubectl apply` copy, which goes stale on rotation. - **Move the consumer.** If the portal truly shares a database credential with the records service, the two may belong in one namespace. - **Call over the network.** If a pod needs data owned by another namespace, it can call a Service there instead of mounting that namespace's objects. ## Network traffic crosses namespaces by default Services get DNS names that include their namespace. For Service `records-db` in namespace `data`, on a cluster using the default `cluster.local` domain: - `records-db` reaches this Service only from pods inside `data`; - `records-db.data` resolves from any namespace; - `records-db.data.svc.cluster.local` is the fully qualified form and resolves from anywhere in the cluster. How those lookups are expanded is the cluster DNS's business. What matters here is that the namespace sits **in the name**, so the same short name can point at different Services from different namespaces, and a fully qualified name always points at one. Nothing about a namespace blocks the connection itself. The pod network is flat: any pod can reach any pod IP and any Service in any namespace. A **NetworkPolicy**, enforced by a network plugin that supports it, is what restricts traffic between namespaces. Without one, `records-review` can connect to the database in `records-dev` as easily as `records-dev` can. ## Why interviewers ask this The pair separates people who have run clusters from people who have read about them: - The object-reference half catches the "just mount the Secret from the shared namespace" answer, which the API cannot express. - The network half catches the "namespaces isolate apps" answer, which is false without NetworkPolicy. A strong answer names both halves and names the control that closes each gap: per-namespace copies of the objects a pod needs, and NetworkPolicy for traffic.
- How can a Kubernetes Service in one namespace act as a local alias for a Service in another namespace?Create a Service of `type: ExternalName` in the consuming namespace with `externalName: records-db.data.svc.cluster.local`. Pods then use the short local name, and cluster DNS answers with a CNAME to the other namespace's Service. It is only a DNS alias: no proxying, no ports remapped, and NetworkPolicy still governs the traffic.
- A pod in namespace portal is stuck with CreateContainerConfigError, yet kubectl get secret db-creds returns the Secret. What is the likely cause?The `kubectl get` ran against a different namespace, usually the context's namespace or `default`, while the pod looks up `db-creds` in `portal`. Check with `kubectl get secret db-creds -n portal` and `kubectl describe pod -n portal`. The fix is to create the Secret in `portal`, not to change the reference, because a pod's Secret reference cannot name a namespace.
- Does putting two apps in separate Kubernetes namespaces stop one from connecting to the other's database?No. Pod networking is flat across namespaces, so a pod can reach any Service by its namespaced name. You need a NetworkPolicy, enforced by a network plugin that supports it, that only admits traffic from the owning namespace. Separate namespaces only give those rules something to select on.
saying these in an interview costs you the question
- A pod can mount a Secret from another namespace with namespace/name
- Pods in different namespaces cannot reach each other by default
- A Service selector matches pods in every namespace
- Setting a namespace field on secretKeyRef shares the Secret
- Cross-namespace Service calls need an RBAC RoleBinding first