Kubernetes: Private Docker Registry in 5 Minutes

Do I really need a private Docker Registry?

----     ------     ----               ----                -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/webpage-5fc78c945d-sl7gx to k3s-node2
Normal Pulling 15s (x2 over 31s) kubelet, k3s-node2 Pulling image "webpage"
Warning Failed 14s (x2 over 31s) kubelet, k3s-node2 Error: ErrImagePull
Warning Failed 14s (x2 over 31s) kubelet, k3s-node2 Failed to pull image "webpage": rpc error: code = Unknown desc = failed to pull and unpack image "docker.io/library/webpage:latest": failed to resolve reference "docker.io/library/webpage:latest": pull access denied, repository does not exist or may require authorization: server message: insufficient_scope: authorization failed
Warning Failed 2s (x2 over 30s) kubelet, k3s-node2 Error: ImagePullBackOff
Normal BackOff 2s (x2 over 30s) kubelet, k3s-node2 Back-off pulling image "webpage"

Private Docker Registry

  • Create a domain and DNS entry
  • Install docker registry
  • Add TLS certificates

Domain and DNS Entry

Install Docker Registry

>> arkade install docker-registryNAME: docker-registry
LAST DEPLOYED: Sun Apr 26 19:29:33 2020
NAMESPACE: default
STATUS: deployed
REVISION: 2
TEST SUITE: None
NOTES:
...=======================================================================
= docker-registry has been installed. =
=======================================================================
# Find out more at:
# https://github.com/helm/charts/tree/master/stable/registry
Thanks for using arkade!
Registry credentials: USERNAME SECRET
export DOCKER_REGISTRY=<<domain>>
export DOCKER_USERNAME=<<admin>>
export DOCKER_PASSWORD=<<password>>
export DOCKER_EMAIL=<<email>>

Provide TLS Certificates

>> arkade install docker-registry-ingress --email $DOCKER_EMAIL --domain $DOCKER_REGISTRY=======================================================================
= Docker Registry Ingress and cert-manager ClusterIssuer have been installed =
=======================================================================
>> kubectl get ingress docker-registry --output=yamlapiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod-registry
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-body-size: 200m
spec:
rules:
- host: docker.admantium.com
http:
paths:
- backend:
serviceName: docker-registry
servicePort: 5000
path: /
tls:
- hosts:
- docker.admantium.com
secretName: docker-registry
status:
loadBalancer:
ingress:
- ip: 49.12.45.26
> kubectl logs -n cert-manager deploy/cert-managerI0502 15:26:54.317163       1 sync.go:379] cert-manager/controller/certificates "level"=0 "msg"="validating existing CSR data" "related_resource_kind"="CertificateRequest" "related_resource_name"="docker-admantium-com-3726166042" "related_resource_namespace"="default" "resource_kind"="Certificate" "resource_name"="docker-admantium-com" "resource_namespace"="default"I0502 15:26:54.317935       1 sync.go:479] cert-manager/controller/certificates "level"=0 "msg"="CertificateRequest is not in a final state, waiting until CertificateRequest is complete" "related_resource_kind"="CertificateRequest" "related_resource_name"="docker-admantium-com-3726166042" "related_resource_namespace"="default" "resource_kind"="Certificate" "resource_name"="docker-admantium-com" "resource_namespace"="default" "state"="Pending"I0502 15:26:54.324391       1 controller.go:135] cert-manager/controller/certificates "level"=0 "msg"="finished processing work item" "key"="default/docker-registry"

Test: Pushing Images to Private Docker Registry

> docker login $DOCKER_REGISTRY --username=$DOCKER_USERNAME --password=$DOCKER_PASSWORDLogin Succeeded
> docker push docker.admantium.com/webpage:latestThe push refers to repository [docker.admantium.com/webpage]
599b6638e2aa: Pushed
81210be95b2f: Pushed
f3629d9fa534: Pushed
403ab6c36d93: Pushed
313be5a92861: Pushed
f6fbf55b4240: Pushing [=============> ] 23.42MB/83.96MB
2fc9f319e2c4: Pushed
de7d7e8f96e8: Pushed
55c928cc6db5: Pushed
e90cdc933987: Pushed
dba921702de8: Pushing [=====> ] 8.229MB/76.92MB
883a1e8c9056: Pushing [==> ] 17.66MB/326MB
1fbb01ef7573: Pushing [==================================================>] 3.584kB
b54ada1169f0: Pushing [==============> ] 2.241MB/7.621MB
0586a03753aa: Waiting
531743b7098c: Waiting
kb create deployment --image docker.adamantium.com/webpage
>> kb describe pod/webpage-86976f8869-5jgtzName:         webpage-86976f8869-5jgtz
Namespace: default
Priority: 0
Node: k3s-node2/49.12.64.126
Start Time: Sun, 26 Apr 2020 19:57:53 +0200
Labels: app=webpage
pod-template-hash=86976f8869
Annotations: <none>
Status: Pending
...Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled <unknown> default-scheduler Successfully assigned default/test-86976f8869-5jgtz to k3s-node2
Normal Pulling 36s (x3 over 77s) kubelet, k3s-node2 Pulling image "docker.admantium.com/webpage"
Warning Failed 35s (x3 over 75s) kubelet, k3s-node2 Failed to pull image "docker.admantium.com/webpage": rpc error: code = Unknown desc = failed to pull and unpack image "docker.admantium.com/webpage:latest": failed to resolve reference "docker.admantium.com/webpage:latest": unexpected status code [manifests latest]: 401 Unauthorized

Configure a Kubernetes Secrete to Access the Registry

kubectl create secret docker-registry registry-secret \
--docker-server=$DOCKER_REGISTRY \
--docker-username=$DOCKER_USERNAME \
--docker-password=$DOCKER_PASSWORD \
--docker-email=$DOCKER_EMAIL secret/registry-secret created
> kb describe secret registry-secretName:         registry-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjsonData
====
.dockerconfigjson: 166 bytes
apiVersion: apps/v1
kind: Deployment
metadata:
name: webpage
spec:
selector:
matchLabels:
app: webpage
template:
metadata:
labels:
app: webpage
spec:
containers:
- name: webpage
image: docker.admantium.com/webpage:latest
imagePullSecrets:
- name: registry-secret
>>  kb describe pod/webpage-7b4469547b-cpbrqName:         webpage-7b4469547b-cpbrq
Namespace: default
Priority: 0
Node: k3s-node2/49.12.64.126
Start Time: Sun, 26 Apr 2020 20:43:19 +0200
Labels: app=webpage
pod-template-hash=7b4469547b
Annotations: <none>
Status: Running
IP: 10.42.2.151
IPs:
IP: 10.42.2.151
Controlled By: ReplicaSet/webpage-7b4469547b
Containers:
webpage:
Container ID: containerd://a42ac84a8e8fca2e67c5b32a690d00f5b63bd79a71ecd25a5a62764ebb109768
Image: docker.admantium.com/webpage:0.1.0
Image ID: docker.admantium.com/webpage@sha256:1c15180d3d08a8d4c8f5e7f368bbf54a7a33c163cf0aacb4cb60f460aee6e441

Conclusion

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store