Categories
Containerisation Containers DevOps Kubernetes

Minikube: Deploy a container using a private image registry

This post is mainly for wanting to test a private image on your local k8s instance.

At this point in time I feel minikube is the lightweight standard for this.

You should have a private registry with the image you want to deploy, otherwise – use a public image.

Getting Started

Install minikube

Once minikube is installed, start it:

minikube start

The setup will tell you:

  Starting control plane node minikube in cluster minikube
?  Downloading Kubernetes v1.18.3 preload ...
    > preloaded-images-k8s-v3-v1.18.3-docker-overlay2-amd64.tar.lz4: 526.01 MiB
?  Creating hyperkit VM (CPUs=2, Memory=2200MB, Disk=20000MB) ...
?  Preparing Kubernetes v1.18.3 on Docker 19.03.8 ...
?  Verifying Kubernetes components...
?  Enabled addons: default-storageclass, storage-provisioner
?  Done! kubectl is now configured to use "minikube"

So you don’t even need to update your kubectl.

View the k8s Cluster Nodes

There should only be a single node called minikube:

$ kubectl get nodes
NAME       STATUS   ROLES    AGE     VERSION
minikube   Ready    master   2m13s   v1.18.3

The next few steps are done in the default namespace

Add the Private Registry Secret

Read on k8s docs how to pull an image from a private registry

kubectl create secret docker-registry regcred \
--docker-server= \
--docker-username= \
--docker-password= \
--docker-email=

Inspect the secret

kubectl get secret regcred --output=yaml

It is base64 encoded, so to view actual:

kubectl get secret regcred --output="jsonpath={.data.\.dockerconfigjson}" | base64 --decode

Create a pod that uses the secret

In a file my-pod.yml:

apiVersion: v1
kind: Pod
metadata:
  name: private-reg
  labels:
    name: private-reg
spec:
  containers:
  - name: private-reg-container
    image: 
  imagePullSecrets:
  - name: regcred

Apply and view the pod:

kubectl apply -f my-pod.yml
kubectl get pod private-reg

If you have an ImagePullBackoff issue then scroll to the bottom of this page

The more k8s way of doing things would be to use a deployment instead of deploying the pod:

kubectl create deployment my-project --image=k8s.gcr.io/echoserver:1.4

Pod is Running how to View the Frontend

Full tutorial on k8s

By default, the Pod is only accessible by its internal IP address within the Kubernetes cluster.
To expose the pod outside of kubernetes you need to create a service.

kubectl expose deployment my-project --type=LoadBalancer --port=8080

or if you just deployed a pod – you need to update the pod spec to include a label:

kubectl expose po private-reg--type=LoadBalancer --port=8080

Ensure the service is running with:

kubectl get svc

On cloud providers that support load balancers, an external IP address would be provisioned to access the Service. On Minikube, the LoadBalancer type makes the Service accessible through the minikube service command.

minikube service 

Finding the reason for an ImagePullBackoff

In my case the pod did not deploy:

$ kubectl get po
NAME          READY   STATUS             RESTARTS   AGE
private-reg   0/1     ImagePullBackOff   0          45s

This question on stackoverflow – highlights how to debug an ImagePullBackoff

kubectl describe pod private-reg

The error I saw was:

Failed to pull image "//:": rpc 
error: code = Unknown desc = Error response from daemon: pull access denied for //,
repository does not exist or may require 'docker login': denied:
requested access to the resource is denied

Usually this happens if your username, password, registry url or image name is incorrect.