Auf dieser Seite
Behandelte Architektureigenschaften
- P-1Die probabilistische Workload in einem eigenen Namespace, mit ausgehendem Netzwerkverkehr nur zu dem, was sie braucht, und ohne Zugangsdaten für den maßgeblichen Datenspeicher. Eine Ergänzung der Anwendungsgrenze, nie ihr Ersatz.
- P-4Ausführungskontext einmal pro Workload konfiguriert; eine gesampelte Trace-Pipeline, getrennt von der Prüfspur gehalten; die Herkunft der Konfiguration an jedem Pod ablesbar.
- P-6Deployment-Admission und Release-Gates als Fence-Flächen, mit ihren typischen Umgehungen benannt.
- P-8Konfigurations- und Policy-Revisionen, die Rollouts überstehen, und ein Entscheidungsdatensatz, der die Revision nennt, wenn zwei gleichzeitig live sind.
- P-7Externe Dienste über expliziten ausgehenden Verkehr erreicht, sodass eine neue Abhängigkeit eine geprüfte Änderung an einer Policy ist und keine Codezeile.
- P-2, P-3Auf Infrastrukturebene nicht behandelt: Es sind Eigenschaften der Anwendung, und COADF veröffentlicht sie nur als Prinzipien.
Architektonische Absicht
Kubernetes bringt eigene Grenzen mit (Namespaces, Netzwerk-Policies, Admission, Rollout) und eigene Fehlermuster: Objekte, die angenommen und nicht durchgesetzt werden, Abgleich, der irgendwann stattfindet, zwei Versionen desselben Dienstes, die gleichzeitig antworten. Dieses Profil bildet die COADF-Eigenschaften auf diese Grenzen ab, ohne Kubernetes als Voraussetzung von COADF zu behandeln und ohne eine Kontrolle im Cluster an die Stelle einer Kontrolle in der Anwendung treten zu lassen.
Die Regel, die sich hindurchzieht: Infrastruktur kann eine Grenze schwerer überschreitbar machen, aber sie kann keine entstehen lassen. Eine Anwendung, die Modellausgaben in ihre eigenen maßgeblichen Tabellen schreibt, wird durch keine Netzwerk-Policy repariert.
Technologiezuordnung
| Architektureigenschaft | Cloud-native und Kubernetes |
|---|---|
| Probabilistische Grenze | Ein eigenes Deployment und ein eigener Namespace; NetworkPolicy für ausgehenden Verkehr; die Schreib-Zugangsdaten nur dort angelegt, wo die Domäne läuft; Datenbank-Grants pro Workload |
| Admission-Fence | ValidatingAdmissionPolicy (CEL, im Prozess) oder OPA Gatekeeper (Rego, mit einem Audit bestehender Ressourcen) |
| Ausführungskontext | OpenTelemetry-SDK-Konfiguration pro Workload; eine Collector-Pipeline für Traces |
| Prüfspur | Der eigene Append-only-Speicher der Anwendung, außerhalb der Telemetrie-Pipeline |
| Herkunft der Konfiguration | Revisions-Annotationen, unveränderliche, nach Revision benannte ConfigMaps, per Digest fixierte Images; ein GitOps-Controller, der die synchronisierte Revision festhält |
| Release-Kontrolle | Pflicht-Checks, die nicht dadurch bestehen können, dass sie übersprungen werden; Deployment-Umgebungen; Promotion per Digest |
| Policy | OPA als Dienst oder Sidecar, seine Bundle-Revision in den Entscheidungsprotokollen; Admission-Policies für Infrastrukturregeln |
Referenzmuster
Drei Namespaces: inference für den Modell-Client und seine Grenze, model-serving für den Modell-Endpunkt, records für die Aufnahme der Vorschläge, den Domänenkern und die Datenbank. Die Seite Probabilistische Grenze zeichnet dasselbe System als Cluster-Diagramm.
P-1 · Kein Weg zu den Datensätzen
- Zweck
- Wenn die probabilistische Seite als eigener Workload läuft, ihr keine Route zum maßgeblichen Speicher geben.
- Architektureigenschaft
- Netzwerkisolation als zusätzliche Durchsetzung der Grenze aus P-1 auf Ebene der Infrastruktur. Sie ergänzt die Grenze in der Anwendung und ersetzt sie nicht.
# Illustrative reference example: the inference workloads can reach the model# endpoint, the domain's proposal intake and DNS, and nothing else. The records# database sits in the same namespace as the intake, and no rule here opens a# route to it: selecting the intake pods and port is what keeps it closed.# Enforced only by a network plugin that implements NetworkPolicy, and only as an# addition: the application boundary is still required, and this replaces none of it.apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: inference-egress namespace: inferencespec: podSelector: {} # every pod in this namespace policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: model-serving ports: - protocol: TCP port: 8080 - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: records podSelector: # same list item: this namespace AND these pods matchLabels: app: proposal-intake ports: - protocol: TCP port: 8443 - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53Was es bewusst weglässt
- Das Netzwerk-Plugin. Ohne eines, das NetworkPolicy umsetzt, wird dieses Objekt angenommen und bewirkt nichts.
- Ingress-Regeln und eine Default-Deny-Policy für den Namespace.
- Die Labels der DNS-Pods, die sich zwischen Clustern unterscheiden.
- Egress zu einem außerhalb des Clusters gehosteten Modell, der eine eigene Regel braucht.
So lässt es sich prüfen
Für diesen Companion nicht ausgeführt: Das Manifest wurde gegen die Kubernetes-Schemata validiert, was seine Struktur belegt und nichts über die Durchsetzung. Um die Durchsetzung zu verifizieren, in einem Testcluster mit einem durchsetzenden Netzwerk-Plugin, von einem Inferenz-Pod aus: Der Modell-Endpunkt antwortet, und die Datenbank der Datensätze antwortet nicht; die Policy löschen, und die Datenbank antwortet, was belegt, dass es die Policy war, die sie blockiert hat.
Adressiertes Fehlermuster
Eine NetworkPolicy, die in einen Cluster eingespielt wird, dessen Netzwerk-Plugin sie nicht durchsetzt. Das Manifest ist gültig, das Review besteht, und nichts ist isoliert.
Stützt sich auf
P-6 · Ein Fence zum Zeitpunkt des Deployments
ValidatingAdmissionPolicy ist seit Kubernetes 1.30 stabil und läuft innerhalb des API-Servers, braucht also keinen verfügbaren Webhook. Dieselben Regeln lassen sich für OPA Gatekeeper schreiben, das ein Audit bereits vorhandener Ressourcen und Durchsetzungsaktionen wie dryrun und warn ergänzt; beides ist tragfähig, und die Eigenschaft hängt nicht von der Wahl ab.
Die Regel muss das Ganze prüfen, das sie benennt. Ein Test auf @sha256: irgendwo in der Image-Referenz lässt image@sha256: ohne irgendetwas dahinter zu; diese Policy prüft auf einen vollständigen SHA-256-Digest und verlangt, dass die Revisions-Annotation eine Revision enthält, nicht bloß existiert.
- Zweck
- Kein Deployment zulassen, dessen Images nicht über einen wohlgeformten Digest fixiert sind oder das nicht in einer nicht leeren Annotation die Konfigurationsrevision nennen kann, aus der es stammt.
- Architektureigenschaft
- Ein verbotener Zustand verhindert den Übergang, hier das Anlegen oder Aktualisieren eines Deployments (P-6), und die Herkunft der Konfiguration wird zu einer Eigenschaft jedes laufenden Workloads (P-4).
# Illustrative reference example: a Deployment is admitted only if every image# reference ends in a well-formed sha256 digest and the object names, in a# non-empty annotation, the configuration revision it was rendered from.# Admission sees API objects; it never sees application data.apiVersion: admissionregistration.k8s.io/v1kind: ValidatingAdmissionPolicymetadata: name: deployments-declare-provenancespec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] validations: - expression: >- object.spec.template.spec.containers.all(c, c.image.matches('^[^@]+@sha256:[0-9a-f]{64}$')) && (!has(object.spec.template.spec.initContainers) || object.spec.template.spec.initContainers.all(c, c.image.matches('^[^@]+@sha256:[0-9a-f]{64}$'))) message: "every container image must end in a sha256 digest of 64 hex characters" - expression: >- has(object.metadata.annotations) && 'refapp.example/config-revision' in object.metadata.annotations && object.metadata.annotations['refapp.example/config-revision'].matches('^[A-Za-z0-9._-]+$') message: "the Deployment must name, in a non-empty annotation, the configuration revision it was rendered from"---apiVersion: admissionregistration.k8s.io/v1kind: ValidatingAdmissionPolicyBindingmetadata: name: deployments-declare-provenancespec: policyName: deployments-declare-provenance validationActions: ["Deny"] matchResources: namespaceSelector: matchLabels: refapp.example/provenance-required: "true"Was es bewusst weglässt
- Validierung auf Anwendungsebene. Admission sieht API-Objekte und nie die Anfragen, die der eigene Dienst bearbeitet.
- Objekte, die bereits existieren. Admission wertet Anfragen aus, wenn sie gestellt werden, und das Hinzufügen dieser Policy prüft nichts erneut, das bereits läuft.
- Direkt angelegte Pods und andere Workload-Arten (StatefulSet, Job, CronJob, DaemonSet), die jeweils eine eigene Zuordnung brauchen.
- Ob die genannte Revision existiert oder ob der Digest derjenige ist, den die Continuous Integration gebaut hat. Die Regel prüft die Form eines Digests, nicht seine Herkunft.
So lässt es sich prüfen
Gegen einen echten Kubernetes-API-Server (ein lokaler Wegwerf-kube-apiserver 1.37 ohne Nodes; jeder Fall ein serverseitiger Dry Run): Per Digest fixierte Images werden zugelassen, auch hinter einem Registry-Port und nach einem Tag; ein Image nur mit Tag, ein leerer Digest, ein Digest, der nicht hexadezimal ist, und ein Digest falscher Länge werden abgelehnt, ebenso eine fehlende, leere oder nur aus Leerzeichen bestehende Revisionsannotation (tests/test_admission_policy.py). Mit einer Regel, die nur das Vorhandensein prüft, contains('@sha256:') und einem bloßen in, werden fünf dieser Fälle zugelassen, und deshalb prüft die Regel den gesamten Digest.
Adressiertes Fehlermuster
Ungeprüfte Annahmen über das Release: ein Tag, der nach dem Review verschoben wurde, oder ein laufendes Deployment, das niemand der Konfiguration zuordnen kann, aus der es gerendert wurde.
P-4 und P-8 · Herkunft der Konfiguration am Pod
- Zweck
- Die Konfigurationsrevision im Objekt, im Pod-Template und im Namen einer unveränderlichen ConfigMap sichtbar machen.
- Architektureigenschaft
- Eine neue Revision ist ein Rollout, und kein Pod läuft mit einer Konfiguration, die er nicht benennen kann. Die Revision der Prompt-Vorlage, die der Modellaufruf meldet (
prompt_revisionin der Python-Grenze), hat hier ein deploybares Gegenstück.
# Illustrative reference example: configuration provenance you can read off a# running pod. The revision is in the object, in the pod template and in the# name of the immutable ConfigMap, so a new revision is a new rollout and no# pod runs a configuration it cannot name.apiVersion: v1kind: ConfigMapmetadata: name: prompt-templates-3f9c2d1 namespace: inferenceimmutable: truedata: service-report.txt: | Read the service report and propose next_service_due and component_class.---apiVersion: apps/v1kind: Deploymentmetadata: name: report-extraction namespace: inference annotations: refapp.example/config-revision: "3f9c2d1"spec: replicas: 2 selector: matchLabels: app: report-extraction template: metadata: labels: app: report-extraction annotations: refapp.example/config-revision: "3f9c2d1" spec: automountServiceAccountToken: false containers: - name: worker image: registry.example/refapp/extraction@sha256:3f9c2d1e3f9c2d1e3f9c2d1e3f9c2d1e3f9c2d1e3f9c2d1e3f9c2d1e3f9c2d1e env: - name: OTEL_SERVICE_NAME value: report-extraction - name: OTEL_RESOURCE_ATTRIBUTES value: service.version=3f9c2d1 volumeMounts: - name: prompts mountPath: /etc/refapp/prompts readOnly: true volumes: - name: prompts configMap: name: prompt-templates-3f9c2d1Was es bewusst weglässt
- Überlappung beim Rollout. Während eines Rolling Updates bedienen alte und neue Pods gleichzeitig, sodass zwei Revisionen zugleich aktiv sind; die Revision nennen muss der Entscheidungssatz, nicht der Zustand des Deployments.
- Secrets, Probes, Ressourcen und Security Context.
- Der Service Account und seine Berechtigungen.
So lässt es sich prüfen
Den Prompt-Text unter demselben Namen bearbeiten: Die ConfigMap ist unveränderlich, und die Änderung wird abgelehnt. Eine neue ConfigMap anlegen und den Namen und die Annotationen aktualisieren: Ein Rollout folgt, und jeder Pod meldet seine Revision als service.version.
Adressiertes Fehlermuster
Umgebungen, die ohne Herkunftsnachweis unterschiedliche Konfiguration ausführen. Eine über Umgebungsvariablen gelesene ConfigMap wird erst übernommen, wenn Pods neu starten, eine eingehängte irgendwann, und in der Zwischenzeit kann niemand sagen, welche Konfiguration eine bestimmte Antwort erzeugt hat.
P-4 · Die Trace-Pipeline ist nicht die Prüfspur
OpenTelemetry-SDKs lesen OTEL_PROPAGATORS und verwenden standardmäßig tracecontext,baggage, sodass der Ausführungskontext Dienstgrenzen ohne Code überquert. Die Audit-Identität reist nicht auf diesem Weg: Sie ist Teil des Vertrags jeder Nachricht, und die Audit-Einträge schreibt die Anwendung in ihren eigenen Speicher.
- Zweck
- Eine gewöhnliche, gesampelte Trace-Pipeline zeigen und warum die Prüfspur nie durch eine solche läuft.
- Architektureigenschaft
- Ausführungstelemetrie und Prüfspur sind verschiedene Artefakte und versprechen Verschiedenes. Sie werden über die
trace_idder Prüfspur korreliert, und die Prüfspur läuft nie durch eine Pipeline, die so konfiguriert ist, dass sie Daten verwirft (P-4).
# Illustrative reference example: an OpenTelemetry Collector pipeline for# traces. Sampling is legitimate here, and it is exactly why this pipeline is# not the audit trail: audit entries are written to their own append-only# store by the application, and never pass through this configuration.receivers: otlp: protocols: grpc: {} http: {} processors: memory_limiter: check_interval: 1s limit_percentage: ${env:MEMORY_LIMIT_PERCENTAGE} probabilistic_sampler: sampling_percentage: ${env:TRACE_SAMPLE_PERCENTAGE} batch: {} exporters: otlp: endpoint: tracing-backend.observability:4317 service: pipelines: traces: receivers: [otlp] processors: [memory_limiter, probabilistic_sampler, batch] exporters: [otlp]Was es bewusst weglässt
- Tail Sampling, das verlangt, dass jeder Span eines Traces dieselbe Collector-Instanz erreicht.
- Das Trace-Backend und seine Aufbewahrung.
- Pipelines für Logs und Metriken.
- Die Prozentsätze. Sie sind betriebliche Einstellungen, geliefert über die Expansion von Umgebungsvariablen, und ihre Werte sind für die Architektureigenschaft ohne Belang.
So lässt es sich prüfen
otelcol-contrib validate akzeptiert die Konfiguration, wenn die beiden Prozentsätze aus der Umgebung kommen, und lehnt sie ab, wenn sie fehlen. Eine bekannte Anzahl von Traces senden und zählen, was ankommt: Bei jedem Sampling, das Traces verwirft, kommen einige nicht an, und genau diese Eigenschaft schließt diesen Pfad als Prüfspur aus.
Adressiertes Fehlermuster
Ein Trace, der nur im Tracing-Backend vorliegt: Die Frage „Was ist mit diesem Vorgang geschehen?“ wird aus einem Speicher beantwortet, der ihn verwerfen durfte.
P-6 · Release-Kontrollen
Der Workflow definiert die Checks und lässt seinen Zusammenfassungsjob scheitern, wenn ein Fence fehlschlägt, abgebrochen oder übersprungen wird. Zur Pflicht machen kann er diesen Job nicht: Das leistet Branch Protection oder ein Ruleset in den Repository-Einstellungen, und ohne sie ignoriert der Merge-Button das Ergebnis.
- Zweck
- Den Merge und das Release bei einem gescheiterten Fence stoppen, mit einem erforderlichen Check, der rot bleibt, wenn ein Fence übersprungen wird.
- Architektureigenschaft
- Ein gescheiterter, abgebrochener oder übersprungener Fence lässt den Job
fencesscheitern, und das Release läuft nicht (P-6). Der Workflow kannfencesnicht zum erforderlichen Check machen: Nur Branch Protection oder ein Ruleset in den Repository-Einstellungen blockiert darauf gestützt einen Merge.
# Illustrative reference example: fences that stop a release, and one summary# check that cannot turn green by being skipped. Making it a REQUIRED check is a# repository setting (branch protection or a ruleset), not part of this file.name: releaseon: pull_request: push: branches: [main] jobs: architecture: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install -r requirements.txt - run: lint-imports tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - uses: actions/setup-python@v7 with: python-version: "3.12" - run: pip install -r requirements.txt - run: pytest -q publication: runs-on: ubuntu-latest steps: - uses: actions/checkout@v7 - run: make site # writes the public build to build/ - name: Fence the built output env: PATTERNS: ${{ secrets.PUBLICATION_PATTERNS }} run: | printf '%s\n' "$PATTERNS" > "$RUNNER_TEMP/patterns.txt" python -m refapp.fence build/ "$RUNNER_TEMP/patterns.txt" # The one job branch protection requires. A skipped job reports success, # so this job runs whatever happened above and fails unless all passed. fences: if: ${{ always() }} needs: [architecture, tests, publication] runs-on: ubuntu-latest steps: - if: >- contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'skipped') run: exit 1 release: if: github.event_name == 'push' needs: fences # never `if: always()` here: that would release after a failed fence runs-on: ubuntu-latest environment: production steps: - run: echo "promote the artifact built from ${{ github.sha }}"Was es bewusst weglässt
- Der Build der Site selbst;
make sitesteht dafür. - Einstellungen der Branch Protection, die in den Repository-Einstellungen liegen und nicht im Workflow.
- Das Fixieren von Actions auf Commit-Hashes, die stärkere Praxis. Hier werden der Lesbarkeit halber Major-Version-Tags verwendet.
So lässt es sich prüfen
Auf einem Test-Branch einen Fence-Job scheitern lassen: Der Job fences scheitert, und das Release wird übersprungen. Stattdessen einen Fence-Job mit einem falschen if: überspringen lassen: Der Job fences scheitert trotzdem, weil ein übersprungener Job der Branch Protection Erfolg meldet und dieser Job es ablehnt, ihn mitzuzählen.
Adressiertes Fehlermuster
Ein erforderlicher Check, der grün wird, weil er übersprungen wurde. GitHub meldet einen übersprungenen Job als Erfolg, sodass ein erforderlicher Job, der von einem gescheiterten Fence abhängt, den Merge durchlassen kann.
Fehlermuster
Eine NetworkPolicy, die nichts durchsetzt
Eine NetworkPolicy ohne ein Netzwerk-Plugin, das sie implementiert, hat keine Wirkung. Das Manifest ist gültig, die Prüfung besteht, und nichts ist isoliert.
Ein Bindestrich erweitert die Regel
Innerhalb eines
to-Eintrags wählen einnamespaceSelectorund einpodSelectorzusammen diese Pods in diesen Namespaces aus. Als zwei Listeneinträge geschrieben, wählen sie den ganzen Namespace aus oder diese Pods im eigenen Namespace der Policy. Die Kubernetes-Dokumentation warnt genau vor diesem YAML-Unterschied.Admission mit Validierung in der Anwendung verwechselt
Admission fängt Anfragen an den API-Server ab: Sie sieht Deployments und Pods, nie die Anfragen, die der eigene Dienst verarbeitet, oder die Antworten, die ein Modell liefert. Siehe die Technologie-Notiz.
Ein Fence, der offen versagt
Ein Webhook mit der Failure Policy
Ignorelässt eine Anfrage durch, wenn der Webhook nicht aufgerufen werden kann. Der Tag, an dem der Webhook ausfällt, ist der Tag, an dem die Regel aus ist.Bestehende Objekte nie erneut geprüft
Admission beurteilt Anfragen, wenn sie eintreffen. Für LimitRange hält Kubernetes fest, dass bereits laufende Pods unverändert weiterlaufen; ebenso sagt eine neue Admission-Regel nichts über das, was vor ihr zugelassen wurde. Das Audit von Gatekeeper existiert für diese Lücke.
Ein nach der Prüfung verschobener Tag
Digests sind unveränderlich; Tags lassen sich so verschieben, dass sie auf andere Images zeigen. Ein per Tag geprüftes Image ist nicht notwendigerweise das Image, das läuft.
Unsichtbare Konfigurationsdrift
Eine über Umgebungsvariablen genutzte ConfigMap wird erst beim Neustart des Pods aktualisiert, eine eingehängte irgendwann, und eine über
subPatheingehängte nie. Drei Pods können drei Konfigurationen halten, während jedes Manifest eine nennt.Zwei Revisionen live während eines Rollouts
Rolling Updates betreiben alte und neue Versionen gleichzeitig. Alles, was eine Revision nennen muss (eine Entscheidung, eine Extraktion, eine Antwort), muss sie in dem Moment festhalten, in dem es entsteht, und darf sie nicht nachträglich aus dem Deployment ableiten.
Die gesampelte Pipeline als Nachweis verwendet
Ein nicht gesampelter Trace wird nicht exportiert. Eine Pipeline, die so konfiguriert ist, dass sie einen Bruchteil der Traces behält, ist für die Diagnose richtig und kann keine Audit-Frage beantworten.
Baggage, das das Haus verlässt
OpenTelemetry warnt, dass Baggage an unbeabsichtigte Empfänger weitergegeben werden kann, APIs von Dritten eingeschlossen. Eine Kennung, die aus Bequemlichkeit ins Baggage gelegt wurde, reist weiter, als ihr Eigentümer beabsichtigt hat.
Eine synchronisierte Revision als deployte Revision gelesen
status.sync.revisionin Argo CD ist die Revision, mit der der Live-Zustand zuletzt verglichen wurde; die Sync-Historie hält fest, welche Revision jeder Sync tatsächlich angewendet hat. Beide sind nur gleich, solange die Anwendung synchron ist.Ein Gate für namentlich benannte Personen, das der Tarif nicht durchsetzt
In den GitHub-Tarifen Free, Pro und Team gibt es Required Reviewers für Umgebungen nur für öffentliche Repositories. Ein privates Repository in diesen Tarifen hat den Namen der Einstellung, nicht ihre Wirkung.
Verifikation
Deployment- oder Admission-Test
Bestanden, wenn: Gegen einen lokalen Wegwerf-API-Server wird das Beispiel-Deployment in einen Namespace zugelassen, der das Label des Bindings trägt, und ebenso Digests hinter einem Registry-Port oder nach einem Tag.
Zahnbeweis: Ein Image nur mit Tag, ein leerer oder fehlerhafter Digest und eine fehlende, leere oder nur aus Leerzeichen bestehende Revision werden jeweils von der Policy abgelehnt. Die Regeln für Digest und Revision durch reine Vorhandenseinsprüfungen ersetzen: Fünf dieser Fälle werden zugelassen, und die Tests schlagen fehl.
Integrationstest
Bestanden, wenn: Für diese Revision nicht ausgeführt. Aus einem Inferenz-Pod, mit einem durchsetzenden Netzwerk-Plugin: Der Modell-Endpunkt und die Aufnahme der Vorschläge antworten, der Datenbank-Port nicht.
Zahnbeweis: Die Policy löschen: Die Datenbank antwortet, was belegt, dass die Policy und nichts anderes sie blockiert hat.
Vertragstest
Bestanden, wenn: Manifeste validieren im Strict Mode gegen die Kubernetes-Schemata jeder unterstützten Minor-Version, sodass ein falsch geschriebenes Feld ein Fehler ist.
Zahnbeweis:
podSelectorfalsch schreiben: Die strikte Validierung schlägt fehl.Vertragstest
Bestanden, wenn: Die Collector-Konfiguration validiert mit dem Collector-Binary der deployten Version, mit den Prozentsätzen aus der Umgebung.
Zahnbeweis: Eine Prozessor-Einstellung falsch schreiben oder die Prozentsätze nicht setzen: Die Validierung schlägt fehl.
End-to-End-Test
Bestanden, wenn: Ein fehlgeschlagener Fence-Job lässt den Zusammenfassungsjob scheitern und überspringt das Release; die Branch Protection führt den Zusammenfassungsjob als Pflicht.
Zahnbeweis: Einen Fence-Job überspringen, statt ihn scheitern zu lassen: Der Zusammenfassungsjob schlägt trotzdem fehl, weil er sich weigert, einen übersprungenen Job zu zählen.
Manueller Nachweis
Bestanden, wenn: Bei jedem Release werden die Image-Digests und die Konfigurationsrevision festgehalten und mit dem verglichen, was der Cluster meldet.
Alternative Umsetzungen
- Gatekeeper, Kyverno oder ValidatingAdmissionPolicy für Admission-Regeln. Die Eigenschaft ist, dass die Regel den Übergang stoppt und dabei beobachtet wurde; die Engine ist eine Wahl.
- Die Autorisierungs-Policy eines Service Mesh, wo ausgehender Verkehr pro Anfrage statt pro Port kontrolliert werden muss.
- GitOps-Controller (Argo CD, Flux) als Nachweis, welche Konfigurationsrevision angewendet ist, zusätzlich zu den Annotationen an den Objekten.
- Eine verwaltete Plattform ohne Kubernetes. Jede Eigenschaft dieses Profils hat dort ein Gegenstück: getrennte deploybare Einheiten, Netzwerkregeln, Deployment-Gates, Konfigurationsrevisionen. COADF setzt keines der hier genannten Werkzeuge voraus.
Abwägungen
- Admission im Prozess oder eine Policy-Engine. ValidatingAdmissionPolicy braucht keine zusätzliche Komponente und kann nicht getrennt vom API-Server ausfallen; Gatekeeper ergänzt ein Audit bestehender Ressourcen und eine gestufte Durchsetzung und ist ein System mehr im Betrieb.
- Netzwerkisolation hat ihren Preis: ein durchsetzendes Plugin, zu pflegende Policies und Fehler, die wie Anwendungsfehler aussehen, wenn eine Regel zu eng ist.
- Getrennte Deployments machen aus einer Grenze einen versionierten Vertrag, der über Rollouts hinweg in beide Richtungen kompatibel bleiben muss.
- Sampling spart Kosten und nimmt den Nachweiswert. Es beibehalten und die Prüfspur anderswo führen.
Grenzen
- Die Manifeste wurden gegen die Kubernetes-Schemata für 1.35, 1.36 und 1.37 validiert; die Admission-Policy wurde auf einen lokalen Wegwerf-API-Server ohne Nodes angewendet und mit serverseitigen Dry Runs ausgeübt; die Collector-Konfiguration wurde validiert und der Workflow gelintet. Nichts lief auf einem Cluster mit Nodes: Die Durchsetzung der Netzwerk-Policy, Rollouts und das Laufzeitverhalten des Collectors wurden nicht beobachtet.
- Die Beispiele lassen Ingress-Regeln, Security Contexts, Ressourcen, Probes und Secrets weg.
- Kubernetes ist ein Weg, diese Eigenschaften zu deployen. COADF setzt es nicht voraus.
Was dieses Profil nicht begründet
Wer diesem Profil folgt, begründet damit weder die Einhaltung regulatorischer Anforderungen noch eine Zertifizierung oder ein Verfahren zur Bewertung der Übereinstimmung mit Rechtsvorschriften, und nichts hier wird von COADF vorausgesetzt. Ein Cluster, der diese Manifeste zulässt, hat diese Manifeste zugelassen.
Getestete Referenzumgebung
- kubeconform 0.8.0 · strikte Schemavalidierung gegen Kubernetes 1.35.0, 1.36.0 und 1.37.0; nicht auf einen Cluster angewendet
- Kubernetes API server (envtest release) 1.37.0 · ein lokaler Wegwerf-kube-apiserver mit etcd und ohne Nodes: die Admission-Policy angewendet und zehn Fälle als serverseitige Dry Runs ausgeführt; nichts eingeplant, keine Durchsetzung im Netzwerk
- OpenTelemetry Collector (contrib) 0.160.0 · otelcol-contrib validate
- actionlint 1.7.12 · ohne shellcheck, die Shell in den run-Schritten wurde also nicht gelintet
Quellen
- Kubernetes: Network Policies: prerequisites · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Validating Admission Policy · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Admission control: what are they · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Dynamic admission control: failure policy · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Limit Ranges: admission-time validation · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Images: image names and digests · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: ConfigMaps: updates and immutability · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Deployments: rolling update · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Kubernetes: Annotations · offizielle Dokumentation · Kubernetes 1.37 · Geprüft am 2026-09-11
- Open Policy Agent Gatekeeper: Gatekeeper: audit · offizielle Dokumentation · Gatekeeper 3.23 · Geprüft am 2026-09-11
- Open Policy Agent Gatekeeper: Gatekeeper: enforcement actions · offizielle Dokumentation · Gatekeeper 3.23 · Geprüft am 2026-09-11
- OpenTelemetry: SDK environment variables: OTEL_PROPAGATORS · Spezifikation · Specification 1.60.0 · Geprüft am 2026-09-11
- OpenTelemetry: Sampling · offizielle Dokumentation · Geprüft am 2026-09-11
- OpenTelemetry: Tracing SDK: sampling · Spezifikation · Specification 1.60.0 · Geprüft am 2026-09-11
- OpenTelemetry: Transforming telemetry · offizielle Dokumentation · Geprüft am 2026-09-11
- OpenTelemetry Collector Contrib: Tail sampling processor · Projekt-Repository · Geprüft am 2026-09-11
- OpenTelemetry: Baggage: security considerations · offizielle Dokumentation · Geprüft am 2026-09-11
- Argo CD: Application CRD: status.sync.revision and status.history · Projekt-Repository · Argo CD 3.5.2 · Geprüft am 2026-09-11
- GitHub: Workflow syntax: jobs.<job_id>.needs · offizielle Dokumentation · Geprüft am 2026-09-11
- GitHub: Control jobs with conditions · offizielle Dokumentation · Geprüft am 2026-09-11
- GitHub: Troubleshooting required status checks · offizielle Dokumentation · Geprüft am 2026-09-11
- GitHub: Deployments and environments: required reviewers · offizielle Dokumentation · Geprüft am 2026-09-11
- GitHub: About protected branches: require status checks before merging · offizielle Dokumentation · Geprüft am 2026-09-11
- Open Container Initiative: Image specification, descriptors: SHA-256 digests · Spezifikation · Geprüft am 2026-09-11
- OpenTelemetry: Collector configuration: environment variables · offizielle Dokumentation · Geprüft am 2026-09-11
