Deploying Local Image Registry

A local registry is needed to pull NGINX Plus Ingress Controller image from k3s.

Make sure Docker already installed.

Note

This already deployed in your lab deployment.

Deployment Manifest

Resource defined in the manifest:

Persistent volume & claim

Required to store downloaded Docker images, it needs to be persistent.

The local-registry pod

The pod itself.

Service

To publish the local-registry service.

/home/ubuntu/setup/local-registry.yaml manifest file

 1apiVersion: v1
 2kind: PersistentVolume
 3metadata:
 4  name: local-registry-pv
 5spec:
 6  capacity:
 7    storage: 10Gi
 8  accessModes:
 9    - ReadWriteOnce
10  hostPath:
11    path: /tmp/repository
12
13---
14apiVersion: v1
15kind: PersistentVolumeClaim
16metadata:
17  name: local-registry-pvc
18spec:
19  accessModes:
20    - ReadWriteOnce
21  resources:
22    requests:
23      storage: 10Gi
24
25---
26apiVersion: v1
27kind: Pod
28metadata:
29  name: local-registry
30  labels:
31    app: local-registry
32spec:
33  containers:
34    - name: local-registry
35      image: registry:2.6.2
36      volumeMounts:
37        - name: repo-vol
38          mountPath: "/var/lib/registry"
39        - name: certs-vol
40          mountPath: "/certs"
41          readOnly: true
42        - name: auth-vol
43          mountPath: "/auth"
44          readOnly: true
45      env:
46        - name: REGISTRY_AUTH
47          value: "htpasswd"
48        - name: REGISTRY_AUTH_HTPASSWD_REALM
49          value: "Registry Realm"
50        - name: REGISTRY_AUTH_HTPASSWD_PATH
51          value: "/auth/htpasswd"
52        - name: REGISTRY_HTTP_TLS_CERTIFICATE
53          value: "/certs/tls.crt"
54        - name: REGISTRY_HTTP_TLS_KEY
55          value: "/certs/tls.key"
56  volumes:
57    - name: repo-vol
58      persistentVolumeClaim:
59        claimName: local-registry-pvc
60    - name: certs-vol
61      secret:
62        secretName: local-registry-tls
63    - name: auth-vol
64      secret:
65        secretName: local-registry-auth
66
67---
68apiVersion: v1
69kind: Service
70metadata:
71  name: local-registry
72spec:
73  selector:
74    app: local-registry
75  ports:
76    - port: 5000
77      targetPort: 5000

Deployment Script

Steps executed by this script:

  1. Generate TLS certificate and htpasswd file

  2. Create secrets for tls, generic and docker-registry

  3. Deploy local-registry pods

  4. Setup docker to use the local-registry

  5. Setup K3s to use the local-registry

/home/ubuntu/setup/local-registry.sh script file

 1#!/bin/bash
 2#
 3# Local Docker registry install script
 4#
 5
 6# Generate certificate & htpasswd
 7openssl req -x509 -newkey rsa:4096 -days 365 -nodes -sha256 -keyout local-registry.key -out local-registry.crt -subj "/CN=local-registry" -addext "subjectAltName = DNS:local-registry"
 8docker run --rm --entrypoint htpasswd registry:2.6.2 -Bbn myuser mypasswd > htpasswd
 9
10# Create secrets
11kubectl create secret tls local-registry-tls --cert=local-registry.crt --key=local-registry.key
12kubectl create secret generic local-registry-auth --from-file=htpasswd
13kubectl create secret docker-registry local-registry-cred --docker-server=local-registry:5000 --docker-username=myuser --docker-password=mypasswd
14
15# Create local-registry pod
16kubectl create -f local-registry.yaml
17echo -n "Waiting for pod to up and running"
18
19# wait for the pod to up and running before continue
20while true;
21do
22  if [ "$(kubectl get pod local-registry -o=jsonpath='{.status.phase}')" == "Running" ]; then
23    break;
24  fi
25  echo -n ".";
26  sleep 3;
27done
28
29set -x
30
31# Setup docker to use local-registry
32export REGISTRY_IP="$(kubectl get svc local-registry -o=jsonpath={.spec.clusterIP})"
33sudo sh -c "echo '$REGISTRY_IP local-registry' >> /etc/hosts"
34sudo mkdir -p /etc/docker/certs.d/local-registry:5000
35sudo cp local-registry.crt /etc/docker/certs.d/local-registry:5000/ca.crt
36
37# Setup K3s to use local-registry
38cat <<EOF > /tmp/registries.yaml
39configs:
40    "local-registry:5000":
41        auth:
42            username: myuser
43            password: mypasswd
44        tls:
45            ca_file: /etc/docker/certs.d/local-registry:5000/ca.crt
46            insecure_skip_verify: true
47EOF
48sudo mv /tmp/registries.yaml /etc/rancher/k3s/
49sudo systemctl restart k3s
50
51# Test
52docker login local-registry:5000 -u myuser -p mypasswd
53echo "Local-registry setup, done!"

Make sure you’re in APP node then change working directory to /home/ubuntu/setup, then run the deployment script:

$ bash local-registry.sh

Verify Deployment

After install script finished, you can verify the result using below command:

$ kubectl get pods,svc,ep local-registry -o wide
NAME                 READY   STATUS    RESTARTS        AGE   IP           NODE   NOMINATED NODE   READINESS GATES
pod/local-registry   1/1     Running   3 (3h13m ago)   38h   10.42.0.40   app    <none>           <none>

NAME                     TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE   SELECTOR
service/local-registry   ClusterIP   10.43.3.5    <none>        5000/TCP   38h   app=local-registry

NAME                       ENDPOINTS         AGE
endpoints/local-registry   10.42.0.40:5000   38h

You can see the pod is running, the service & endpoint are defined.

Check if you can login to local-registry via Docker CLI:

$ docker login local-registry:5000 -u myuser -p mypasswd

At this point, the local registry is deployed inside k3s.