Post

Container stuff

Container stuff

Crane

crane docs and recipes

List tags available

1
2
3
4
5
6
7
8
9
10
11
12
function img-tags {
    if [ "${1}" = "-h" ]; then
        echo "Usage: imgtags cgr.dev/reponame/imagename]"
        echo "List tags for an OCI-compliant image, omitting digests, using crane."
        return
    fi
    if [ "${1}" = "" ]; then
        echo "Image name required."
        return
    fi
    crane ls ${1} --omit-digest-tags
}

Docker

Clean up all the things

The “nuke it from orbit” approach that removes all stopped containers, dangling images, build cache, and volumes. I use this one a lot.

1
2
3
4
5
6
7
8
9
10
11
function docker-cleanup {
  if [ "${1}" = "-h" ]; then
    echo "Usage: docker-cleanup"
    echo "Remove all stopped containers and dangling images, build cache, volumes, and more."
    return
  fi
  # remove all stopped containers, networks, images
  docker system prune -af
  # remove all unused volumes, not just anonymous ones
  docker volume prune -af
}

Return size in human-readable format

1
2
3
4
5
6
7
8
9
10
11
12
function docker-size {
  if [ "${1}" = "-h" ]; then
    echo "Usage: docker-size [image]"
    echo "Inspect the size of a Docker image and return it in human-readable format."
    return
  fi
  if [ "${1}" = "" ]; then
    echo "Image name required."
    return
  fi
  docker inspect -f "{{ .Size }}" ${1} | numfmt --to=si
}

Return a list of architectures for a multi-arch image

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function docker-arch {
  if [ "${1}" = "-h" ]; then
    echo "Usage: docker-arch [image]"
    echo "List the architectures for a multi-arch image."
    return
  fi
  if [ "${1}" = "" ]; then
    echo "Image name required."
    return
  fi
  docker manifest inspect ${1} |\
    jq -r '.manifests[].platform | select(.os != "unknown" and .architecture != "unknown") | "\(.os)-\(.architecture)"' |\
    sort |\
    uniq
}

Grype

Summarize Grype results

This prints out a markdown table to copy/paste into another system.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function grype-summary () {
  if [ "${1}" = "-h" ]; then
    echo "Usage: grype-summary [path]"
    echo "Summarize vulnerabilities found by Grype."
    return
  fi
  if [ "${1}" = "" ]; then
    echo "Path or image name required."
    return
  fi
  grype ${1} -o json --file grype.json -q
  echo "Total = $(cat grype.json | jq  '.matches[].vulnerability.severity' | uniq -c | awk '{sum += $1} END {print sum}')"
  echo ""
  echo "| Count | Severity    |"
  echo "|-------|-------------|"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'Critical') "critical"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'High') "high"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'Medium') "medium"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'Low') "low"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'Negligible') "negligible"
  printf "| %-5s | %-11s |\n" $(cat grype.json | jq  '.matches[].vulnerability.severity' | grep -c 'Unknown') "unknown"
  rm grype.json
}

Outputs something like this:

1
2
3
4
5
6
7
8
9
10
Total = 558

| Count | Severity    |
|-------|-------------|
| 38    | critical    |
| 170   | high        |
| 298   | medium      |
| 43    | low         |
| 0     | negligible  |
| 9     | unknown     |

Multi-image Grype summarization

I wrote a Python script that takes a newline-delimited text file to summarize multiple Grype results into a pretty console table.

1
2
3
4
5
6
7
8
9
10
11
ᐅ ./grype-table.py test-list.txt
Analyzing nginx:1...
Analyzing registry.access.redhat.com/ubi9/ubi-init:9.3...
Analyzing cgr.dev/chainguard-private/nginx-fips:1...
+----------------------------------------------+----------+------+--------+-----+------------+---------+
|                    Image                     | Critical | High | Medium | Low | Negligible | Unknown |
+----------------------------------------------+----------+------+--------+-----+------------+---------+
|                   nginx:1                    |    2     |  14  |   34   |  4  |     72     |   20    |
| registry.access.redhat.com/ubi9/ubi-init:9.3 |    0     |  1   |   32   | 143 |     0      |    4    |
|   cgr.dev/chainguard-private/nginx-fips:1    |    0     |  0   |   0    |  0  |     0      |    0    |
+----------------------------------------------+----------+------+--------+-----+------------+---------+

To make life easier, it’s symlinked into /usr/local/bin.


Helm

helm docs

List unique images

1
2
3
4
5
6
7
8
9
10
11
12
function helm-ls-images {
  if [ "${1}" = "-h" ]; then
    echo "Usage: helm-images [chart]"
    echo "List of unique images used in Helm chart."
    return
  fi
  if [ "${1}" = "" ]; then
    echo "Chart name required."
    return
  fi
  helm template "${1}" | grep -oE 'image: .+' | cut -d' ' -f2 | sort | uniq | tr -d '"'
}

Kubectl

Export a specific context

1
kubectl config view --minify --flatten --raw --context=CONTEXTNAME

List all images running in a cluster

Does exactly what the title says it does. I usually redirect output into a text file, then run the Python script above on it for a quick table of vulnerability count by images in a cluster.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function k-ls-images {
  if [ "${1}" = "-h" ]; then
    echo "Usage: k-ls-images"
    echo "List all images running in a cluster, using the current context."
    return
  fi
  if [ "${1}" = "-c" ]; then
    echo "Returning count of pods running each image as well."
    echo " ... any `uniq` arguments work here ... "
  fi
  kubectl get pods --all-namespaces \
    -o jsonpath="{.items[*].spec['initContainers', 'containers'][*].image}" |\
  tr -s '[[:space:]]' '\n' |\
  sort |\
  uniq ${1}
}
This post is licensed under CC BY 4.0 by the author.