Skip to content

Latest commit

 

History

History
243 lines (183 loc) · 9.08 KB

kube-docker-reg.md

File metadata and controls

243 lines (183 loc) · 9.08 KB

Docker Registory

  1. Create own local Docker registry.

Select some free external node for placing your docker registry in there, it must have enough disk space for storing your local Docker images. Then ssh into it and install Docker, if it’s not installed. Also, you need to have installed OpenSSL on this node, after that we can create own registry:

Alternative you can install it on a Master / Control Plane node

master01

mkdir -p /opt/registry/{certs,store,auth}

We just created a new directory for our new Docker registry, in store sub-directory we’ll keep our docker images, in certs directory we’ll put our self-created SSL certificate and in auth will be htpasswd file with credentials for basic authentication.

Now let’s create a certificate using OpenSSL utility, as we don’t have a FQDN name for this registry we need to put the node public IP into the openssl config file, into [ v3_ca ] section first:

vi /etc/ssl/openssl.cnf
[ v3_ca ]
subjectAltName=IP:x.x.x.x # Put your master or registory node IP address here

Now let’s create a cert and key pair:

cd /opt/registryregistry

openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt

You will see output similar to below

Generating a RSA private key
.............................................................................++++
........................................................................................++++
writing new private key to 'certs/domain.key'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [VIC]:
Locality Name (eg, city) []:
Organization Name (eg, company) [Some Company Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:x.x.x.x                   
Email Address []:

Don’t forget to put the registry node public IP as a server FQDN name. This will create two files in the cert directory, called domain.crt and domain.key.

Now we need to create a password file for the basic authentication:

cd /opt/registryregistry

docker run --rm --entrypoint htpasswd registry:2 -Bbn admin some-password >> auth/htpasswd

OK, we almost did with it, now let’s start our registry using docker command:

docker run -d -p 5000:5000 --restart=always --name registry \
  -v /opt/registry/certs:/certs \
  -v /opt/registry/store:/var/lib/registry \
  -v /opt/registry/auth:/auth \
  -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
  -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
  -e REGISTRY_AUTH=htpasswd \
  -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
  -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
  registry:2

Then make sure that our registry container is running well:

docker ps

CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
7d89a1788086        registry:2          "/entrypoint.sh /etc…"   2 seconds ago       Up 1 second         0.0.0.0:5000->5000/tcp   registry

If you’ll get any errors at this point, please use docker logs container_id command for figuring them out.

Now let’s try to login into this new registry, from any node with installed docker run:

master02# docker login x.x.x.x:5000
Username: admin
Password: some-password
Error response from daemon: Get https://x.x.x.x:5000/v1/users/: x509: certificate signed by unknown authority

This error happens because we use a self-signed certificate and docker know nothing about it, if you have a valid certificate, you can use them instead.

In our example, we need to add the self-created certificate to docker trusted certificates, on all nodes that will use this registry.

On all these nodes you need to run:

mkdir -p /etc/docker/certs.d/x.x.x.x:5000

# Copy in there domain.crt file from registry /opt/registry/certs
scp x.x.x.x:/opt/registry/certs/domain.crt /etc/docker/certs.d/x.x.x.x:5000

# Rename file
cd /etc/docker/certs.d/x.x.x.x:5000
mv domain.crt ca.crt

# Reload docker engine
systemctl reload docker

After this will be done, try to log in one more time:

master02# docker login x.x.x.x:5000
Username: admin
Password: some-password
Login Succeeded

Don’t forget to repeat step with adding self signed certificate on all docker for all your Kubernetes cluster nodes too !

Good, now all works as it must, let’s test out registry by putting in there any Docker image, for example, nginx. It may need to pull them from public registry first:

master02# docker pull nginx

Using default tag: latest
latest: Pulling from library/nginx
27833a3ba0a5: Pull complete 
e83729dd399a: Pull complete 
ebc6a67df66d: Pull complete 
Digest: sha256:dff6326b09c76bef1425ee64c2e218b38737cdb5412b8ccf84ca70740bfa1db2
Status: Downloaded newer image for nginx:latest

master01# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
nginx               latest              2bcb04bdb83f        11 hours ago        109MB

master01# docker tag 2bcb04bdb83f x.x.x.x:5000 nginx

master01# docker push x.x.x..:5000/nginx
The push refers to a repository [x.x.x.x:5000/nginx]
7e274c0effe8: Pushed 
dd0338cdfab3: Pushed 
5dacd731af1b: Pushed 
latest: digest: 
sha256:dc4887a794219dc5e3459abc1575f1fa293da344772c33f5bf0a96767371d4e3 size: 948

OK, now we have tested our new private registry by pushing in there some test Docker image, and it works well. You can check the store directory on the registry node and see their new sub-directories with our pushed nginx test image:

master01# ls /opt/registry/store/docker/registry/v2/repositories/nginx

As I said previously you need to add this self-signed certificate to all docker engines on nodes that will communicate with your internal docker registry, or use the valid certificate instead.

Well, it’s time to add this new internal registry to our Kubernetes cluster. First, we need to create some Secret in our Kubernetes cluster for it. This Secret will use information from any node, that you have configured with our self-created certificates and successfully logged in to this local registry after this. After a successful login, the docker engine on these nodes always stores information in config.json file for the future time. So we need to take it from there:

master01# cat ~/.docker/config.json | base64

ewoJImF1dGhzIjogewoJCSIxOTQuMTMyLjQ5LjExNzo1MDAwIjogewoJCQkiYXV0aCI6ICJZV1J00NmRXaG1lV0p1VmpjNCIKCQl9LAoJCSJsYWJzLmludGVybmV0dmlraW5ncy5zZTo1MDAwIjogoJCQkiYXV0aCI6ICJjbVZuWVdSdGFXNDZjR2h2WVRWQ2RYbz0iCgkJfQoJfQrdf

Copy this data and login then to your Kubernetes cluster control node, with configured kubectl, there we’ll add new Secret to our cluster:

master01# vi registry-secret.yaml
apiVersion: v1
kind: Secret
metadata:
 name: registrypullsecret
data:
 .dockerconfigjson: <base-64-encoded-copied-json-here>
type: kubernetes.io/dockerconfigjson

Create this new secret then:

master01# kubectl create -f registry-secret.yaml

master01# kubectl get secrets
.....
registrypullsecret                   kubernetes.io/dockerconfigjson        1      59s

And at this point we can try to deploy previously pushed nginx, from our local registry as a pod:

master01# vi local-registry-nginx.yaml
apiVersion: v1
kind: Pod
metadata:
 name: nginx-test
spec:
 containers:
 - name: nginx-test
   image: x.x.x.x:5000/nginx
 imagePullSecrets:
 - name: registrypullsecretcontrol
 
kubectl create -f local-registry-nginx.yaml
pod/nginx-test created

master01# kubectl get pods
nginx-test                          1/1     Running   0          9s

As you can see, there was successfully downloaded and started the nginx pod, from our local docker registry.

You can sure about it by running kubectl describe pod nginx-test and looking into Containers: section:

master01# kubectl describe pod nginx-test.... ... ..
Containers:
  nginx-test:
    Container ID:   docker://e31c8c4f444a02467d8352b1ea2b4e7688176969c962e736590931a0ce594e8f
    Image:          x.x.x.x:5000/nginx
    Image ID:       docker-pullable://x.x.x.x:5000/nginx@sha256:gc4887a794219dc5e3459abc1575f1fa293da344772c33f5bf0as6767371s4e3
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 28 Mar 2020 10:11:45 +0100
    Ready:          True
    Restart Count:  0
    Environment:    <none>

This means that you can use this new internal registry for storing any private containers if you don’t wanna share them with the Docker community for security or other reasons. Also, you can build any Kubernetes resources based on these images as well.

If you’ll get any error, when Kubernetes try to pull images, that mean you forgot to add certificate it to Docker engine on all or some of your Kubernetes nodes.