Skip to content

Kubernetes Admission Webhook to enforce pulling of Docker images from the private registry.

License

Notifications You must be signed in to change notification settings

jainishshah17/tugger

Repository files navigation

Tugger

What does Tugger do?

Tugger is Kubernetes Admission webhook to enforce pulling of docker images from private registry.

Prerequisites

Kubernetes 1.9.0 or above with the admissionregistration.k8s.io/v1 API enabled. Verify that by the following command:

kubectl api-versions | grep admissionregistration.k8s.io/v1beta1

The result should be:

admissionregistration.k8s.io/v1beta1

In addition, the MutatingAdmissionWebhook and ValidatingAdmissionWebhook admission controllers should be added and listed in the correct order in the admission-control flag of kube-apiserver.

Build and Push Tugger Docker Image

# Build docker image
docker build -t jainishshah17/tugger:0.1.8 .

# Push it to Docker Registry
docker push jainishshah17/tugger:0.1.8
# Create a Docker registry secret called 'regsecret'
kubectl create secret docker-registry regsecret --docker-server=${DOCKER_REGISTRY} --docker-username=${DOCKER_USER} --docker-password=${DOCKER_PASS} --docker-email=${DOCKER_EMAIL}

Note: Create Docker registry secret in each non-whitelisted namespaces.

Generate TLS Certs for Tugger

./tls/gen-cert.sh

Get CA Bundle

./webhook/webhook-patch-ca-bundle.sh

Deploy Tugger to Kubernetes

Deploy using Helm Chart

The helm chart can generate certificates and configure webhooks in a single step. See the notes on webhooks below for more information.

# Add Tugger Helm repository
helm repo add tugger https://jainishshah17.github.io/tugger

# Update Helm repository index
helm repo update
helm install --name tugger \
  --set docker.registrySecret=regsecret, \
  --set docker.registryUrl=jainishshah17, \
  --set whitelistNamespaces={kube-system,default}, \
  --set whitelistRegistries={jainishshah17} \
  --set createValidatingWebhook=true \
  --set createMutatingWebhook=true \
  tugger/tugger

Deploy using kubectl

  1. Create deployment and service

    # Run deployment
    kubectl create -f deployment/tugger-deployment.yaml
    
    # Create service
    kubectl create -f  deployment/tugger-svc.yaml
  2. Configure MutatingAdmissionWebhook and ValidatingAdmissionWebhook

    Note: Replace ${CA_BUNDLE} with value generated by running ./webhook/webhook-patch-ca-bundle.sh

    # re MutatingAdmissionWebhook
    kubectl create -f webhook/tugger-mutating-webhook ration.yaml

    Note: Use MutatingAdmissionWebhook only if you want to enforce pulling of docker image from Private Docker Registry e.g JFrog Artifactory. If your container image is nginx then Tugger will append REGISTRY_URL to it. e.g nginx will become jainishshah17/nginx

    # Configure ValidatingWebhookConfiguration
    kubectl create -f webhook/tugger-validating-webhook ration.yaml

    Note: Use ValidatingWebhookConfiguration only if you want to check pulling of docker image from Private Docker Registry e.g JFrog Artifactory. If your container image does not contain REGISTRY_URL then Tugger will deny request to run that pod.

Test Tugger

# Deploy nginx
kubectl apply -f test/nginx.yaml

Configure

The mutation or validation policy can be defined as a list of rules in a YAML file.

The YALM file can be specified with the command line argument --policy-file=FILE, or when using the Helm chart, populate rules: in values.

Schema

rules:
- pattern: regex
  replacement: template (optional)
  condition: policy (optional)
- ...

pattern is a regex pattern

replacement is a template comprised of the captured groups to use to generate the new image name in the mutating admission controller. When replacement is null or undefined, the image name is allowed without patching. Rules with this field are ignored by the validating admission controller, where mutation is not supported.

condition is a special condition to test before committing the replacement. Initially Always and Exists will be supported. Always is the default and performs the replacement regardless of any condition. Exists implements the behavior from #7; it only rewrites the image name if the target name exists in the remote registry.

Each rule will be evaluated in order, and if the list is exhausted without a match, the admission controller will return allowed: false.

Examples

This example allows all images without rewriting:

rules:
- pattern: .*

This example implements the default behavior of rewriting all image names to start with jainishshah17:

rules:
- pattern: ^jainishshah17/.*
- pattern: (.*)
  replacement: jainishshah17/$1

Or the same thing, but only if the image exists in jainishshah17/, and allowing all other images:

rules:
- pattern: ^jainishshah17/.*
- pattern: (.*)
  replacement: jainishshah17/$1
  condition: Exists
- pattern: .*

Allow the nginx image, but rewrite everything else:

rules:
- pattern: ^nginx(:.*)?$
- pattern: (?:jainishshah17)?(.*)
  replacement: jainishshah17/$1