Skip to content

Instantly share code, notes, and snippets.

@dims
Last active February 11, 2026 19:00
Show Gist options
  • Select an option

  • Save dims/8fdfd022d555525490384eddd6aed611 to your computer and use it in GitHub Desktop.

Select an option

Save dims/8fdfd022d555525490384eddd6aed611 to your computer and use it in GitHub Desktop.
Kubernetes Dependency Analysis (v1.36.0-alpha) -- depstat
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
<svg xmlns="http://www.w3.org/2000/svg" width="500" height="1044" viewBox="0 0 500 1044" font-family="system-ui,-apple-system,sans-serif">
<defs>
<marker id="a" viewBox="0 0 10 6" refX="10" refY="3" markerWidth="8" markerHeight="5" orient="auto-start-reverse">
<path d="M0 0L10 3L0 6z" fill="#888"/>
</marker>
<marker id="ar" viewBox="0 0 10 6" refX="10" refY="3" markerWidth="8" markerHeight="5" orient="auto-start-reverse">
<path d="M0 0L10 3L0 6z" fill="#D32F2F"/>
</marker>
</defs>
<text x="250.0" y="28" text-anchor="middle" font-size="14" font-weight="600" fill="#333">Why is go.opentelemetry.io/otel included?</text>
<text x="250.0" y="46" text-anchor="middle" font-size="11" fill="#888">10 paths, 31 direct dependent(s)</text>
<rect x="16" y="60" width="12" height="12" rx="3" fill="#E8F5E9" stroke="#388E3C" stroke-width="1"/><text x="32" y="66" font-size="11" dominant-baseline="central" fill="#555">Main module</text><rect x="126" y="60" width="12" height="12" rx="3" fill="#E3F2FD" stroke="#1976D2" stroke-width="1"/><text x="142" y="66" font-size="11" dominant-baseline="central" fill="#555">Same org</text><rect x="236" y="60" width="12" height="12" rx="3" fill="#FFF3E0" stroke="#F57C00" stroke-width="1"/><text x="252" y="66" font-size="11" dominant-baseline="central" fill="#555">External</text><rect x="346" y="60" width="12" height="12" rx="3" fill="#FFE0E0" stroke="#D32F2F" stroke-width="1"/><text x="362" y="66" font-size="11" dominant-baseline="central" fill="#555">Target</text>
<path d="M250.0 674.0Q250.0 712.0 250.0 750.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 124.0Q250.0 162.0 250.0 200.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 784.0Q250.0 877.0 250.0 970.0" fill="none" stroke="#D32F2F" stroke-width="2.2" marker-end="url(#ar)"/>
<path d="M250.0 674.0Q250.0 767.0 250.0 860.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)" stroke-dasharray="5,3"/>
<path d="M250.0 894.0Q250.0 932.0 250.0 970.0" fill="none" stroke="#D32F2F" stroke-width="2.2" marker-end="url(#ar)"/>
<path d="M250.0 564.0Q250.0 602.0 250.0 640.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 784.0Q250.0 822.0 250.0 860.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 234.0Q250.0 272.0 250.0 310.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 344.0Q250.0 382.0 250.0 420.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 454.0Q250.0 712.0 250.0 970.0" fill="none" stroke="#D32F2F" stroke-width="2.2" marker-end="url(#ar)"/>
<path d="M250.0 454.0Q250.0 547.0 250.0 640.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)" stroke-dasharray="5,3"/>
<path d="M250.0 674.0Q250.0 822.0 250.0 970.0" fill="none" stroke="#D32F2F" stroke-width="2.2" marker-end="url(#ar)"/>
<path d="M250.0 454.0Q250.0 492.0 250.0 530.0" fill="none" stroke="#888" stroke-width="1.3" marker-end="url(#a)"/>
<path d="M250.0 564.0Q250.0 767.0 250.0 970.0" fill="none" stroke="#D32F2F" stroke-width="2.2" marker-end="url(#ar)"/>
<g><title>github.com/google/cel-go</title><rect x="156.4" y="200.0" width="187.2" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="217.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">github.com/google/cel-go</text></g>
<g><title>go.opentelemetry.io/auto/sdk</title><rect x="142.8" y="750.0" width="214.4" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="767.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">go.opentelemetry.io/auto/sdk</text></g>
<g><title>go.opentelemetry.io/otel</title><rect x="156.4" y="970.0" width="187.2" height="34.0" rx="6" fill="#FFE0E0" stroke="#D32F2F" stroke-width="2"/><text x="250.0" y="987.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#B71C1C">go.opentelemetry.io/otel</text></g>
<g><title>go.opentelemetry.io/otel/metric</title><rect x="132.6" y="640.0" width="234.8" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="657.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">go.opentelemetry.io/otel/metric</text></g>
<g><title>go.opentelemetry.io/otel/sdk</title><rect x="142.8" y="530.0" width="214.4" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="547.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">go.opentelemetry.io/otel/sdk</text></g>
<g><title>go.opentelemetry.io/otel/trace</title><rect x="136.0" y="860.0" width="228.0" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="877.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">go.opentelemetry.io/otel/trace</text></g>
<g><title>google.golang.org/genproto/googleapis/api</title><rect x="112.2" y="310.0" width="275.6" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="327.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">google.golang.org...to/googleapis/api</text></g>
<g><title>google.golang.org/grpc</title><rect x="163.2" y="420.0" width="173.6" height="34.0" rx="6" fill="#FFF3E0" stroke="#F57C00" stroke-width="1.5"/><text x="250.0" y="437.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#E65100">google.golang.org/grpc</text></g>
<g><title>k8s.io/apiextensions-apiserver</title><rect x="136.0" y="90.0" width="228.0" height="34.0" rx="6" fill="#E8F5E9" stroke="#388E3C" stroke-width="2"/><text x="250.0" y="107.0" text-anchor="middle" dominant-baseline="central" font-size="11" fill="#1B5E20">k8s.io/apiextensions-apiserver</text></g>
<text x="250.0" y="1032" text-anchor="middle" font-size="10" fill="#aaa">generated by depstat</text>
</svg>
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

