-
Notifications
You must be signed in to change notification settings - Fork 68
OSSM-13581: Add ARCHITECTURE.md documenting high-level system design #2035
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5aff33d
bac5f46
a31325e
5715f7e
fff17bd
cc78f3f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,272 @@ | ||||||
| # Architecture | ||||||
|
|
||||||
| This document describes the high-level architecture of the Sail Operator. | ||||||
|
|
||||||
| See also [AGENTS.md](AGENTS.md) for development workflow, commands, and contribution guidelines. | ||||||
|
|
||||||
| ## Project Structure | ||||||
|
|
||||||
| ``` | ||||||
| sail-operator/ | ||||||
| ├── api/ # CRD type definitions | ||||||
| │ ├── v1/ # Stable API group (Istio, IstioRevision, IstioRevisionTag, IstioCNI, ZTunnel) | ||||||
| │ └── v1alpha1/ # Experimental API group (ZTunnel) | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ztunnel is already in v1 too
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point, thanks! Done. |
||||||
| ├── bundle/ # OLM bundle (ClusterServiceVersion, metadata) | ||||||
| ├── chart/ # Operator's own Helm chart for deployment | ||||||
| ├── cmd/ # Operator binary entry point | ||||||
| │ └── main.go # Manager setup, controller registration, platform detection | ||||||
| ├── common/ # Shared Makefile infrastructure (from istio/common-files) | ||||||
| ├── controllers/ # Kubernetes controller implementations | ||||||
| │ ├── istio/ # Top-level Istio CR controller | ||||||
| │ ├── istiocni/ # CNI plugin controller | ||||||
| │ ├── istiorevision/ # Revision lifecycle via Helm charts | ||||||
| │ ├── istiorevisiontag/ # Revision tag management | ||||||
| │ ├── webhook/ # ValidatingWebhookConfiguration controller | ||||||
| │ └── ztunnel/ # Ambient mesh tunnel controller | ||||||
| ├── docs/ # Documentation | ||||||
| ├── enhancements/ # Sail Enhancement Proposals (SEPs) | ||||||
| ├── hack/ # Shell scripts for chart downloads, CRD extraction, patching | ||||||
| ├── licenses/ # Third-party license information | ||||||
| ├── pkg/ # Core packages (see "Core Packages" below) | ||||||
| ├── resources/ # Embedded Istio Helm charts and profiles, per version | ||||||
| ├── tests/ | ||||||
| │ ├── e2e/ # End-to-end tests (Ginkgo, against real clusters) | ||||||
| │ └── integration/ # Integration tests (Ginkgo, envtest) | ||||||
| └── tools/ # Dependency update and utility scripts | ||||||
| ``` | ||||||
|
|
||||||
| ## High-Level System Diagram | ||||||
|
|
||||||
| ``` | ||||||
| ┌─────────────────────────────────────────────┐ | ||||||
| │ Kubernetes API │ | ||||||
| └───────────────────┬─────────────────────────┘ | ||||||
| │ | ||||||
| ┌───────────────────▼─────────────────────────┐ | ||||||
| │ Sail Operator (Manager) │ | ||||||
| │ │ | ||||||
| │ ┌──────────┐ ┌───────────┐ ┌─────────┐ │ | ||||||
| │ │ Istio │ │ IstioCNI │ │ ZTunnel │ │ | ||||||
| │ │Controller│ │Controller │ │Controller│ │ | ||||||
| │ └────┬─────┘ └─────┬─────┘ └────┬────┘ │ | ||||||
| │ │ │ │ │ | ||||||
| │ ┌────▼─────────┐ │ │ │ | ||||||
| │ │IstioRevision │ │ │ │ | ||||||
| │ │ Controller │ │ │ │ | ||||||
| │ └────┬─────────┘ │ │ │ | ||||||
| │ │ │ │ │ | ||||||
| │ ┌────▼──────────────▼──────────────▼────┐ │ | ||||||
| │ │ Helm ChartManager │ │ | ||||||
| │ │ (install/upgrade embedded charts) │ │ | ||||||
| │ └────┬─────────────────────────────────┘ │ | ||||||
| │ │ │ | ||||||
| └───────┼─────────────────────────────────────┘ | ||||||
| │ | ||||||
| ┌───────▼─────────────────────────────────────┐ | ||||||
| │ Deployed Istio Components │ | ||||||
| │ (istiod, CNI DaemonSet, ZTunnel, gateways) │ | ||||||
| └─────────────────────────────────────────────┘ | ||||||
| ``` | ||||||
|
Comment on lines
+40
to
+69
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is misaligned..
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. +1 to this |
||||||
|
|
||||||
| The Istio controller watches `Istio` CRs and creates `IstioRevision` resources. | ||||||
| The IstioRevision controller uses the Helm ChartManager to install the actual | ||||||
| Istio control plane components. IstioCNI and ZTunnel controllers manage their | ||||||
| respective components independently through the same ChartManager. | ||||||
|
|
||||||
| ## Core Components | ||||||
|
|
||||||
| ### Entry Point (`cmd/main.go`) | ||||||
|
|
||||||
| The operator binary. Responsibilities: | ||||||
| - Parse flags (metrics address, config file path, resource directory) | ||||||
| - Detect platform (Kubernetes vs OpenShift) to select the default Helm profile | ||||||
| - Load operator configuration from `/etc/sail-operator/config.properties` | ||||||
| - Initialize embedded or filesystem-based Istio chart resources | ||||||
| - Create the controller-runtime Manager with leader election and secure metrics | ||||||
| - Register all six controllers and start the manager | ||||||
| - On OpenShift: fetch cluster TLS profile and watch for changes (triggers restart on change) | ||||||
|
|
||||||
| ### Controllers (`controllers/`) | ||||||
|
|
||||||
| Each controller follows the `StandardReconciler` pattern from `pkg/reconciler/`, | ||||||
| which provides common reconciliation flow with finalizer support. | ||||||
|
|
||||||
| | Controller | CRD | Key Behavior | | ||||||
| |---|---|---| | ||||||
| | `istio` | `Istio` | Validates version, selects update strategy (InPlace or RevisionBased), creates/updates `IstioRevision` | | ||||||
| | `istiorevision` | `IstioRevision` | Runs the values pipeline, calls ChartManager to install Helm releases (base, istiod, gateway) | | ||||||
| | `istiorevisiontag` | `IstioRevisionTag` | Manages MutatingWebhookConfigurations to route sidecar injection between revisions | | ||||||
| | `istiocni` | `IstioCNI` | Deploys the Istio CNI DaemonSet via the cni chart | | ||||||
| | `ztunnel` | `ZTunnel` | Deploys the ZTunnel DaemonSet for ambient mode via the ztunnel chart | | ||||||
| | `webhook` | *(none)* | Manages ValidatingWebhookConfigurations for CRD validation | | ||||||
|
|
||||||
| ### Custom Resource Relationships | ||||||
|
|
||||||
| ``` | ||||||
| Istio ──creates──▶ IstioRevision ──installs──▶ Helm releases (base, istiod, gateway) | ||||||
| ▲ | ||||||
| IstioRevisionTag ───────┘ (points to a revision for traffic routing) | ||||||
|
|
||||||
| IstioCNI ──installs──▶ cni chart | ||||||
| ZTunnel ──installs──▶ ztunnel chart | ||||||
| ``` | ||||||
|
|
||||||
| - **Sidecar mode** requires: `Istio` (and `IstioCNI` on OpenShift) | ||||||
| - **Ambient mode** requires: `Istio` + `IstioCNI` + `ZTunnel` | ||||||
|
|
||||||
| ### Core Packages (`pkg/`) | ||||||
|
|
||||||
| | Package | Purpose | | ||||||
| |---|---| | ||||||
| | `helm` | Helm v4 ChartManager: chart loading (`FSLoader`), install/upgrade, post-renderer for label injection | | ||||||
| | `install` | Installation orchestration: CRD management, RBAC setup, Library pattern for operator-in-operator embedding | | ||||||
| | `istiovalues` | Values transformation pipeline: profiles, image digests, FIPS/TLS settings, platform overrides | | ||||||
| | `istioversion` | Version resolution from `versions.yaml`: aliases (e.g. `vX.Y-latest` -> `vX.Y.Z`), EOL tracking | | ||||||
| | `revision` | Revision lifecycle: dependency tracking, old revision pruning, workload migration | | ||||||
| | `reconcile` | Component-specific reconciliation logic for istiod, CNI, and ZTunnel | | ||||||
| | `reconciler` | Generic `StandardReconciler[T]` with finalizer support, used by all controllers | | ||||||
| | `config` | Operator configuration loading, platform detection, TLS profile management | | ||||||
| | `kube` | Kubernetes utilities: finalizer helpers, status patching, resource key formatting | | ||||||
| | `validation` | CRD validation helpers | | ||||||
| | `predicate` | Event filtering predicates for controller watches | | ||||||
| | `watches` | Watch configuration helpers for controllers | | ||||||
| | `scheme` | Kubernetes scheme registration (API types, OpenShift types) | | ||||||
| | `enqueuelogger` | Debug logging wrapper for reconciliation queue events | | ||||||
| | `constants` | Shared constants (label values, annotation keys) | | ||||||
| | `converter` | Configuration conversion utilities | | ||||||
| | `env` | Environment variable reading helpers | | ||||||
| | `errlist` | Error list aggregation | | ||||||
| | `version` | Build-time version information | | ||||||
| | `test` | Shared test utilities | | ||||||
|
|
||||||
| ## Data Flow | ||||||
|
|
||||||
| ### Values Pipeline | ||||||
|
|
||||||
| When an `IstioRevision` is reconciled, values are assembled through a pipeline | ||||||
| before being passed to Helm: | ||||||
|
|
||||||
| ``` | ||||||
| Chart defaults (values.yaml from embedded chart) | ||||||
| │ | ||||||
| ▼ | ||||||
| Profile overlay (default, openshift, demo, ambient, etc.) | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "Image digest injection" comes before "ApplyProfilesAndPlatform" sail-operator/pkg/revision/values.go Line 41 in f53307f
Also, there is an additional step where we apply the vendor specific defaults. sail-operator/pkg/revision/values.go Line 45 in f53307f
|
||||||
| │ | ||||||
| ▼ | ||||||
| Image digest injection (from config.properties) | ||||||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we want to include this? I don't think an user can touch config.properties right?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, users do not touch it, but the diagram is for an agent, so I think it's valuable information. Could we leave it as is?
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. |
||||||
| │ | ||||||
| ▼ | ||||||
| User-provided overrides (Istio CR spec.values) | ||||||
| │ | ||||||
| ▼ | ||||||
| Platform-specific settings (OpenShift adjustments) | ||||||
| │ | ||||||
| ▼ | ||||||
| FIPS / TLS profile settings (cipher suites, min TLS version) | ||||||
| │ | ||||||
| ▼ | ||||||
| Final merged values ──▶ Helm install/upgrade | ||||||
| ``` | ||||||
|
|
||||||
| ### Update Strategies | ||||||
|
|
||||||
| The `Istio` controller supports two update strategies: | ||||||
|
|
||||||
| - **InPlace**: Directly updates the existing `IstioRevision` in place | ||||||
| - **RevisionBased**: Creates a new `IstioRevision` alongside the old one, | ||||||
| uses `IstioRevisionTag` to shift traffic, then prunes old revisions | ||||||
| after a configurable grace period | ||||||
|
|
||||||
| ## Key Technologies | ||||||
|
|
||||||
| | Technology | Role | | ||||||
| |---|---| | ||||||
| | Go | Implementation language | | ||||||
| | controller-runtime | Kubernetes operator framework | | ||||||
| | Helm | Chart-based Istio deployment | | ||||||
| | Istio | Service mesh (managed by this operator) | | ||||||
| | Kubebuilder | Project scaffolding and code generation | | ||||||
| | Ginkgo / Gomega | BDD testing framework | | ||||||
| | OpenShift API | Platform-specific integration (optional) | | ||||||
|
|
||||||
| ## Embedded Resources | ||||||
|
|
||||||
| Istio Helm charts and profiles are compiled into the operator binary via Go's | ||||||
| `embed.FS` (`resources/resources.go`). Each supported Istio version has its own | ||||||
| directory under `resources/`: | ||||||
|
|
||||||
| ``` | ||||||
| resources/ | ||||||
| ├── resources.go # //go:embed directive | ||||||
| ├── vX.Y.Z/charts/ # base, cni, gateway, istiod, revisiontags, ztunnel | ||||||
| └── ... | ||||||
| ``` | ||||||
|
|
||||||
| At runtime, the `--resource-directory` flag can override embedded charts with | ||||||
| a filesystem path, which is useful for development. | ||||||
|
|
||||||
| ## Development and Testing | ||||||
|
|
||||||
| ### Testing Layers | ||||||
|
|
||||||
| - **Unit tests** (`*_test.go` throughout the codebase): Standard Go testing, | ||||||
| no cluster required. Run with `make test`. | ||||||
| - **Integration tests** (`tests/integration/`): Use controller-runtime's envtest | ||||||
| to run against a local API server. Run with `make test.integration`. | ||||||
| - **E2E tests** (`tests/e2e/`): Full cluster tests using Ginkgo, covering | ||||||
| ambient mode, control plane lifecycle, multicluster, gateway API, cert-manager, | ||||||
| and more. Run with `make test.e2e.kind` (KIND) or `make test.e2e.ocp` (OpenShift). | ||||||
|
|
||||||
| ### Code Generation | ||||||
|
|
||||||
| Generated artifacts are produced by `make gen` (or specific sub-targets): | ||||||
|
|
||||||
| | Generator | Output | | ||||||
| |---|---| | ||||||
| | controller-gen | CRD manifests, RBAC manifests, DeepCopy methods (`zz_generated.deepcopy.go`) | | ||||||
| | Custom tooling | `values_types.gen.go` (Istio Helm values schema from `istio.io/api`) | | ||||||
| | operator-sdk | OLM bundle in `bundle/` | | ||||||
| | crd-ref-docs | API reference documentation | | ||||||
| | `hack/download-charts.sh` | Embedded charts under `resources/` | | ||||||
|
|
||||||
| ## Deployment | ||||||
|
|
||||||
| The operator is deployed via its own Helm chart (`chart/`): | ||||||
|
|
||||||
| ``` | ||||||
| chart/ | ||||||
| ├── Chart.yaml | ||||||
| ├── crds/ # Operator CRDs (Istio, IstioRevision, etc.) | ||||||
| ├── templates/ # Deployment, ServiceAccount, RBAC, etc. | ||||||
| └── values.yaml | ||||||
| ``` | ||||||
|
|
||||||
| It can also be deployed as an OLM-managed operator using the bundle in `bundle/`. | ||||||
|
|
||||||
| Key environment variables: | ||||||
| - `HUB` / `TAG`: Container image registry and tag | ||||||
| - `POD_NAMESPACE`: Operator namespace (auto-detected from service account) | ||||||
| - `HELM_DRIVER`: Helm storage driver override | ||||||
| - `VERSIONS_YAML_FILE`: Custom versions file for downstream vendors | ||||||
|
|
||||||
| ## Security Considerations | ||||||
|
|
||||||
| - Metrics endpoint serves over HTTPS with authentication and authorization filters | ||||||
| - HTTP/2 is disabled on the metrics server to mitigate stream cancellation CVEs | ||||||
| - On OpenShift, the operator respects the cluster-wide TLS security profile | ||||||
| (cipher suites, minimum TLS version) and restarts on profile changes | ||||||
| - Leader election prevents multiple active instances | ||||||
| - All commits require signing (`-s` flag) | ||||||
| - Gitleaks pre-commit hook scans for secrets | ||||||
|
|
||||||
| ## Platform Abstraction | ||||||
|
|
||||||
| The operator detects the platform at startup (`pkg/config/platform.go`): | ||||||
|
|
||||||
| - **Kubernetes**: Uses the `default` Helm profile | ||||||
| - **OpenShift**: Uses the `openshift` Helm profile, fetches TLS configuration | ||||||
| from the cluster's `APIServer` resource, and integrates with OpenShift-specific | ||||||
| APIs (`github.com/openshift/api`, `github.com/openshift/library-go`) | ||||||
|
|
||||||
| Vendor-specific customization is configuration-driven (no code forks): | ||||||
| custom `versions.yaml` files and `vendor_defaults.yaml` for Helm value overrides. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: maybe sort it alphabetically so it matches order visible in GH UI
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. Done.