KIND: Kubernetes In Docker — Pulling Image From Private Insecure Registry

Nash
3 min readSep 18, 2023

--

After successfully publishing my previous article, which aimed to provide support for beginners entering the Kubernetes realm, I am now sharing a solution to one of the most trivial issues: downloading a Docker image from a private registry to a Kubernetes pod. Typically, there are no concerns when it comes to uploading and downloading images to and from a secure private registry like Nexus when HTTPS is employed. However, the primary challenge arises when the repository is configured for access via HTTP.

Using Docker

To upload or download images from the private registry, we need to login to the repository before we can do docker push or docker pull.

docker login http://<your.private.registry>:<port>

The above command is utilized to log in to the private Docker registry in an insecure manner. To ensure its functionality, it’s essential to specify the private Docker registry’s host and port in the /etc/docker/daemon.json configuration.

{ 
“insecure-registries”:["your-private-registry:port"]
}

The daemon.json file must be created before applying these changes. Additionally, your-private-registry can either be the hostname or the host IP address, so it’s important to ensure that you have entered the correct one. The port number can be obtained from the settings configured during the creation of the Docker repository on Nexus.

Using Kubernetes

While it might seem that, with the insecure registry entry already configured, Kubernetes manifest file should be able to download the repository image by simply specifying the image path and tag.

image: <your-private-registry>:<port>/<repository-name>/<image-name>:<tag>

However, since Kubernetes operates based on containerd configurations, applying the manifest file with the aforementioned changes will result in an ErrImagePull error. For a more detailed explanation, you can execute the following command:

kubectl describe pod <pod-name>

Unknown desc = failed to pull and unpack image “10.52.212.167:9000/test-docker-repo/test-image:dev-test”: failed to resolve reference “10.52.212.167:9000/test-docker-repo/test-image:dev-test”: failed to do request: Head “https://10.52.212.167:9000/v2/test-docker-repo/test-image/manifests/dev-test": http: server gave HTTP response to HTTPS client

Take note of the final line in the error description above: http: server gave HTTP response to HTTPS client. This statement suggests that the error is related to insecure access. There are several ways to address this issue. One approach is to modify the configuration in /etc/containerd/config.toml, while another option is to include the necessary configuration during the creation of the Kubernetes cluster.

kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: InitConfiguration
nodeRegistration:
kubeletExtraArgs:
node-labels: "ingress-ready=true"
extraPortMappings:
- containerPort: 80
hostPort: 80
protocol: TCP
- containerPort: 443
hostPort: 443
protocol: TCP
containerdConfigPatches:
- |-
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."10.52.212.167:9000"]
endpoint = ["http://10.52.212.167:9000"]
[plugins."io.containerd.grpc.v1.cri".registry.configs."10.52.212.167:9000".tls]
insecure_skip_verify = true

As illustrated above, the containerdConfigPatches now incorporates the insecure registry endpoint, and TLS verification is skipped. With these adjustments, the Kubernetes manifest file will seamlessly download the image from the private registry without encountering any errors.

Hope the content of this article has successfully fulfilled its intended objectives and effectively addressed the goals it was meant to achieve.

--

--

Nash

Software developer with a passion for Kubernetes, ML, and Networking. Committed to merging skills for innovative solutions.