Skip to content

Instantly share code, notes, and snippets.

@zakame
Created March 25, 2026 21:24
Show Gist options
  • Select an option

  • Save zakame/16c32f5c3a82d1d380249d911ccd0d61 to your computer and use it in GitHub Desktop.

Select an option

Save zakame/16c32f5c3a82d1d380249d911ccd0d61 to your computer and use it in GitHub Desktop.
k3s-prune-images.pl - Manually prune unused container images in k3s
#!/usr/bin/env perl
use 5.024;
use strict;
use warnings;
use Pod::Usage qw(pod2usage);
if ("@ARGV" =~ /--help/) {
pod2usage(-exitstatus => 0, -verbose => 1);
}
my $prune = shift(@ARGV) // '';
my %store;
ALL_IMAGES: {
# ref: k3s crictl images | tail -n +2 | awk '{print $1 ":" $2}' | sort | uniq
open my $in, '-|', qw(/usr/local/bin/k3s crictl images)
or die "Cannot get list of container images: $!\n";
while (<$in>) {
next if /^IMAGE/; # skip header
chomp;
my ($repo, $tag, $id) = split /\s+/;
$store{$repo}{$tag} = [$id, 0]; # [image_id, used_count]
}
}
USED_IMAGES: {
# ref: k3s crictl ps -a -r | tail -n +2 | awk '{print $2}' | sort | uniq
open my $used, '-|', qw(/usr/local/bin/k3s crictl ps -a -r)
or die "Cannot get list of *used* container images: $!\n";
while (<$used>) {
next if /^IMAGE/; # skip header
chomp;
my (undef, $img) = split /\s+/;
my ($repo, $tag) = split /:/, $img;
$store{$repo}{$tag}[1]++ if $tag;
}
}
for my $repo (sort keys %store) {
next if $repo =~ /pause/;
for my $tag (sort keys $store{$repo}->%*) {
next if $store{$repo}{$tag}[1] > 0;
my $img = "$repo:$tag";
say "Prunable: $img ($store{$repo}{$tag}[0])";
if ($prune eq '--yes') {
system(qq(/usr/local/bin/k3s crictl rmi $store{$repo}{$tag}[0])) == 0
or die "Cannot prune: $?\n";
}
}
}
__END__
=head1 NAME
k3s-prune-images.pl - Manually prune unused container images in k3s
=head1 SYNOPSIS
k3s-prune-images.pl [--yes]
k3s-prune-images.pl --help
=head1 DESCRIPTION
This script scans the local container image registry used by k3s to identify
images that are currently not attached to any running or stopped containers.
It lists these unused images and provides an option to automatically remove
them to free up disk space.
The script uses C<crictl> via the k3s wrapper to inspect image status and
container associations.
=head1 OPTIONS
=over 4
=item B<--yes>
When this flag is provided, the script will automatically remove (prune)
the identified unused images after listing them. Without this flag, the
script operates in "dry-run" mode, displaying only the list of prunable
images.
=item B<--help>
Display this help message and exit.
=back
=head1 EXAMPLES
To preview which images will be pruned:
./k3s-prune-images.pl
To actually remove the unused images:
./k3s-prune-images.pl --yes
=head1 EXIT CODES
=over 4
=item 0
Success.
=item 1
An error occurred while retrieving image lists or during the removal process.
=back
=head1 SEE ALSO
=over 4
=item * C<k3s crictl images>
=item * C<k3s crictl ps>
=back
=head1 AUTHOR
Zak B. Elep <zakame@zakame.net>
=head1 LICENSE
MIT License
Copyright (c) 2026 Zak B. Elep
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=cut
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment