Thursday, December 26, 2024
Google search engine
HomeGuest BlogsInstall and Use Trow Container Image Registry With Kubernetes

Install and Use Trow Container Image Registry With Kubernetes

In this era, we can all agree that containerization is almost everywhere. It allows many people and organizations around the world to run applications in a lightweight executable known as a container. The containers contain all the required dependencies and packages required to run an application. This comes with several benefits such as portability and agility for developers. There are several tools that can be used to run the containers. The most popular ones are docker, Podman, Openshift, Kubernetes etc.

Container images can be created using tools like  BuildahkanikoImg Image builder etc. Once created, the images can either be saved on your local machine or stored elsewhere so that they can be accessed, shared and used later when required.

A container registry can be defined as a repository or a collection of repositories that provides storage for your container images. This serves as an intermediary when sharing the images across your organization/systems. Using container registries, you are able to access the images by uploading (pushing) and downloading them(pulling) to a remote system.

There are two main container registry types:

  • Public registries: used by individuals and small teams that want to spin and run registries as fast as possible. These are less secure and might cause problems such as patching, privacy, and access control for large organizations.
  • Private registries: They provide advanced security features, providing the best way to incorporate security and privacy into enterprise container image storage. They can be hosted remotely or o-premise. The most popular Private Registries are Google Container Registry, Amazon Elastic Container Registry (ECR), and the Azure Container Registry

What is Trow Container Image Registry?

Do you know that there is an image management solution for Kubernetes and other orchestrators which runs inside the cluster, is simple to set up and fully integrated with Kubernetes, including support for auditing and RBAC? Yes, there is!

Trow” is a word with several, diverse meanings. In Shetland folklore, it can be defined as a small, mischievous creature, similar to the Scandanavian troll. In England, it is an old-style of cargo boat that transported goods on rivers. But its origin is archaic to mean “to think, believe, or trust”. But you have the freedom to choose the interpretation you like.

Trow provides a secure and fast registry used to get containers running on the cluster. Its main focus is to give control to system admins so that they can define which images can run in the cluster. It prevents unauthorised and potentially insecure or malicious images from being deployed into your cluster.

The main features provided by Trow are:

  • Distributed architecture for HA and scalability (planned)
  • Full auditing and authentication of image access (in progress)
  • Controls images running inside the cluster via approve/deny lists
  • It conforms to the OCI Distribution Specification for registries

In this tutorial, we will learn how we can install and use Trow Container Image Registry With Kubernetes.

1. Set up a Kubernetes Cluster

This guide requires one to have a Kubernetes Cluster up and running. There are several ways you can use to create a Kubernetes cluster. This website provides the following options:

After spinning the cluster, ensure that you have kubectl set up. You can use the below command to install it:

curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin

Now to have access to the cluster, export the admin config:

##For RKE2
export PATH=$PATH:/var/lib/rancher/rke2/bin export KUBECONFIG=/etc/rancher/rke2/rke2.yaml

##For K0s
export KUBECONFIG=/var/lib/k0s/pki/admin.conf

Verify if kubectl is working:

$ kubectl get nodes
NAME      STATUS   ROLES           AGE     VERSION
master    Ready    control-plane   2m12s   v1.25.4+k0s
worker1   Ready    <none>          97s     v1.25.4+k0s
worker2   Ready    <none>          79s     v1.25.4+k0s

2. Create a Persistent Storage for Trow

The Trow Container Image Registry requires a persistent storage to store files and configurations. We will begin by creating a dedicated namespace for the installation:

kubectl create namespace trow

Set it as the default namespace:

kubectl config set-context --current --namespace trow

Manually defining Storage Class (ignore if you have already)

Once the namespace has been created, we will now create a storage class.

kubectl apply -f - <<EOF
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: trow-sc
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
EOF

Now set it as a default storage class:

kubectl patch storageclass trow-sc -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

Verify this:

$ kubectl get sc
NAME                PROVISIONER                    RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
trow-sc (default)   kubernetes.io/no-provisioner   Delete          WaitForFirstConsumer   false                  11s

Now create a persistent volume on this storage class:

$ vim trow-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: trow-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: trow-sc
  local:
    path: /mnt/disk/vol1
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: kubernetes.io/hostname
          operator: In
          values:
          - worker1

Before we create the PV, you need to create the path on the specified node. For this case, it is worker1

sudo mkdir -p /mnt/disk/vol1
sudo chmod 777 /mnt/disk/vol1

##Also run this On Rhel-based systems#####
sudo chcon -Rt svirt_sandbox_file_t /mnt/disk/vol1

Using default existing Storage Class

To use existing storage class name configure like below.

$ vim trow-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: trow-pv
spec:
  capacity:
    storage: 20Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain

Now apply the manifest file:

kubectl create -f trow-pv.yml

3. Install Trow Container Image Registry on Kubernetes

For this guide, we will install the Trow Container Image Registry on Kubernetes using Helm. Therefore, you need to have Helm installed on your system. The easiest way to install Helm is captured in the guide below:

Once Helm has been installed, add the helm chart for trow:

helm repo add trow https://trow.io

Now you can install Trow using the added Helm Chart. During the installation, you can also use several other variables that include:

Parameter Description Default value
trow.domain The Domain that Trow will be served on, you will need to setup the DNS to point to the correct IP myregistry.mydomain.io
trow.user the admin user name user
trow.password the admin password password
trow.validatingWebhooks.enabled enable the validation webhooks that block unauthorized images false
imagePullSecrets secret used to pull the image (not needed if using the default image) []
service.type type on the service ( ClusterIP, NodePort, LoadBalancer) NodePort
service.port Port to expose the service on 8000
ingress.enabled Enable the ingress setup false
ingress.annotations List of annotations to set on the ingress {}
ingress.hosts Host configuration for the ingress [{host: null, paths: [‘/’]}}
ingress.gke Set to true if you are using GKE’s managed SSL certificates false
ingress.tls TLS configuration for the Ingress []
resources Resource Limits and quotas (currently no limits or requests set) {}
nodeSelector Selector to define which nodes to put the pods on {}
tolerations Any toleration values to be set on the pods []
affinity Any affinity rules to be set on the pod {}
volumeClaim As trow uses a statefulset and uses a volume to store data this can be configured accordingly {accessModes: [“ReadWriteOnce”], resources: {requests: {storage: “20Gi”}}}
replicaCount Amount of replicas of trow to run 1

It is possible to use a few variables by declaring them in a YAML file. Below are demo variables for the ingress service.

$ vim values.yaml
ingress:
    enabled: true
    tls: 
    - hosts:
      - trow.geeksforgeeks.org
      secretName: myingress-cert

In this guide, we will not use the values since we will deploy an ingress controller separately. Begin by creating and Installing the ingress controller.

a. Install and Configure an Ingress Controller

We can install Traefik ingress from Helm charts using the aid in the guide below:

Now ensure that the obtained Loadbalancer IP for the Ingress service is mapped to a domain name:

$ sudo vim /etc/hosts
192.168.205.40 trow.geeksforgeeks.org 

We will now generate TLS certs for the Loadbalancer IP. Now create your certificate secret. In this guide, I will demonstrate how to create this using Self-signed certificates. Create a simple config file for this:

$ cd ~/ && vim csr.conf
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
req_extensions = req_ext
distinguished_name = dn

[ dn ]
C = KE
ST = Nairobi
L = Nairobi
O = Computingforgeeks
OU = tech
CN = trow.geeksforgeeks.org

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster
DNS.5 = kubernetes.default.svc.cluster.local
DNS.6 = trow.geeksforgeeks.org
IP.1 = <LoadBalancer_IP>

[ v3_ext ]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=keyEncipherment,dataEncipherment
extendedKeyUsage=serverAuth,clientAuth
subjectAltName=@alt_names

