Search code examples
dockernexusdocker-registry

How to pull images from private docker registry only?


is there a way to only pull images from a private registry and blocking pulling images from the public registry, docker hub?

I'm using a Nexus registry that I was able to configure and pull images from. I'm trying to implement a way of only push images from my private registry so I can track what docker images I'm using and after that, apply some security analysis in that. But I can still pull images from docker hub in my computer. Is there a way to block that?


Solution

  • There are different ways, how you can do it.

    I assume here you are using Kubernetes:

    1. Use an admission controller on the cluster that rewrite Pod spec to your internal registry
    2. Container Runtimes have nowadays options to restrict registries, cri-o and containerd have this option.

    If you are using something like CNCF Harbor [1], [2] you can create proxies for 3rd party registries and then user Kyverno to rewrite the Pod spec.

    Replace Image Registry with Kyverno

    Rather than blocking Pods which come from outside registries, it is also possible to mutate them, so the pulls are directed to approved registries. In some cases, those registries may function as pull-through proxies and can fetch the image if not cached. This policy mutates all images either in the form 'image:tag' or 'example.container-registry.com/image:tag' to be myregistry.corp.com/. Any path in the image name will be preserved. Note that this mutates Pods directly and not their controllers. It can be changed if desired, but if so, may need not match on Pods.

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: replace-image-registries
    spec:
      background: false
      rules:
        # We only allow a known set of approved registries to be used in our clusters
        - name: validate-registries
          match:
            resources:
              kinds:
              - Pod
          validate:
            message: "Unapproved image registry."
            pattern:
              spec:
                containers:
                - image: "example.container-registry.com/* | quay.io/* | gcr.io/* | ghcr.io/* | docker.io/*"
    
        # Rewrite all the references for our approved external registries
        - name: replace-registries
          match:
            resources:
              kinds:
              - Pod
          mutate:
            patchStrategicMerge:
              spec:
                containers:
                - (name): "*"
                  image: |-
                    {{ regex_replace_all('(quay.io|gcr.io|ghcr.io|docker.io)/(.*)', '{{@}}', 'example.container-registry.com/$1/$2') }}
    
        # At this point we expect everything that has a registry prefix to have been transformed
        # example.container-registry.com.*. We are left with references like:
        #
        # - velero/velero:v1.6.2
        # - nginx:latest
        # - nginx
        #
        # Without interfering with our newly rewritten references that start with example.container-registry.com
        - name: replace-docker
          match:
            resources:
              kinds:
              - Pod
          mutate:
            patchStrategicMerge:
              spec:
                containers:
                - (name): "*"
                  image: |-
                    {{ regex_replace_all('^([^example.container-registry.com].*)', '{{@}}', 'example.container-registry.com/docker.io/$1') }}
    
    

    This repo here has some examples: https://github.com/jvanzyl/kyverno-registries