Skip to content

14 - Anatomy of a K8s-Related OSS Project

What this session is

About 30 minutes. Walk through the typical layout of a K8s-related OSS project - Helm charts, operators, kubectl plugins.

Typical Helm chart repo

my-app-chart/
├── README.md
├── LICENSE
├── CONTRIBUTING.md
├── Chart.yaml                       (chart metadata)
├── values.yaml                      (default values)
├── values.schema.json               (JSON schema for values, optional)
├── templates/
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   ├── serviceaccount.yaml
│   ├── hpa.yaml
│   ├── tests/
│   │   └── test-connection.yaml
│   └── NOTES.txt
├── ci/                              (test values files)
│   ├── ci-values.yaml
│   └── lint-values.yaml
├── .helmignore                      (like .gitignore but for chart packaging)
└── .github/workflows/
    ├── lint.yml                     (helm lint, chart-testing)
    └── release.yml                  (publish to a chart repo)

Roles: - Chart.yaml - metadata. Version. Dependencies. - values.yaml - what users can configure. The README usually has a table of all values. - values.schema.json - JSON schema; helm install validates against it. - templates/ - Go-templated manifests. _helpers.tpl is shared snippets. - templates/tests/ - Helm tests. Run with helm test <release>. Each test is a pod that runs an assertion (e.g., curl the service to ensure it works). - ci/ - different value combos for CI testing. - .helmignore - files NOT included when packaging the chart.

Typical operator repo (Go-based)

my-operator/
├── README.md
├── LICENSE
├── CONTRIBUTING.md
├── Makefile                         (build, test, deploy targets)
├── go.mod / go.sum
├── PROJECT                          (Kubebuilder/operator-sdk project file)
├── api/
│   └── v1alpha1/
│       ├── mything_types.go         (Go struct for the CRD)
│       └── zz_generated_deepcopy.go (generated code)
├── controllers/
│   └── mything_controller.go        (the reconcile loop)
├── config/
│   ├── crd/bases/                   (generated CRD YAMLs)
│   ├── default/                     (default deployment manifests)
│   ├── manager/                     (operator pod deployment)
│   ├── rbac/                        (ServiceAccount + Role + Binding)
│   └── samples/                     (sample CR instances)
├── hack/                            (helper scripts)
└── .github/workflows/

Operators are usually built with Kubebuilder or Operator SDK. The above is the Kubebuilder layout.

You wouldn't dive into operator Go code as a first contribution. Likely contributions: improve config/samples/ examples, fix typos in README.md, update RBAC in config/rbac/, improve test fixtures.

Typical kubectl plugin

kubectl-myplugin/
├── README.md
├── LICENSE
├── main.go                          (entry point, single binary)
├── pkg/
│   └── cmd/
│       └── ...                      (subcommands)
├── go.mod
├── Makefile
├── .github/workflows/
│   └── release.yml                  (build binaries for multiple platforms)
└── docs/

kubectl plugins are standalone binaries named kubectl-<plugin>. Put one in your PATH and kubectl <plugin> works. Many plugins are small (a few hundred lines of Go).

Contributions: subcommand improvements, docs, bug fixes.

CI: what your PR will be measured against

For Helm charts, common CI:

- name: Run chart-testing (lint)
  run: ct lint --config ct.yaml
- name: Run chart-testing (install)
  run: ct install --config ct.yaml

chart-testing is the standard Helm-CI tool. Replicate locally:

brew install chart-testing
ct lint --config ct.yaml --target-branch=main

For operators, CI usually runs: - make test (unit tests) - make manifests (regenerate CRDs from Go types - should be no-op if you didn't change types) - make docker-build (build the operator image)

For kubectl plugins, CI runs go test ./... and cross-compiles.

Conventions in CONTRIBUTING.md

  • Setup. "How to run the chart locally," "how to build the operator binary."
  • Tests. What make test or ct install checks.
  • Commit format. Some projects use Conventional Commits. Many don't.
  • PR template. Address every checkbox.
  • DCO. CNCF projects often require git commit -s for the DCO.
  • CLA. Some projects require a CLA signature via a bot.

Reading a chart's README

Real-world chart READMEs typically have:

  1. Overview.
  2. Prerequisites (K8s version, Helm version).
  3. Installation:
    helm repo add ...
    helm install my-release .../my-chart
    
  4. Configuration values table - every settable value, default, description.
  5. Upgrade notes (breaking changes per version).
  6. Troubleshooting.

Read this before opening a PR. Many issues are answered there.

A worked walkthrough

Pick a Bitnami chart, say bitnami/postgresql. Apply orientation:

  1. Open Chart.yaml - name: postgresql, dependencies (none direct), version (likely double-digits - Bitnami iterates fast).

  2. Open values.yaml - heavily commented. The structure shows: image:, auth:, primary:, readReplicas:, metrics:, etc.

  3. Look in templates/:

  4. primary/statefulset.yaml (Postgres primary)
  5. primary/svc.yaml
  6. read/statefulset.yaml (read replicas if configured)
  7. secrets.yaml
  8. serviceaccount.yaml
  9. metrics/

  10. Read the primary StatefulSet template. Note how it pulls everything from .Values.primary.*.

  11. Open templates/NOTES.txt. That's what users see after install - "your password is X, connect with Y."

Five minutes; you have a mental map of one of the most-deployed Postgres charts.

Exercise

Use the project you picked in page 13:

  1. Clone locally.
  2. Walk the layout. Map files to categories.
  3. Read CONTRIBUTING.md.
  4. Find the CI workflow. List the commands.
  5. Run them locally:
  6. For Helm: helm lint . and maybe ct lint.
  7. For operator: make test.
  8. Identify the file your issue would touch.

What you might wonder

"What's app.kubernetes.io/managed-by: Helm?" A label every Helm-installed resource gets, indicating who manages it. Useful for "show me all Helm-managed things."

"What's release.toolkit.fluxcd.io/...?" Annotations the Flux GitOps operator uses to track resources. You'll see them in Flux-managed clusters.

Done

  • Recognize Helm chart layout.
  • Recognize operator (Kubebuilder) layout.
  • Recognize kubectl plugin layout.
  • Read CI workflows, run them locally.
  • Read a chart README for configuration.

Next: Your first contribution →

Comments