Kubernetes Dependency Analysis

Generated by depstat — a Go dependency analysis tool from kubernetes-sigs. Analysis performed on commit 411c4499fa5 (branch dump-from-utils, based on v1.36.0-alpha.1).


1. Executive Summary

Metric Value
Direct Dependencies 179
Transitive Dependencies 224
Total Dependencies 257
Max Dependency Depth 19
Test-only Dependencies 31
Non-test Dependencies 226
Dependency Cycles 19
Archived Dependencies 6
Main Modules (go.work) 32 (1 root + 31 staging)

Key findings:

  • Kubernetes has a large but well-managed dependency surface — 257 total deps across a 32-module monorepo with staging modules
  • Depth of 19 is the deepest observed across similar projects (etcd: 12, containerd: 11), reflecting the layered architecture
  • All 19 cycles are external — no internal (k8s.io ↔ k8s.io) cycles detected
  • The v1.34.0 → v1.35.0 release saw a net +16 dependencies (+17 added, -1 removed, 69 version bumps)
  • 6 archived dependencies remain, notably github.com/json-iterator/go and github.com/pkg/errors
  • The gopkg.in/yaml.v2 dependency was finally removed in v1.35.0, replaced by go.yaml.in/yaml/v2

2. Module Architecture

Kubernetes is a 32-module monorepo using go.work for workspace management:

  • Root module: k8s.io/kubernetes
  • 31 staging modules: k8s.io/api, k8s.io/apimachinery, k8s.io/apiserver, k8s.io/client-go, etc.

The staging modules are published as separate repositories but developed in-tree under staging/src/k8s.io/.


3. Dependency Statistics

3.1 Overall Stats

Direct Dependencies:     179
Transitive Dependencies: 224
Total Dependencies:      257
Max Depth:                19

3.2 Test-only Split

Test-only Dependencies:   31
Non-test Dependencies:   226

Roughly 12% of dependencies are test-only, a healthy ratio indicating most deps are production-critical.


4. Graph Characteristics

4.1 Full Dependency Graph

Full Dependency Graph

