Author a Kustomize artifact
After this guide, your service deploys onto Kubernetes as one Kustomize artifact of a vector. The Kubernetes deployer renders the bundle once per vector into the landscape.
The examples build a service named my-service and push everything to registry.example.com/my-org.
Prerequisites
Before you begin, make sure you have:
- A container build tool such as
dockerand thefluxcommand-line tool for pushing Open Container Initiative (OCI) artifacts. - Push access to an OCI registry for the image, the bundle, and the artifact.
- The
kdencommand-line tool. See Publish artifacts. - A landscape with a ready
kustomize.konfidence.cloudtarget. See Configure deployment targets for a landscape. - A service that reads and forwards
X-Vector-ID. See Prepare your application.
Build and push the container image
Create a
Dockerfilein your service directory. The following example copies a prebuilt binary into a small base image. Replace the build with your own toolchain.dockerfileFROM alpine:3.20 COPY my-service /usr/local/bin/my-service EXPOSE 8080 ENTRYPOINT ["my-service"]Build and push the image with the version you plan to release:
bashdocker build -t registry.example.com/my-org/my-service:1.0.0 . docker push registry.example.com/my-org/my-service:1.0.0
The registry lists my-service:1.0.0 afterward.
Create a minimal bundle
Create a directory manifests/ with a kustomization.yaml at its root and the manifests it lists.
Create
manifests/kustomization.yaml:yamlapiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployment.yaml - service.yamlCreate
manifests/deployment.yaml:yamlapiVersion: apps/v1 kind: Deployment metadata: name: my-service spec: replicas: 1 selector: matchLabels: app: my-service template: metadata: labels: app: my-service spec: containers: - name: my-service image: registry.example.com/my-org/my-service:1.0.0 ports: - containerPort: 8080Create
manifests/service.yaml:yamlapiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-service ports: - port: 80 targetPort: 8080
The bundle renders one Deployment and one Service.
Package and push the bundle
Push the manifests/ directory as a Flux-compatible OCI artifact:
flux push artifact oci://registry.example.com/my-org/my-service-manifests:1.0.0 \
--path=./manifests \
--source=https://github.com/my-org/my-service \
--revision=1.0.0The bundle is available as registry.example.com/my-org/my-service-manifests:1.0.0.
Reference the bundle from the artifact component
Create
manifest.jsonwith the Kustomize type:json{ "type": "kustomize.konfidence.cloud", "allowReuse": false }Set
allowReusetotrueonly when one running instance can serve several vectors.Create
component-constructor.yamlwith the manifest and the bundle as resources:yamlcomponents: - name: github.com/my-org/my-service version: 1.0.0 provider: name: my-org resources: - name: my-service-manifest type: cloud.konfidence.artifact.manifest version: 1.0.0 relation: local input: type: file/v1 path: ./manifest.json - name: my-service-manifests type: kustomize version: 1.0.0 relation: external access: type: ociArtifact imageReference: registry.example.com/my-org/my-service-manifests:1.0.0The component carries exactly one resource of type
kustomize.
Expect a suffix on every resource name
Several vectors deploy the same bundle into one landscape namespace. The deployer appends a suffix to every resource name so the instances coexist. The final name follows this pattern:
<name-in-your-manifest>-<artifact-version>-<hash>For the Service my-service in artifact version v1.0.0 with hash abc12345, the applied Service is named my-service-v1-0-0-abc12345. Kustomize updates references between resources in the bundle, so a Deployment that mounts a ConfigMap by name keeps working.
The suffix changes the DNS name of your Service. Do not hard-code the names of other Services in your code. Read them at runtime as described in Add deployment results to an artifact.
Do not set nameSuffix or namespace in your kustomization.yaml. The deployer overwrites both before it renders the bundle and discards your values.
The deployer owns the rendered instance: its name suffix, its namespace, and its labels. Everything in the bundle is duplicated per instance. Deliver resources that must exist once per cluster, such as a CustomResourceDefinition, through a separate delivery path.
Fields the deployer sets on the Kustomization
The deployer creates one Flux Kustomization per artifact instance and sets these fields. Your bundle cannot override them.
| Field | Value |
|---|---|
metadata.name | The ArtifactDeployment name |
spec.sourceRef | The OCIRepository with the same name |
spec.targetNamespace | The landscape namespace |
spec.nameSuffix | -<sanitized-artifact-version>-<hash>, derived from the artifact version and hash |
spec.commonMetadata.labels | konfidence.cloud/artifact-deployment=<artifact-deployment-name> |
Verify the result
Render the bundle locally and confirm that it contains no field the deployer owns:
kubectl kustomize ./manifests
grep -E 'nameSuffix|namespace' ./manifests/kustomization.yamlThe first command prints the Deployment and the Service. The second command prints nothing.
Next steps
Use the following guides to publish your artifact and expose its Service:
- Validate and publish the artifact.
- Add deployment results to an artifact to expose the Service to other services in the vector.
- Read Kubernetes deployer for supported manifest types and deployment-result behavior.