Generate a ca.key and ca.crt

openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=trow.geeksforgeeks.org" -days 10000 -out ca.crt

Create s server key:

openssl genrsa -out server.key 2048

Now we will create a Certificate Signing Request using the config:

openssl req -new -key server.key -out server.csr -config csr.conf

Now generate a server certificate using the ca.key, ca.crt and server.csr:

openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -out server.crt -days 10000 \
    -extensions v3_ext -extfile csr.conf -sha256

Now we will create Kubernetes secrets:

kubectl create secret generic myingress-cert --from-file=tls.crt=./server.crt --from-file=tls.key=./server.key --from-file=ca.crt=./ca.crt

Verify the secret creation:

$ kubectl get secrets
NAME                            TYPE                 DATA   AGE
myingress-cert                  Opaque               3      13s

b. Run Trow Container Image Registry

Install Trow using the variable and any other desired flags. For example here, set our desired domain name.

helm install \
    trow \
    trow/trow \
--set trow.domain=trow.geeksforgeeks.org

Sample output:

NAME: trow
LAST DEPLOYED: Fri Dec 30 15:35:25 2022
NAMESPACE: trow
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Welcome to Trow!

Please set the DNS entry for your registry to point to Trow

If you are running Trow on http, there will need to be a TLS ingress in front of it as Trow needs to be run over TLS.
Please see the examples found on the docs at
https://github.com/ContainerSolutions/trow/blob/main/docs/HELM_INSTALL.md

To test you can run and login with the credentials for 

$ docker login https://trow.geeksforgeeks.org


Please contribute to the Trow project at https://github.com/ContainerSolutions/trow/

In case you want to use the YAML, will have your command as:

helm install \
    -f values.yaml  \
    trow \
    trow/trow \
--set trow.domain=trow.geeksforgeeks.org

Check if the pod is running:

# kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
traefik-865f54fc64-66f5n   1/1     Running   0          25m
trow-0                     1/1     Running   0          2m35s

After this, we need to configure an ingress controller for HTTPS.

$ vim trow-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: trow-https
  annotations:
    traefik.ingress.kubernetes.io/router.entrypoints: websecure
spec:
  rules:
    - host: trow.geeksforgeeks.org
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: trow
                port:
                  number: 8000
  tls:
  - hosts:
    - trow.geeksforgeeks.org
    secretName: myingress-cert

Apply the ingress:

kubectl apply -f trow-ingress.yaml

Verify the creation:

NAME         CLASS     HOSTS                        ADDRESS   PORTS     AGE
trow-https   traefik   trow.geeksforgeeks.org             80, 443   16s

Now we have trow.geeksforgeeks.org ready to handle HTTPS connections for Trow. To verify this use:

$ curl -k https:///trow.geeksforgeeks.org
<!DOCTYPE html><html><body>
<h1>Welcome to Trow, the cluster registry</h1>
</body></html>root

4. Test Trow Container Image Registry

We can now test if Trow Container Image Registry is working as desired. By default docker only uses TLS to pull and push images, we, therefore, have one problem, we have used self-signed certs. You can set docker to use insecure Registries or trust the certs.

First, ensure that docker is installed on your system.

  • Option 1: Allow docker to use insecure registries.
$ sudo vim /etc/docker/daemon.json
{
"insecure-registries" : ["trow.geeksforgeeks.org"]
}

Restart the service:

sudo systemctl restart docker
  • Option 2: Set docker to trust the certs

For this option, copy the ca.cert for the domain name/IP Address to the docker certs directory

sudo mkdir -p /etc/docker/certs.d/trow.geeksforgeeks.org
sudo cp ~/ca.crt /etc/docker/certs.d/trow.geeksforgeeks.org/ca.crt

Now verify if everything is working:

$ docker login trow.geeksforgeeks.org
Username: user
Password: password
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

You can also use Podman, with the syntax:

##For Podman with HTTPS
podman login <trow_address>

#For Podman with HTTP
podman login <trow_address> --tls-verify=false

Use the default login creds if you have not configured any, to access your Trow Container Image Registry. Once logged in as above, we can now try to push images to the registry.

Create a sample docker image file:

$ vim Dockerfile
FROM ubuntu:20.04
RUN apt-get update -y
ENV DEBIAN_FRONTEND=noninteractive 
RUN apt-get install -y gnupg apt-transport-https apt-utils wget
RUN echo "deb https://notesalexp.org/tesseract-ocr5/focal/ focal main" \
|tee /etc/apt/sources.list.d/notesalexp.list > /dev/null
RUN wget -O - https://notesalexp.org/debian/alexp_key.asc | apt-key add -
RUN apt-get update -y
RUN apt-get install tesseract-ocr -y
RUN apt install imagemagick -y
ENTRYPOINT ["tesseract"]
RUN tesseract -v

Build the image:

##For Docker
docker build . -t tesseract:5

##For Podman
podman build . -t tesseract:5

We will add a tag to this built image. For example:

docker tag tesseract:5 trow.geeksforgeeks.org/library/tesseract:latest

List the images:

$ docker images
REPOSITORY                                     TAG          IMAGE ID       CREATED          SIZE
tesseract                                      5            4a8b781f348b   29 seconds ago   308MB
trow.geeksforgeeks.org/library/tesseract   latest       4a8b781f348b   29 seconds ago   308MB
ubuntu                                         20.04        d5447fc01ae6   3 weeks ago      72.8MB

Now push the image:

$ docker push trow.geeksforgeeks.org/library/tesseract:latest
The push refers to repository [trow.geeksforgeeks.org/library/tesseract]
d6b5cd35d094: Pushed 
f1337b051098: Pushed 
0ec1183a10ba: Pushed 
79a92b7eb192: Pushed 
05b2e6435d75: Pushed 
bcaa36a72e2f: Pushed 
ada7a75be815: Pushed 
0002c93bdb37: Pushed 
latest: digest: sha256:4c61af5027ef185d7d090726aae7e57a9d275a54eedd1630c4efec71cf0d161d size: 2001

You now have a new image successfully pushed to Trow Container Image Registry! We can now use the image to run a container with Docker or Kubernetes.

On Docker, use:

$ docker run --rm trow.geeksforgeeks.org/library/tesseract
Unable to find image 'trow.geeksforgeeks.org/library/tesseract:latest' locally
latest: Pulling from library/tesseract
846c0b181fff: Already exists 
b826d099326f: Pull complete 
6c4d48fea110: Pull complete 
a91c3cb5df5c: Pull complete 
f87ad742ce15: Pull complete 
d4a41703f6bb: Pull complete 
8a2c5dd1ab87: Pull complete 
e2079de4719f: Pull complete 
Usage:
  tesseract --help | --help-extra | --version
  tesseract --list-langs
  tesseract imagename outputbase [options...] [configfile...]

OCR options:
  -l LANG[+LANG]        Specify language(s) used for OCR.
NOTE: These options must occur before any configfile.

Single options:
  --help                Show this help message.
  --help-extra          Show extra help for advanced users.
  --version             Show version information.
  --list-langs          List available languages for tesseract engine.

Assuming the image does not exist locally, it will be pulled and used as shown above.

If you want to remove the trow deployment, use the command:

helm uninstall trow

Books For Learning Kubernetes Administration:

Conclusion

That marks the end of this guide on how to install and use Trow Container Image Registry With Kubernetes. You now have secure storage for your container images. I hope this was significant.

Relates posts:

Dominic Rubhabha-Wardslaus
Dominic Rubhabha-Wardslaushttp://wardslaus.com
infosec,malicious & dos attacks generator, boot rom exploit philanthropist , wild hacker , game developer,
RELATED ARTICLES

Most Popular

Recent Comments