The graph shows the dense interconnection between staging modules (k8s.io/*) and the major external dependency clusters: etcd, gRPC, OpenTelemetry, Prometheus, and the Go standard library extensions.


5. Dependency Cycles

19 cycles detected — all involving external dependencies:

Cycle Modules
protobuf github.com/golang/protobufgoogle.golang.org/protobuf
ginkgo/gomega github.com/onsi/ginkgo/v2github.com/onsi/gomega
prometheus github.com/prometheus/client_golanggithub.com/prometheus/common
testify github.com/stretchr/objxgithub.com/stretchr/testify
OTel auto/sdk (5 cycles) go.opentelemetry.io/auto/sdkotelotel/metricotel/trace
OTel core (3 cycles) otelotel/metricotel/trace
OTel SDK otel/sdkotel/sdk/metric
golang.org/x (5 cycles) x/cryptox/netx/textx/toolsx/mod
gRPC/genproto google.golang.org/genproto/googleapis/apigoogle.golang.org/grpc

Notable: Zero internal cycles between k8s.io modules — the staging module hierarchy is clean.


6. Archived Dependencies

6 archived dependencies found:

Module Version Status
github.com/flynn/go-shlex v0.0.0-20150515145356 Archived
github.com/google/btree v1.1.3 Archived
github.com/google/gofuzz v1.0.0 Archived (superseded by sigs.k8s.io/randfill)
github.com/json-iterator/go v1.1.12 Archived
github.com/kr/pty v1.1.1 Archived (superseded by github.com/creack/pty)
github.com/pkg/errors v0.9.1 Archived (superseded by fmt.Errorf wrapping)

11 modules were unresolvable (non-GitHub hosts: bitbucket.org, buf.build, cyphar.com, gonum.org, google.golang.org, gopkg.in).

Recommendations:

  • google/gofuzz → already being replaced by sigs.k8s.io/randfill
  • json-iterator/go → migrate to encoding/json or go.yaml.in/yaml/v3
  • pkg/errors → use fmt.Errorf with %w wrapping
  • kr/pty → already has github.com/creack/pty in the tree
  • flynn/go-shlex → consider go-shellwords or stdlib alternatives

7. Release Diff: v1.34.0 → v1.35.0

7.1 Summary

Metric v1.34.0 v1.35.0 Delta
Direct Deps 183 187 +4
Transitive Deps 212 228 +16
Total Deps 250 266 +16
Max Depth 18 19 +1

7.2 Dependencies Added (+17)

Module Category
cyphar.com/go-pathrs Container runtime (path resolution)
github.com/Masterminds/semver/v3 Semantic versioning
github.com/gkampitakis/ciinfo CI detection (test tooling)
github.com/gkampitakis/go-diff Diff library (test tooling)
github.com/gkampitakis/go-snaps Snapshot testing
github.com/goccy/go-yaml YAML processing
github.com/joshdk/go-junit JUnit report parsing
github.com/maruel/natural Natural sort
github.com/mfridman/tparse Test output parser
github.com/moby/sys/atomicwriter Atomic file writes
github.com/tidwall/gjson JSON path queries
github.com/tidwall/match Pattern matching
github.com/tidwall/pretty JSON formatting
github.com/tidwall/sjson JSON mutations
go.uber.org/automaxprocs GOMAXPROCS tuning
golang.org/x/tools/go/expect Test expectations
golang.org/x/tools/go/packages/packagestest Package testing

7.3 Dependencies Removed (-1)

Module Notes
gopkg.in/yaml.v2 Replaced by go.yaml.in/yaml/v2 (fork with maintained module path)

7.4 Notable Version Bumps

  • Go: 1.24.0 → 1.25.0
  • Docker: v26.1.4 → v28.2.2
  • runc: v1.2.5 → v1.3.0
  • etcd: v3.6.4 → v3.6.5
  • gRPC: v1.72.1 → v1.72.2
  • OTel: v1.35.0 → v1.36.0
  • Prometheus client: v1.22.0 → v1.23.2
  • AWS SDK: v1.30.1 → v1.36.3
  • cobra: v1.9.1 → v1.10.0

7.5 Diff Visualization

Dependency Diff v1.34.0 → v1.35.0


8. Why-Traces

8.1 Why is gRPC included? (32 direct dependents)

gRPC is the most connected external dependency, used by 32 modules including 16 k8s.io staging modules and key external deps (etcd, OTel, containerd, konnectivity).

Key paths:

  • k8s.io/apiservergo.etcd.io/etcd/client/v3google.golang.org/grpc
  • k8s.io/cri-apigoogle.golang.org/grpc (CRI protocol)
  • k8s.io/kmsgoogle.golang.org/grpc (KMS protocol)
  • k8s.io/component-basegoogle.golang.org/grpc (base infrastructure)

Why gRPC

8.2 Why is OpenTelemetry included? (29 direct dependents)

OTel is the second most connected dependency with 29 direct dependents — including 17 k8s.io modules. It enters primarily through gRPC (which depends on OTel for instrumentation) and through direct k8s.io tracing support.

Key paths:

  • k8s.io/apiservergo.opentelemetry.io/otel (direct tracing)
  • google.golang.org/grpcgo.opentelemetry.io/otel (gRPC instrumentation)
  • k8s.io/component-basego.opentelemetry.io/otel (base tracing)

Why OTel

8.3 Why is Prometheus client_golang included? (21 direct dependents)

Prometheus metrics is deeply embedded with 21 direct dependents — 15 k8s.io modules plus etcd, cadvisor, grpc-middleware, and konnectivity.

Key paths:

  • k8s.io/component-basegithub.com/prometheus/client_golang (metrics framework)
  • k8s.io/apiservergithub.com/prometheus/client_golang (API metrics)
  • go.etcd.io/etcd/server/v3github.com/prometheus/client_golang (etcd metrics)

Why Prometheus

8.4 Why is cel-go included? (11 direct dependents)

CEL (Common Expression Language) is used for admission control validation and is depended on by 11 modules — 10 k8s.io modules plus grpc-middleware.

Key paths:

  • k8s.io/apiextensions-apiservergithub.com/google/cel-go (CRD validation)
  • k8s.io/apiservergithub.com/google/cel-go (admission webhooks)
  • k8s.io/kube-schedulergithub.com/google/cel-go (scheduling policies)

Why cel-go

8.5 Why is etcd client/v3 included? (9 direct dependents)

The etcd client is used by 9 modules — 7 k8s.io modules plus the etcd server itself.

Key paths:

  • k8s.io/apiservergo.etcd.io/etcd/client/v3 (storage backend)
  • k8s.io/apiextensions-apiservergo.etcd.io/etcd/client/v3 (CRD storage)
  • k8s.io/cloud-providergo.etcd.io/etcd/client/v3 (cloud integration)

Why etcd client/v3


9. Recommendations

High Priority

  1. Replace github.com/json-iterator/go — archived; standard encoding/json with Go 1.24+ performance improvements is viable
  2. Replace github.com/pkg/errors — archived; use fmt.Errorf("%w", err) wrapping
  3. Complete google/gofuzzsigs.k8s.io/randfill migration — already in progress

Medium Priority

  1. Monitor OTel cycle complexity — 9 of the 19 cycles involve OTel modules; upstream cleanup would benefit the ecosystem
  2. Track gopkg.in/yaml.v2 removal — successfully replaced in v1.35.0, confirm no regressions
  3. Evaluate test tooling additions — v1.35.0 added 7+ test-related deps (gkampitakis/*, mfridman/tparse, joshdk/go-junit)

Low Priority

  1. Replace github.com/flynn/go-shlex — archived, 2015-era code
  2. Replace github.com/kr/ptygithub.com/creack/pty is already in the dependency tree

10. Reproducibility

All commands run from the Kubernetes checkout at commit 411c4499fa5:

# Statistics
depstat stats -d .
depstat stats -d . --split-test-only
depstat stats -d . --verbose

# Dependency graph
depstat graph -d . --svg > k8s-full-graph.svg

# Cycle detection
depstat cycles -d . --json

# Archived dependencies
GITHUB_TOKEN="$(gh auth token)" depstat archived -d . --json

# Version diff
depstat diff -d . v1.34.0 v1.35.0
depstat diff -d . v1.34.0 v1.35.0 --svg > k8s-diff-v134-v135.svg

# Why-traces (SVG)
depstat why -d . google.golang.org/grpc --svg --max-paths 50 > k8s-why-grpc.svg
depstat why -d . go.opentelemetry.io/otel --svg --max-paths 30 > k8s-why-otel.svg
depstat why -d . github.com/prometheus/client_golang --svg --max-paths 50 > k8s-why-client_golang.svg
depstat why -d . github.com/google/cel-go --svg --max-paths 50 > k8s-why-cel-go.svg
depstat why -d . go.etcd.io/etcd/client/v3 --svg --max-paths 50 > k8s-why-etcd-v3.svg

Tool version: depstat built from source at sigs.k8s.io/depstat.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment