From f59f8859dc1a63cf92f1dab5434d691841fb743f Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Tue, 7 Apr 2026 16:09:25 -0700 Subject: [PATCH] Localize kube-state-metrics container (Dockerfile + nix) (#327) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary - Build kube-state-metrics v2.18.0 locally from forge mirror, replacing upstream `registry.k8s.io` image - Dockerfile (two-stage Go build) for indri/minikube - default.nix (buildGoModule + buildLayeredImage) for ringtail/k3s - Both kustomization files updated with `newName` pointing to local registry ## Verification - [x] Nix build succeeded on ringtail (`nix-build` → 10-layer image) - [x] Dockerfile build succeeded locally (`dagger call build` → ~2min) - [x] `container-version-check --all-files` passes (2.18.0 consistent across Dockerfile, nix, service-versions.yaml) - [ ] CI builds container images from this branch - [ ] Update kustomization `newTag` with SHA-tagged version from CI - [ ] ArgoCD sync on both clusters ## Test plan - Trigger CI build: `mise run container-build-and-release kube-state-metrics` - Verify tags: `mise run container-list kube-state-metrics` - Update newTag in kustomization files with CI-produced tag - Sync ArgoCD on indri: `argocd app sync kube-state-metrics` - Sync ArgoCD on ringtail: `argocd app sync kube-state-metrics --context=k3s-ringtail` (note: argocd uses its own auth, not kubectl context) - Verify metrics still flowing to Prometheus Reviewed-on: https://forge.eblu.me/eblume/blumeops/pulls/327 --- .../kustomization.yaml | 3 +- .../kube-state-metrics/kustomization.yaml | 3 +- containers/kube-state-metrics/Dockerfile | 44 ++++++++++++++ containers/kube-state-metrics/default.nix | 59 +++++++++++++++++++ .../localize-kube-state-metrics.infra.md | 1 + 5 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 containers/kube-state-metrics/Dockerfile create mode 100644 containers/kube-state-metrics/default.nix create mode 100644 docs/changelog.d/localize-kube-state-metrics.infra.md diff --git a/argocd/manifests/kube-state-metrics-ringtail/kustomization.yaml b/argocd/manifests/kube-state-metrics-ringtail/kustomization.yaml index 005cba8..7717ed1 100644 --- a/argocd/manifests/kube-state-metrics-ringtail/kustomization.yaml +++ b/argocd/manifests/kube-state-metrics-ringtail/kustomization.yaml @@ -6,4 +6,5 @@ resources: - service.yaml images: - name: registry.k8s.io/kube-state-metrics/kube-state-metrics - newTag: v2.18.0 + newName: registry.ops.eblu.me/blumeops/kube-state-metrics + newTag: v2.18.0-e2e35cc-nix diff --git a/argocd/manifests/kube-state-metrics/kustomization.yaml b/argocd/manifests/kube-state-metrics/kustomization.yaml index 005cba8..c370239 100644 --- a/argocd/manifests/kube-state-metrics/kustomization.yaml +++ b/argocd/manifests/kube-state-metrics/kustomization.yaml @@ -6,4 +6,5 @@ resources: - service.yaml images: - name: registry.k8s.io/kube-state-metrics/kube-state-metrics - newTag: v2.18.0 + newName: registry.ops.eblu.me/blumeops/kube-state-metrics + newTag: v2.18.0-e2e35cc diff --git a/containers/kube-state-metrics/Dockerfile b/containers/kube-state-metrics/Dockerfile new file mode 100644 index 0000000..ebaf8e6 --- /dev/null +++ b/containers/kube-state-metrics/Dockerfile @@ -0,0 +1,44 @@ +# kube-state-metrics — Kubernetes state metrics exporter +# Two-stage build: Go binary, Alpine runtime + +ARG CONTAINER_APP_VERSION=2.18.0 +ARG KSM_VERSION=v${CONTAINER_APP_VERSION} +ARG KSM_COMMIT=ab562f78ebf4cb97cc2f87c1235e457076035d16 + +FROM golang:alpine3.22 AS build + +ARG KSM_VERSION +ARG KSM_COMMIT +RUN apk add --no-cache build-base git + +RUN mkdir /app && cd /app \ + && git init \ + && git remote add origin https://forge.ops.eblu.me/mirrors/kube-state-metrics.git \ + && git fetch --depth 1 origin ${KSM_COMMIT} \ + && git checkout FETCH_HEAD + +WORKDIR /app + +ENV CGO_ENABLED=0 + +RUN go build \ + -o /kube-state-metrics \ + -ldflags "-s -w -X k8s.io/kube-state-metrics/v2/pkg/version.Version=${KSM_VERSION}" + +FROM alpine:3.22 + +ARG CONTAINER_APP_VERSION +LABEL org.opencontainers.image.title="kube-state-metrics" +LABEL org.opencontainers.image.description="Generates metrics about the state of Kubernetes objects" +LABEL org.opencontainers.image.version="${CONTAINER_APP_VERSION}" +LABEL org.opencontainers.image.source="https://forge.eblu.me/eblume/blumeops" +LABEL org.opencontainers.image.vendor="blumeops" + +RUN apk --no-cache add ca-certificates tzdata + +COPY --from=build /kube-state-metrics /usr/bin/kube-state-metrics + +EXPOSE 8080 8081 + +USER 65534 +ENTRYPOINT ["/usr/bin/kube-state-metrics"] diff --git a/containers/kube-state-metrics/default.nix b/containers/kube-state-metrics/default.nix new file mode 100644 index 0000000..bd83db5 --- /dev/null +++ b/containers/kube-state-metrics/default.nix @@ -0,0 +1,59 @@ +# Nix-built kube-state-metrics +# Builds v2.18.0 from forge mirror +# Built with dockerTools.buildLayeredImage for efficient layer caching +{ pkgs ? import { } }: + +let + version = "2.18.0"; + + src = pkgs.fetchgit { + url = "https://forge.ops.eblu.me/mirrors/kube-state-metrics.git"; + rev = "v${version}"; + hash = "sha256-oLkIjc6VC3hTrFg9LmgSUtwt4ek0dT7h2u2DfNRx5Gg="; + }; + + kube-state-metrics = pkgs.buildGoModule { + inherit src version; + pname = "kube-state-metrics"; + vendorHash = "sha256-ccP34lywpQnIx3R5IyGURuvb4ijNfCu2VVAeVjBrN0w="; + + doCheck = false; + + subPackages = [ "." ]; + + ldflags = [ + "-s" + "-w" + "-X k8s.io/kube-state-metrics/v2/pkg/version.Version=v${version}" + ]; + + meta = with pkgs.lib; { + description = "Generates metrics about the state of Kubernetes objects"; + homepage = "https://github.com/kubernetes/kube-state-metrics"; + license = licenses.asl20; + mainProgram = "kube-state-metrics"; + }; + }; +in + +pkgs.dockerTools.buildLayeredImage { + name = "blumeops/kube-state-metrics"; + contents = [ + kube-state-metrics + pkgs.cacert + pkgs.tzdata + ]; + + config = { + Entrypoint = [ "${kube-state-metrics}/bin/kube-state-metrics" ]; + Env = [ + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "TZDIR=${pkgs.tzdata}/share/zoneinfo" + ]; + ExposedPorts = { + "8080/tcp" = { }; + "8081/tcp" = { }; + }; + User = "65534"; + }; +} diff --git a/docs/changelog.d/localize-kube-state-metrics.infra.md b/docs/changelog.d/localize-kube-state-metrics.infra.md new file mode 100644 index 0000000..f6a709a --- /dev/null +++ b/docs/changelog.d/localize-kube-state-metrics.infra.md @@ -0,0 +1 @@ +Build kube-state-metrics container locally (Dockerfile + nix) from forge mirror, replacing upstream registry.k8s.io image on both indri and ringtail.