Automatically change registry in pod definition

Page content

In this post I will show you how you can automatically change the registry part in deployed pods in Kubernetes.

Parts of the K8S Security Lab series

Container Runetime Security
Advanced Kernel Security
Network Security
Secure Kubernetes Install
User Security
Image Security
  • Part1: Image security Admission Controller
  • Part2: Image security Admission Controller V2
  • Part3: Image security Admission Controller V3
  • Part4: Continuous Image security
  • Part5: trivy-operator 1.0
  • Part6: trivy-operator 2.1: Trivy-operator is now an Admisssion controller too!!!
  • Part7: trivy-operator 2.2: Patch release for Admisssion controller
  • Part8: trivy-operator 2.3: Patch release for Admisssion controller
  • Part8: trivy-operator 2.4: Patch release for Admisssion controller
  • Part8: trivy-operator 2.5: Patch release for Admisssion controller
  • Part9_ Image Signature Verification with Connaisseur
  • Part10: Image Signature Verification with Connaisseur 2.0
  • Part11: Image Signature Verification with Kyverno
  • Part12: How to use imagePullSecrets cluster-wide??
  • Part13: Automatically change registry in pod definition
  • Part14: ArgoCD auto image updater
    Pod Security
    Secret Security
    Monitoring and Observability
    Backup

    ImageSwap Mutating Admission Controller for Kubernetes

    The ImageSwap webhook enables you to define one or more mappings to automatically swap image definitions within Kubernetes Pods with a different registry.

    Install ImageSwap:

    $ kubectl apply -f https://raw.githubusercontent.com/phenixblue/imageswap-webhook/v1.4.2/deploy/install.yaml
    

    For swapping configuration ImageSwap use a configmap to define what image should change to what:

    apiVersion: v1
    data:
      maps: |
        default:registry.example.com
        #gcr.io: # This is a comment
        gitlab.com:registry.example.com/gitlab
        noswap_wildcards:example.com    
    kind: ConfigMap
    metadata:
      creationTimestamp: null
      name: imageswap-maps
      namespace: imageswap-system
    

    Example MAPS Configs:

    Disable image swapping for all registries EXCEPT gcr.io

    default:
    gcr.io:harbor.internal.example.com
    

    Enable image swapping for all registries except gcr.io

    With this, all images will be swapped except those that already match the harbor.internal.example.com pattern

    default:harbor.internal.example.com
    noswap_wildcards:harbor.internal.example.com
    

    Test ImageSwap

    $ kubectl create ns test1
    $ kubectl label ns test1 k8s.twr.io/imageswap=enabled
    

    Then deploy a pod:

    kubectl create deployment unsigned-my \
    --image=docker.io/devopstales/testimage:unsigned
    

    ImageSwap can be disabled on a per workload level by adding the k8s.twr.io/imageswap label with a value of disabled to the pod template.

    Kyverno

    Here is an example of a Kyverno policy that validates that images are only pulled from an allowed list of image registries (based on wildcard patterns):

    apiVersion : kyverno.io/v1alpha1
    kind: Policy
    metadata:
      name: check-registries
    spec:
      rules:
      - name: check-registries
        resource:
          kinds:
          - Deployment
          - StatefulSet
        validate:
          message: "Registry is not allowed"
          pattern:
            spec:
              template:
                spec:
                  containers:
                  - name: "*"
                    # Check allowed registries
                    image: "*/nirmata/* | https://private.registry.io/*"
    

    Rather than blocking Pods which come from outside registries, it is also possible to mutate them so the pulls are directed to approved registries.

    apiVersion: kyverno.io/v1
    kind: ClusterPolicy
    metadata:
      name: replace-image-registry
      annotations:
        policies.kyverno.io/title: Replace Image Registry
        policies.kyverno.io/category: Sample
        policies.kyverno.io/severity: medium
        policies.kyverno.io/subject: Pod
        policies.kyverno.io/minversion: 1.3.6
        policies.kyverno.io/description: >-
          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 policy mutates all images either
          in the form 'image:tag' or 'registry.corp.com/image:tag' to be prefaced
          with `myregistry.corp.com/`.            
    spec:
      background: false
      rules:
        - name: replace-image-registry
          match:
            resources:
              kinds:
              - Pod
          mutate:
            patchStrategicMerge:
              spec:
                containers:
                - (name): "*"
                  image: |-
                                                                    {{ regex_replace_all('^[^/]+', '{{@}}', 'myregistry.corp.com') }}