Private Docker Registry
Docker Hub Public Images work pretty great. But when we are talking about enterprise software we want to keep the code secure. We also need to keep our images secure, because anyone with access to the docker image essentially has the business logic of your application.
Docker hub is where almost all public images are stored. Which is where we have been getting our images from so far. But for production code its neither secure nor acceptable to put our production code in a public docker registry.
Almost all major cloud provider and some image registry provider including docker gives us a private docker registry. The usage of private docker registry works pretty much the same way.
We will use ICR or IBM Container Registry that comes built in with your IBM Cloud account.
Building a Image and Pushing to ICR
So far we have been using things under the IBM account. That account already has the docker secrets set up. But lets use our own account to use as an image registry.
We can (re) login from the cloudshell
ibmcloud login --sso
This would ask to get one time code from a url go to that url copy and paste that code. It will list 2 account. Choose the one with your name. (Number 1)
You wont see any text when you paste, so don't paste multiple times.
Login to the container registry
ibmcloud cr login
Lets than create a namespace
ibmcloud cr namespace-add <unique-name>
Lets build the os-signal
image and push it to our private registry.
Also to help with copy-paste export your namespace name as a path variable
export NAMESPACE="<unique-name>"
ibmcloud cr build -t us.icr.io/$NAMESPACE/os-signal:0.0.1 src/os-signal/
ibmcloud cr build
is a wrapper around docker build that does docker build and push in a single command and it also doesn't store the image in the local system. Pretty great for a cloud environment.
Lets see if our image got the right place.
ibmcloud cr images
It should return the image that we just created and pushed.
Use Image in Kubernetes
Lets try using this image in our deployment.
But first login to the ibm account.
ibmcloud login --sso
This time choose account 2. (the one with IBM)
Update the file at k8s/private-docker-registry/deployment-private.yaml
...
- image: us.icr.io/<YOUR-NAMESPACE>/os-signal:0.0.1
...
Update <YOUR-NAMESPACE>
with your namespace name.
Apply the deployment
kubectl apply -f k8s/private-docker-registry/deployment-private.yaml
Check if the pod got or not.
kubectl get pod
private-86d7b54556-4ln47 0/1 ImagePullBackOff 0 3m30s
Lets see whats going on by describing the pod
kubectl describe pod -l name=private-pod
In the bottom we will see events that happened.
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 5m2s default-scheduler Successfully assigned default/private-86d7b54556-4ln47 to 10.188.186.13
Normal Pulling 3m26s (x4 over 5m1s) kubelet, 10.188.186.13 pulling image "us.icr.io/mofi-kube/os-signal:0.0.1"
Warning Failed 3m26s (x4 over 5m1s) kubelet, 10.188.186.13 Failed to pull image "us.icr.io/mofi-kube/os-signal:0.0.1": rpc error: code = Unknown desc = failed to resolve image "us.icr.io/mofi-kube/os-signal:0.0.1": no available registry endpoint: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
Warning Failed 3m26s (x4 over 5m1s) kubelet, 10.188.186.13 Error: ErrImagePull
Warning Failed 3m14s (x6 over 5m) kubelet, 10.188.186.13 Error: ImagePullBackOff
Normal BackOff 3m1s (x7 over 5m) kubelet, 10.188.186.13 Back-off pulling image "us.icr.io/mofi-kube/os-signal:0.0.1"
The main line that tells us what went wrong is
Failed to pull image "us.icr.io/mofi-kube/os-signal:0.0.1": rpc error: code = Unknown desc = failed to resolve image "us.icr.io/mofi-kube/os-signal:0.0.1": no available registry endpoint: pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
So our pull access is denied. This is understandable. Our cluster is under the IBM account and the image is in our own account. Kubernetes does not know how to pull this image.
Creating Secret for Docker
We will create a docker secret so that Kubernetes can pull this image.
Done Run this yet, but this is what we want.
kubectl create secret docker-registry private-docker-secret \
--docker-server=https://us.icr.io \
--docker-username=iamapikey \
--docker-password=<IAMAPIKEY> \
--docker-email="[email protected]"
Well we don't really have that IAMAPIKEY
at hand. Lets go create that.
First lets log back into your account again.
ibmcloud login --sso
Choose your account.
Then run
ibmcloud iam api-key-create docker-iam-key -d "key for accessing docker image registry"
This creates a API key.
This api key has full user access. Its not good practice to create such api keys. You can also create service api key. Which is a better choice and only gives access to a single service.
The command creates and prints the api key
The key should be stored somewhere as it can't be retrieved later.
Name docker-iam-key
Description key for accessing docker image registry
Created At 2019-08-01T06:48+0000
API Key <Some API Key>
Locked false
UUID ApiKey-2e5c6806-ed81-4669-b8cb-e9ba88c832b6
Now that we have api key
Lets create the docker secret. But before we need to switch back to the IBM account.
ibmcloud login --sso
Choose the IBM Account
export the apikey for easier copy-paste
export APIKEY="<your-api-key>"
kubectl create secret docker-registry private-docker-secret \
--docker-server=https://us.icr.io \
--docker-username=iamapikey \
--docker-password=$APIKEY \
--docker-email="[email protected]"
Check the secret was crated
kubectl get secrets
We should see our secret there
NAME TYPE DATA AGE
default-au-icr-io kubernetes.io/dockerconfigjson 1 9h
default-de-icr-io kubernetes.io/dockerconfigjson 1 9h
default-icr-io kubernetes.io/dockerconfigjson 1 9h
default-jp-icr-io kubernetes.io/dockerconfigjson 1 9h
default-token-5tdlr kubernetes.io/service-account-token 3 9h
default-uk-icr-io kubernetes.io/dockerconfigjson 1 9h
default-us-icr-io kubernetes.io/dockerconfigjson 1 9h
kube201-workshop01 Opaque 2 9h
private-docker-secret kubernetes.io/dockerconfigjson 1 9m26s
Secrets in. Lets try the deployment again.
kubectl get po
imagePullBackOff
again. Why?
So we created a secret but we didn't tell our pod to use it.
In the deployment yaml we have this 2 commented out lines
containers:
- image: us.icr.io/<YOUR-NAMESPACE>/os-signal:0.0.1
name: os-signal
imagePullPolicy: Always
# imagePullSecrets:
# - name: private-docker-secret
Lets use nano or vi to uncomment them
nano k8s/private-docker-registry/deployment-private.yaml
imagePullSecrets needs to be at the same level as containers key. Basically delete two characters.
Lets try this one last time. 🤞🏼
kubectl apply -f k8s/private-docker-registry/deployment-private.yaml
After a moment we should get the pod is running.
kubectl get po
We know all about what this pod does. But if you want to test its still the same thing. (You should always test, Trust but Verify)
kubectl logs -f -l name=private-pod
2019/08/01 07:10:32 awaiting signal
If we send a delete command
kubectl delete po -l name=private-pod
2019/08/01 07:13:11 Doing all sorts of cleanup work!
2019/08/01 07:13:21 exiting
So we can verify the app is working fine. 😎
Last updated
Was this helpful?