Skip to main content

loom-kustomize

Kubernetes-native configuration management with Kustomize.

معلومات المصدر

المستودع
cosmix/loom
آخر نشاط في المصدر
٢٩ أغسطس ٢٠٢٦ في ٢١:١٩
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٦١
التفرعات
٤

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
loom-kustomize
description
Kubernetes-native configuration management with Kustomize.
allowed-tools
["Read","Grep","Glob","Edit","Write","Bash"]
triggers
["kustomize","kustomization","overlay","base","patch","strategic merge","json patch","json6902","configmap generator","secret generator","namespace","namePrefix","nameSuffix","commonLabels","commonAnnotations","component","transformer","replacement","multi-environment","dev/staging/prod configs","k8s manifest management"]
# Kustomize Skill ## Overview Template-free, declarative Kubernetes config management via merging. `kubectl apply -k <dir>` and `kustomize build <dir>` render an overlay. Failure modes here are overwhelmingly **silent** (wrong output, exit 0) — always `diff` the `kustomize build` output before/after any structural change. ## Core Concepts | Term | Meaning | | --------------- | ------------------------------------------------------------------------------------------------ | | **Base** | Dir with `kustomization.yaml` + shared resources; never modified in place. | | **Overlay** | Dir referencing a base under `resources:`, applying env-specific patches/generators. | | **Patch** | Partial resource that modifies existing ones — strategic merge (default) or JSON 6902. | | **Component** | Reusable opt-in feature bundle (`kind: Component`); runs against the parent's accumulated set. | | **Generator** | Builds ConfigMaps/Secrets from literals/files/envs, appending a content-hash name suffix. | | **Transformer** | Cross-cutting mutation: `namespace`, `namePrefix`/`nameSuffix`, `labels`, `images`, `replicas`. | | **Replacement** | Copies a field value from a source resource into target field paths (successor to `vars`). | ## Directory Layout ```text k8s/ ├── base/ # shared, env-agnostic (kustomization.yaml + resources) ├── overlays/ │ ├── dev/ # low resources, debug │ ├── staging/ # + monitoring component │ └── prod/ # HA, security, digest-pinned images └── components/ # opt-in features: monitoring, ingress, debug-tools ``` Keep the hierarchy **shallow** (base → overlay, not base → overlay1 → overlay2). Paths in `resources:` are relative to the kustomization.yaml's own directory. ## Quick Reference | Task | Command | | ---------------- | -------------------------------------------------------------------------- | | Build | `kustomize build k8s/overlays/prod` | | Preview diff | `kubectl diff -k k8s/overlays/prod` | | Apply | `kubectl apply -k k8s/overlays/prod` | | Validate | `kustomize build k8s/overlays/prod \| kubectl apply --dry-run=client -f -` | | Migrate deprecated fields | `kustomize edit fix` (idempotent; run per dir; see Idioms) | | Set image tag | `kustomize edit set image myapp=registry/myapp:v1.2.3` | | Add ConfigMap | `kustomize edit add configmap app-config --from-literal=KEY=value` | **Generators** (`configMapGenerator` / `secretGenerator` items): `literals:` (`K=v`), `files:` (`app.properties`, or `alias=path`), `envs:` (`config.env`). Secrets add `type:` (e.g. `kubernetes.io/tls`). `behavior:` = `create` (default) | `merge` | `replace`. **Transformers** (top-level keys): `namespace`, `namePrefix`, `nameSuffix`, `labels` (use over deprecated `commonLabels`), `commonAnnotations`, `images` (`newName`/`newTag`/`digest`), `replicas` (`- name: x count: n`), `replacements`. ## Patch Strategies | Aspect | Strategic Merge (default) | JSON 6902 (RFC 6902) | | ------------- | ----------------------------------------------------------- | ------------------------------------------------------ | | Merge model | K8s-schema-aware; maps by key, lists merge on known key | `op` (`add`/`remove`/`replace`/`move`/`copy`/`test`) on JSON Pointer paths | | Best for | Field/env/resource-limit tweaks, adding containers | Precise array-index ops, conditional `test`, CRDs | | Whole-list replace | **Unreliable** — `$patch: replace` regressed (issue #2980, ignored/merged instead) | Reliable: `op: replace` on the list path | Both go under the unified `patches:` field, which auto-detects type from content and whose `target` supports `group/version/kind/name/namespace` + `labelSelector`/`annotationSelector` (one patch → many resources). `patchesStrategicMerge`/`patchesJson6902` are deprecated (v5.0.0) and gone from the v1 API. ## Components Reusable opt-in bundles for features only some environments need (monitoring, ingress, debug tools, security hardening). Use a **patch** instead for required, always-applied, or env-specific value tweaks. ```yaml # k8s/components/monitoring/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1alpha1 # alpha — API may change without deprecation window kind: Component resources: - servicemonitor.yaml patches: - path: patch-metrics.yaml target: {kind: Deployment} labels: - pairs: {prometheus.io/scrape: "true"} includeSelectors: false ``` > **Reference Components under `components:`, never `resources:`.** A Component placed under `resources:` is silently misapplied as a plain manifest; kustomize enforces the split (Components rejected from `resources:`, Kustomizations from `components:`). Components run against the parent's accumulated resource set and **can be nested**. ## Examples ### Base kustomization + Deployment ```yaml # k8s/base/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: myapp # Use the labels transformer, NOT deprecated commonLabels (which mutates the # IMMUTABLE spec.selector.matchLabels → delete/recreate on any later change). # includeSelectors defaults false (safe on live resources); includeTemplates # reaches pod templates. Define real selector labels directly in deployment.yaml. labels: - pairs: {app: myapp, managed-by: kustomize} includeSelectors: false includeTemplates: true commonAnnotations: {contact: team@example.com} resources: - deployment.yaml - service.yaml - serviceaccount.yaml configMapGenerator: - name: app-config literals: [LOG_LEVEL=info, MAX_CONNECTIONS=100] images: - name: myapp newName: registry.example.com/myapp newTag: latest ``` ```yaml # k8s/base/deployment.yaml (selector label defined explicitly — not injected) apiVersion: apps/v1 kind: Deployment metadata: {name: myapp} spec: replicas: 1 selector: matchLabels: {app: myapp} template: metadata: labels: {app: myapp} spec: serviceAccountName: myapp containers: - name: app image: myapp ports: [{containerPort: 8080, name: http}] envFrom: [{configMapRef: {name: app-config}}] resources: requests: {memory: 128Mi, cpu: 100m} limits: {memory: 256Mi, cpu: 200m} readinessProbe: httpGet: {path: /ready, port: http} initialDelaySeconds: 5 ``` ### Production overlay (annotated) ```yaml # k8s/overlays/prod/kustomization.yaml apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: myapp-prod labels: - pairs: {environment: prod, criticality: high} includeSelectors: false includeTemplates: true commonAnnotations: oncall: sre-team@example.com # SINGLE resources: block. A second resources: key later in the same document # silently wins (duplicate YAML map keys), dropping ../../base entirely. resources: - ../../base - poddisruptionbudget.yaml - horizontalpodautoscaler.yaml - networkpolicy.yaml patches: - path: patch-resources.yaml # bump requests/limits - path: patch-affinity.yaml # required podAntiAffinity + nodeAffinity - path: patch-security.yaml # runAsNonRoot, drop ALL, RO rootfs, seccomp configMapGenerator: - name: app-config behavior: merge envs: [config-values.env] secretGenerator: - name: app-secrets envs: [secrets.env] # gitignored / external-managed images: - name: myapp newTag: v1.2.3 digest: sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 # pin by digest in prod replicas: - {name: myapp, count: 5} components: - ../../components/monitoring - ../../components/ingress ``` Overlay patch files are minimal partial docs matched by `kind`/`name`, e.g. a security patch: ```yaml # patch-security.yaml apiVersion: apps/v1 kind: Deployment metadata: {name: myapp} spec: template: spec: securityContext: runAsNonRoot: true runAsUser: 1000 seccompProfile: {type: RuntimeDefault} containers: - name: app securityContext: allowPrivilegeEscalation: false readOnlyRootFilesystem: true capabilities: {drop: [ALL]} ``` ### JSON 6902 patch (precise array ops) ```yaml # kustomization.yaml patches: - path: json-patch.yaml target: {group: apps, version: v1, kind: Deployment, name: myapp} ``` ```yaml # json-patch.yaml — list of {op, path, value}; auto-detected as JSON 6902 - op: add # append sidecar path: /spec/template/spec/containers/- value: {name: log-shipper, image: fluent/fluent-bit:2.0} - op: replace # container 0 image path: /spec/template/spec/containers/0/image value: registry.example.com/myapp:v1.2.3 - op: remove # env var by index path: /spec/template/spec/containers/0/env/3 - op: test # conditional guard path: /spec/replicas value: 1 - op: replace path: /spec/replicas value: 5 ``` ### Generators ```yaml configMapGenerator: - name: app-config behavior: merge # create (default) | replace | merge literals: [LOG_LEVEL=debug] # overrides base key files: [app.properties, tls.crt=certs/server.crt] envs: [config.env] options: disableNameSuffixHash: true # ⚠ defeats config-driven rollouts (see Gotchas) secretGenerator: - name: tls-secrets files: [tls.crt, tls.key] type: kubernetes.io/tls - name: app-secrets envs: [secrets.env] # gitignored — never commit secrets ``` ### Replacements (propagate a field value) ```yaml replacements: # Propagate hashed ConfigMap name into the Deployment volume ref - source: {kind: ConfigMap, name: app-config, fieldPath: metadata.name} targets: - select: {kind: Deployment} fieldPaths: - spec.template.spec.volumes.[name=config].configMap.name ``` ### Remote bases ```yaml resources: - https://github.com/org/repo//k8s/base?ref=v1.0.0 # pin to tag or full SHA (see Security) ``` ## Common Tasks ```bash # Validate / preview kustomize build k8s/overlays/prod | kubectl apply --dry-run=server -f - kubectl diff -k k8s/overlays/prod # Inspect name/hash transformations kustomize build k8s/overlays/prod | rg '^ name:' kustomize build k8s/overlays/prod | rg -A2 'kind: ConfigMap' # Migrate deprecated fields in place (idempotent; wrap in a build-diff) kustomize edit fix # Bootstrap kustomization.yaml from existing manifests kustomize create --autodetect # or --resources deployment.yaml,service.yaml ``` ## GitOps & CI/CD Integration **ArgoCD**: `Application.spec.source.path: k8s/overlays/prod`, `syncPolicy.automated {prune, selfHeal}`. **Flux**: `kustomize.toolkit.fluxcd.io/v1 Kustomization` with `spec.path`, `prune: true`, `sourceRef` (GitRepository), `healthChecks`. Both bundle their **own** kustomize version — pin/match it (see Currency gotcha). Prefer the controller's authenticated Git source over remote bases in `resources:`. ```bash # CI: render, then validate. kubeval is unmaintained — use kubeconform. kustomize build "k8s/overlays/${OVERLAY}" > all.yaml kubeconform -strict -summary -kubernetes-version 1.29.0 all.yaml conftest test all.yaml # OPA policy gate ``` ### Helm inflation gotcha
عرض على GitHub
ملف SKILL.md هذا كبير جدا، لذلك يعرض SkillsMP القسم الاول فقط هنا. عرض على GitHub