aws-kubectl
AWS CLI v2 + kubectl on Ubuntu 24.04. Multi-arch (amd64/arm64), checksum-verified.
1M+
This image streamlines work with Amazon Web Services (AWS) and Kubernetes by bundling AWS CLI v2 (aws) and kubectl on Ubuntu 24.04. It also includes jq, curl, unzip, and envsubst (from gettext-base). Perfect for CI/CD steps, automation, and reproducible local scripting.
π³ Docker Hub: heyvaldemar/aws-kubectlβ
| Need | This image | amazon/aws-cli | bitnami/kubectl | Alpine + scripts |
|---|---|---|---|---|
| AWS CLI v2 | β | β | β | manual |
| kubectl | β | β | β | manual |
| jq, envsubst, curl, unzip | β | β | β | manual |
| Multi-arch (amd64/arm64) | β | β | β | depends |
| Cosign signatures | β | β | β | β |
| SBOM (SPDX) | β | β | β | β |
| SLSA build provenance | β | β | β | β |
| OpenSSF Scorecard | 7.8/10 | N/A | N/A | N/A |
| Non-root default (UID 10001) | β (v2.0+) | β | β | depends |
| Weekly base rebuild | β | β | β | manual |
One image instead of three. Full supply-chain attestations. OpenShift-compatible out of the box.
docker version. The image ships AWS CLI v2 and kubectl inside, so you don't need either installed on your host. Multi-arch (amd64 + arm64) β works on Linux, macOS (Intel + Apple Silicon), Windows + WSL2.~/.aws/ if you want to run AWS commands. Create with aws configure from any machine that has aws-cli β or copy from an existing setup. The image mounts the dir read-only by convention.kubeconfig in ~/.kube/ if you want to run kubectl commands against an existing cluster. Create with aws eks update-kubeconfig --name <cluster> or your tool of choice.You can also run the container with no mounts for aws --version, kubectl version --client, or any tool that doesn't need cloud/cluster credentials.
# List S3 buckets (requires ~/.aws)
docker run --rm --user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
heyvaldemar/aws-kubectl aws s3 ls
# Get Kubernetes nodes (requires ~/.kube)
docker run --rm --user "$(id -u):0" \
-v ~/.kube:/home/app/.kube \
heyvaldemar/aws-kubectl kubectl get nodes
# Interactive shell with both
docker run -it --user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
-v ~/.kube:/home/app/.kube \
heyvaldemar/aws-kubectl bash
Runs as non-root by default (UID 10001). See Mounting credentialsβ for permission details.
π¨ Existing v1.x user and v2.0 broke your workflow? Pin
heyvaldemar/aws-kubectl:v1-maintenancefor security updates through July 2026. Migration details ββ
For production use, pin to immutable semver tags:
heyvaldemar/aws-kubectl:2.0.0 β immutable on Docker Hub, never purgedheyvaldemar/aws-kubectl:sha-1dfda81 β short-SHA tags are deleted after 90 daysIf you pin by manifest digest (recommended for maximum supply chain integrity), make sure the digest is also referenced by a semver tag. Otherwise the digest may become unpullable once short-SHA cleanup runs. To resolve a tag to its current digest:
docker buildx imagetools inspect heyvaldemar/aws-kubectl:2.0.0 \
--format '{{.Manifest.Digest}}'
jq, curl, unzip, envsubst, and ca-certificates preinstalled.kubectl during build.buildx.org.opencontainers.image.*) on every published image./etc/kube-version inside the image.Default user is non-root (UID 10001, GID 0) as of v2.0. If you need root β e.g. to install additional
aptpackages at runtime β override with--user 0:0. See Breaking Changes in v2.0β for migration details.
curl | bashsha256 digest (ubuntu:24.04@sha256:β¦). Dependabot's docker ecosystem bumps the digest weekly.Dockerfile keeps build-only intermediate artefacts (the downloaded AWS CLI archive, extracted tree, kubectl tarball, and checksum file) out of the published image.kubectl binaries are verified against the upstream sha256 checksum published at dl.k8s.io during build.cron: "0 6 * * 1").hadolint and shell scripts with shellcheck before any build runs.VCS_REF and BUILD_DATE are stamped into org.opencontainers.image.revision and org.opencontainers.image.created, and the resolved kubectl release is exposed via io.heyvaldemar.kubectl.version and /etc/kube-version.provenance: mode=max) are attached to every published image.actions/attest-build-provenance and stored in GitHub Attestationsβ . Registry push is disabled because Docker Hub's OCI referrer credential handoff proved unreliable in early Phase 2 hotfix testing β see CHANGELOGβ [2.0.0] CI section for context.cosign verify heyvaldemar/aws-kubectl:latest \
--certificate-identity-regexp "https://github.com/heyvaldemar/aws-kubectl-docker/.*" \
--certificate-oidc-issuer "https://token.actions.githubusercontent.com"
Tags fall into five categories:
:2.0.0, :v2.0.0) β immutable on Docker Hub; the digest under these tags never changes after first push. Recommended for production pins.:2.0, :2) β mutable; re-targets to the newest patch (and minor) within the major on each release. Kept forever.:latest, :edge, :v1-maintenance) β updated on every main build; kept forever.:kube-v1.36.0) β generated only on semver releases. Tracks the kubectl release packaged into the image at the time of that release. Immutable on Docker Hub; kept forever.:sha-<7char>) β produced by CI for every commit to main. Immutable while live; retained for 90 days, then automatically deleted by the Docker Hub Tag Cleanup workflow.Cosign signatures (:sha256-<digest>.sig) are managed by Sigstore and are not deleted.
Starting with v2.0.0, this image runs as a non-root user (UID 10001, GID 0) by default. This aligns with modern container security best practices and is required for compatibility with OpenShift, restricted Kubernetes PodSecurityPolicy profiles, and enterprise security scanners.
If you use this image for one-off CI commands (aws s3 sync, kubectl apply),
v2.0 works identically to v1.x.
If you mount a host directory or Kubernetes PVC, you may need to adjust file ownership or run the container with a matching UID:
Docker:
docker run --rm -v "$PWD:/home/app" --user "$(id -u):0" \
heyvaldemar/aws-kubectl:latest aws s3 ls
Kubernetes:
spec:
securityContext:
runAsUser: 10001
runAsGroup: 0
fsGroup: 0
If v2.0 breaks your workflow and you need time to migrate, pin to the v1 maintenance track:
docker pull heyvaldemar/aws-kubectl:v1-maintenance
The v1-maintenance tag will receive security updates through July 20, 2026,
after which it will be frozen.
~/.aws β AWS credentials/config (credentials, config). Mount to /home/app/.aws inside the container.~/.kube β kubeconfig(s). Mount to /home/app/.kube inside the container.The container's default user is UID 10001 with
HOME=/home/app. Pass--user "$(id -u):0"when mounting host files so the container can read them.
Interactive shell with both configs (mount under /home/app β the non-root user's HOME β and match your host UID so the container can read the mounted files):
docker run -it \
--user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
-v ~/.kube:/home/app/.kube \
heyvaldemar/aws-kubectl bash
If you pulled an amd64-only tag on an ARM/M-series Mac:
docker run --platform linux/amd64 -it \
--user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
-v ~/.kube:/home/app/.kube \
heyvaldemar/aws-kubectl bash
# List S3 buckets
docker run --rm \
--user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
heyvaldemar/aws-kubectl aws s3 ls
# Get Kubernetes nodes
docker run --rm \
--user "$(id -u):0" \
-v ~/.kube:/home/app/.kube \
heyvaldemar/aws-kubectl kubectl get nodes
The Dockerfile accepts the following build arguments:
| ARG | Default | Purpose |
|---|---|---|
KUBE_VERSION | latest | Pin a specific kubectl release (e.g. v1.30.6). latest fetches the current stable from dl.k8s.io. |
VCS_REF | unknown | Commit SHA, stamped into org.opencontainers.image.revision. |
BUILD_DATE | unknown | ISO-8601 build timestamp, stamped into org.opencontainers.image.created. |
TARGETARCH | auto | Target architecture (amd64/arm64). Supplied automatically by buildx. |
# From the folder with the Dockerfile
docker build -t aws-kubectl:local .
docker build --build-arg KUBE_VERSION=v1.30.6 \
-t aws-kubectl:local .
If KUBE_VERSION is omitted, the build fetches the latest stable from dl.k8s.io.
docker build \
--build-arg KUBE_VERSION=v1.30.6 \
--build-arg VCS_REF="$(git rev-parse HEAD)" \
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
-t aws-kubectl:local .
docker buildx create --name x --use || docker buildx use x
# Generic tag (no OS name in the tag)
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VCS_REF="$(git rev-parse HEAD)" \
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
-t heyvaldemar/aws-kubectl:latest \
--push .
# Or pin kubectl in a tag users can reason about
KUBE_VERSION=v1.30.6
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg KUBE_VERSION=$KUBE_VERSION \
--build-arg VCS_REF="$(git rev-parse HEAD)" \
--build-arg BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')" \
-t heyvaldemar/aws-kubectl:kube-$KUBE_VERSION \
--push .
Verify:
docker buildx imagetools inspect heyvaldemar/aws-kubectl:latest
Optional supply-chain flags (if you want SBOM/provenance):
--sbom=true --provenance=true
This repo includes scripts/smoke-test.sh to validate the tools in the image.
docker build -t aws-kubectl:local .
chmod +x scripts/smoke-test.sh
./scripts/smoke-test.sh # defaults to aws-kubectl:local
./scripts/smoke-test.sh your/tag:dev # test any tag you pass
The script checks:
/etc/kube-version matches kubectl version --clientkubectl cluster calls if you mount ~/.aws / ~/.kubeIMG=aws-kubectl:local
# OS/arch
docker run --rm $IMG sh -lc 'uname -a; echo -n "Arch: "; uname -m'
# Core tools & versions
docker run --rm $IMG aws --version
docker run --rm $IMG kubectl version --client --output=yaml
docker run --rm $IMG jq --version
docker run --rm $IMG envsubst --version
docker run --rm $IMG sh -c 'curl --version | head -n1'
docker run --rm $IMG sh -c 'unzip -v | head -n2'
# Resolved kubectl release stamped at build time
docker run --rm $IMG cat /etc/kube-version
# Binaries present where expected
docker run --rm $IMG sh -c 'ls -l /usr/local/bin/kubectl; for b in aws jq envsubst curl unzip; do command -v "$b"; done'
# CA bundle present + HTTPS sanity
docker run --rm $IMG sh -c 'ls -lh /etc/ssl/certs/ca-certificates.crt'
docker run --rm $IMG sh -c 'curl -fsSI -o /dev/null -w "HTTPS OK (%{http_code})\n" https://kubernetes.io'
# AWS identity (requires valid creds)
docker run --rm --user "$(id -u):0" \
-v ~/.aws:/home/app/.aws \
aws-kubectl:local aws sts get-caller-identity
# Current k8s context & nodes (requires valid kubeconfig)
docker run --rm --user "$(id -u):0" \
-v ~/.kube:/home/app/.kube \
aws-kubectl:local kubectl config current-context
docker run --rm --user "$(id -u):0" \
-v ~/.kube:/home/app/.kube \
aws-kubectl:local kubectl get nodes -o wide
kubectl binaries are checksum-verified during build.--no-install-recommends) and lists are cleaned.KUBE_VERSION in CI for reproducibility.If a specific workflow requires root inside the container (e.g. installing additional apt packages at runtime, or restoring pre-v2.0 behaviour), override the user:
docker run --rm --user 0:0 heyvaldemar/aws-kubectl bash
The patterns in this image are codified as a reusable standard at heyvaldemar/self-host-repo-hardening-runbook β IMAGE-PUBLISHING-RUNBOOK.mdβ . If you maintain a Dockerfile-based repo and want to follow the same standard, the runbook covers:
org.opencontainers.image.*)provenance: mode=max)Six mandatory phases plus an optional non-root migration phase for repos with existing :latest audiences. Eight production-grounded pitfalls drawn from this repo's own PR history.
Maintained by Vladimir Mikhalevβ β Docker Captain Β· IBM Champion Β· AWS Community Builder
YouTubeβ Β· Blogβ Β· LinkedInβ
Content type
Image
Digest
sha256:967ff6ffeβ¦
Size
510 Bytes
Last updated
5 days ago
docker pull heyvaldemar/aws-kubectl:sha256-ddb5c582bb952aa512892711e42e841d182af66a2c69a15ba8093cfbc505f0b9.sig