Skip to content

appuio/seiso

Repository files navigation

Seiso

Inspired by Robert C. Martin's book, Clean Code, foreword, page xx:

Seisō (清掃), Japanese for “cleaning” (think “shine” in English): Keep the workplace free of hanging wires, grease, scraps, and waste.

Clean up your container registry and Kubernetes resources

Seiso is a CLI client that helps you clean up container resources.

  • Unused images in your container registry (identified by Image Stream Tags in an Image Stream in OpenShift)

  • Superfluous ConfigMaps in your Kubernetes cluster (e.g. generated by the Kustomize configMapGenerator)

  • Superfluous Secret objects in your Kubernetes cluster (e.g. generated by the Kustomize secretGenerator)

  • Empty Namespaces in your Kubernetes cluster.

Kubernetes version support

Seiso >= 1.0 only supports Kubernetes >= 1.18

Usage

seiso --help
seiso image --help
seiso image history --help
seiso image orphans --help
seiso configmaps --help
seiso secrets --help
seiso namespaces --help

Why should I use this tool?

Seiso is intended to be used in application lifecycle management on application container platforms and with automatic deployment processes (CI/CD pipelines).

Kubernetes distributions and tools allow you to easily create or add new resources that allow sophisticated, well-designed deployment processes. For example, you may want to tag every application container image you build with the Git commit SHA-1 hash corresponding to the revision in source control that it was built from. You may use Kustomize to generate ConfigMap and Secret objects for your Kubernetes deployment using the configMapGenerator or secretGenerator feature, which creates a history of rolled out configurations that provides you with both a configuration audit trail and a safe way to roll back application states.

While this is all convenient, those features were designed to create resources but not to clean them up again. As a result, those resources will pile up, incur additional cost for storage, cause confusion, or on (shared) application container environments you may hit a quota limit after a while.

The ImageStream "application" is invalid: []: Internal error: ImageStream.image.openshift.io "application" is forbidden:
 requested usage of openshift.io/image-tags exceeds the maximum limit per openshift.io/ImageStream (51 > 50)

How does it work?

Seiso uses different strategies to identify resources to be cleaned up.

  1. It analyzes a Git repository and compares its history with the target image registry, removing old and unused image tags according to customizable rules.

  2. It can be used more aggressively by deleting dangling image tags, "orphans", that happen to exist when the Git history is altered (e.g. by force-pushing).

  3. It can identify ConfigMap resources by labels that are sufficiently old to be deleted.

  4. It can identify Secret resources by labels that are sufficiently old to be deleted.

Seiso is opinionated, e.g. with respect to naming conventions of image tags, either by relying on a long Git SHA-1 value (namespace/app:a3d0df2c5060b87650df6a94a0a9600510303003) or a Git tag following semantic versioning (namespace/app:v1.2.3).

The cleanup runs in dry-mode by default. Only when the --delete flag is specified, it will actually delete the identified resources. This should prevent accidental deletions during verifications or test runs.

Caveats and known issues

  • Currently, only OpenShift image registries are supported.

  • Please watch out for shallow clones, as the Git history might be missing, it would in some cases also undesirably delete image tags.

Usage Imagestream

The following examples assume the namespace namespace, and image stream named app. For the image cleanup to work, you need to be logged in to the target cluster, as the tool will indirectly read your kubeconfig file.

For the following examples, we will assume the following Git history, with c6 being the latest commit in branch c:

a1
a2
- b3
- b4
a5
- c6

In all cases, it is assumed that the Git repository is already checked out in the desired branch.

Example: Keep the latest 2 image tags

Let's assume target branch is a:

seiso images history -n namespace app --keep 2

or, alternatively

seiso images history namespace/app --keep 2

Only the image tag a1 would be deleted (only current branch is compared).

Example: Keep no image tags

seiso images history namespace/app --keep 0

This would delete a1 and a2, but not a5, as this image is being actively used by a Pod.

Example: Delete orphaned images

seiso images orphans -n namespace app --older-than 7d

or, alternatively

seiso images orphans namespace/app --older-than 7d

This would delete a1, a2, b3 and b4, if we assume that a5 is being actively used, and c6 is younger than 7d (image tag push date, not commit date).

That means it will also look in other branches too. It also deletes amended/force-pushed commits, which do not show up in the history anymore, but would still be available in the registry.

This is very useful in cases where the images from feature branches are being pushed to a dev namespace, but need to be cleaned up after some time. In the production namespace, we can apply different cleanup rules.

Example: Delete versioned image tags

Let's assume we have image tagged according to semver:

v1.9.3
v1.10.0
v1.10.1
seiso images history namespace/app --keep 2 --tags

This would delete v1.9.3 as expected, since the --sort flag is version by default (including support for v prefix). If alphabetic, the order for semver tags is reversed (probably undesired). For date-based tags, alphabetic sorting flag might be better suitable, e.g. 2020-03-17.

Usage ConfigMaps and Secrets

The following examples assume the namespace namespace. For the seiso to work, you need to be logged in to the target cluster, as the tool will indirectly read your kubeconfig file.

For below examples, we will assume the following ConfigMaps and Secrets defined in the cluster.

ConfigMaps:
 - Name: C1
   Labels: app=example,env=production
   Used: yes
   Age: 1m
 - Name: C2
   Labels: app=example,env=staging
   Used: no
   Age: 2m
 - Name: C3
   Labels: app=example
   Used: no
   Age: 1d
 - Name: C4
   Labels: app=example
   Used: no
   Age: 1w

Secrets
 - Name: S1
   Labels: app=example,env=prod,config=default
   Used: no
   Age: 1w
 - Name: S2
   Labels: app=example,env=staging,config=default
   Used: no
   Age: 1w

Example: Delete unused ConfigMaps

seiso configmaps -n mynamespace -l app=example --keep 1 --older-than=1d

This would delete unused ConfigMaps older than 5 hours, from the second element (sorted in descending order) and that have label app=example, more precisely C4.

Example: Delete unused Secrets

seiso secrets -n mynamespace -l app=example -l config=default --keep 0 --older-than=2w

This would delete secrets older than 2 weeks with labels app=example and config=default, more precisely S1 and S2.

Migrate from legacy cleanup plugin

Projects using the legacy oc cleanup plugin can be migrated to seiso as follows

oc -n "$OPENSHIFT_PROJECT" plugin cleanup "$APP_NAME" -p "$PWD" -f=y

becomes:

seiso -n "$OPENSHIFT_PROJECT" image history "$APP_NAME" --delete

We suggest cleaning up orphan image tags in addition, e.g.

seiso -n "$OPENSHIFT_PROJECT" image orphans "$APP_NAME" --delete --older-than 1w

Development

Requirements:

  • go
  • goreleaser
  • Docker

Run code during development:

go run main.go

Reformat all Go code:

make fmt

Run test suite:

make test

Build seiso binary:

make clean build

Build binaries for all target distributions:

make clean dist

Run seiso using its container image:

docker run --rm -it appuio/seiso:<tag>

Release

Push a git tag with the scheme vX.Y.Z (semver).

Environment variables

All CLI flags can be specified also with Environment variables. Just replace dashes with underscore and capitalize the name, e.g.

export KEEP=4
seiso images history namespace/app