Yes. In a multi-node Kubernetes cluster, every node that may run your application Pods must be able to reach the container registry URL.
The important detail is that container images are pulled by the container runtime on each Kubernetes node, not by the Pod itself.
For example, suppose you have three nodes:
node-1runs AI Core.node-2runs API Server.node-3runs PostgreSQL.
If AI Core and API Server use images stored in registry.example.com:5000, both node-1 and node-2 must be able to resolve and connect to that address. node-3 also needs access if it pulls an image from the same registry.
1. Multi-node registry architecture
You normally need one shared registry, not one registry per Kubernetes node.
2. What must be configured on every node?
Requirement | Explanation |
|---|---|
DNS resolution | Each node resolves the registry hostname to a reachable IP |
Network connectivity | Each node can connect to the registry's port, normally HTTPS 443 |
TLS trust | Each node's container runtime trusts the registry certificate |
Authentication | Kubernetes supplies image-pull credentials where required |
Image reference | Deployments use the same registry hostname and image path |
The registry can run on a dedicated VM, a separate Docker host, or inside Kubernetes. For production, an independently hosted registry is often simpler to bootstrap and recover.
3. Configure a shared registry for multiple nodes
Consider this example network:
Component | IP address |
|---|---|
Registry server |
|
Kubernetes Node 1 |
|
Kubernetes Node 2 |
|
Kubernetes Node 3 |
|
These are illustrative addresses.
Step A — Run the registry on a reachable server
On the registry server, a minimal development example is:
docker run -d \
--name registry \
-p 5000:5000 \
-v registry-data:/var/lib/registry \
registry:2Unlike binding to 127.0.0.1, this publishes the registry port on the host's network interfaces. Restrict access with firewall rules.
For production, configure HTTPS with a trusted certificate and registry authentication.
Step B — Verify connectivity from every node
On each Kubernetes node, test:
curl -v http://192.168.1.100:5000/v2/For an unauthenticated HTTP registry, a successful response is typically {} with HTTP 200.
For an authenticated HTTPS registry, an HTTP 401 response can be expected before authentication.
This establishes network reachability, but doesn't yet guarantee that the container runtime trusts the registry.
Step C — Configure the container runtime
Your Kubernetes nodes use containerd, so it is containerd, not Docker Desktop on your MacBook, that needs to trust the registry.
For a production HTTPS registry using a certificate trusted by the node, normally no insecure-registry configuration is needed.
For an HTTP-only lab registry, containerd needs explicit configuration on each node. For example, with a containerd installation configured to use /etc/containerd/certs.d:
/etc/containerd/certs.d/
192.168.1.100:5000/
hosts.tomlExample hosts.toml:
server = "http://192.168.1.100:5000"
[host."http://192.168.1.100:5000"]
capabilities = ["pull", "resolve"]The containerd CRI registry configuration must point to that certificates directory, and containerd may need restarting. The exact procedure depends on your containerd version and Kubernetes distribution.
This HTTP configuration is for a trusted development network only.
Step D — Configure Kubernetes authentication
If the registry requires a username and password, create a Kubernetes image pull Secret:
kubectl create secret docker-registry registry-credentials \
--docker-server=registry.example.com \
--docker-username=myuser \
--docker-password='YOUR_PASSWORD' \
--namespace=myappUse the exact registry hostname and port, if applicable, that your image references use.
Then in your Deployment:
spec:
template:
spec:
imagePullSecrets:
- name: registry-credentials
containers:
- name: ai-core
image: registry.example.com/myapp/ai-core:1.0.0
imagePullPolicy: IfNotPresentThe Secret is stored in the Kubernetes namespace and is available to the kubelet on whichever node schedules the Pod. You do not need to create a separate Secret on each node.
4. Configure the registry in Helm
For your application, centralize the registry settings in values.yaml:
global:
imageRegistry: "registry.example.com"
imagePullSecrets:
- name: registry-credentials
aiCore:
image:
repository: "myapp/ai-core"
tag: "1.0.0"
pullPolicy: IfNotPresent
apiServer:
image:
repository: "myapp/api-server"
tag: "1.0.0"
pullPolicy: IfNotPresentYour Helm Deployment template can construct the full image name:
spec:
template:
spec:
imagePullSecrets:
{{- toYaml .Values.global.imagePullSecrets | nindent 8 }}
containers:
- name: ai-core
image: "{{ .Values.global.imageRegistry }}/{{ .Values.aiCore.image.repository }}:{{ .Values.aiCore.image.tag }}"
imagePullPolicy: {{ .Values.aiCore.image.pullPolicy }}Every node uses the same image reference. Kubernetes automatically attempts the pull on the node where the Pod is scheduled.
5. Special consideration for your MacBook and Minikube
Because you're running Minikube with Docker Desktop on macOS, Minikube nodes are containers inside Docker Desktop's Linux environment.
This creates an important networking distinction:
localhost:5000on your MacBook means your MacBook.localhost:5000inside a Minikube node means that Minikube node.host.docker.internalmay provide access to the Docker Desktop host from containers, but its availability and resolution must be verified inside each Minikube node.
For a local experiment, you can use a registry hosted on your MacBook and configure Minikube nodes to reach it through an address available inside Docker Desktop's network. Minikube also documents registry-specific configurations for macOS.
To test each Minikube node:
minikube node list -p myappThen:
minikube ssh -p myapp -n myapp -- \
curl -v http://host.docker.internal:5000/v2/Repeat with the other node names reported by minikube node list.
If the hostname doesn't resolve or the connection fails, the registry network must be configured before using it for image pulls.
6. What happens if one node cannot access the registry?
Suppose the registry is reachable from Node 1 and Node 2, but not Node 3.
If Kubernetes schedules AI Core on Node 3:
Kubelet requests the image from containerd.
Containerd attempts to contact the registry.
The connection fails.
The Pod may enter
ErrImagePulland subsequentlyImagePullBackOff.
Diagnose with:
kubectl describe pod <pod-name> -n myappIf the required image is already cached on Node 3 and the pull policy is IfNotPresent, Kubernetes may start the Pod without contacting the registry. This is not a reliable substitute for registry connectivity across nodes.
Recommendation for your environments
For your MacBook multi-node Minikube experiment, use one registry reachable from all Minikube nodes, with the same registry hostname in your Helm values.
For your customer's future multi-node Kubernetes deployment, use a centrally accessible private registry with HTTPS, authentication, and persistent storage. Avoid registry URLs that refer to an individual node's localhost.
The key principle is:
One shared registry → multiple Kubernetes nodes → each node independently pulls the images it needs.
You configure connectivity and TLS trust at the node/container-runtime level, authentication through Kubernetes image pull Secrets, and image names through Helm.
No comments:
Post a Comment