Skip to content

Deploying Applications

Kustomize organizes manifests into a base — the shared resources every environment needs — and overlays that extend the base with environment-specific additions. This guide walks through the docs app to show the pattern in practice.

The base lives at apps/base/docs/ and declares three resources in its kustomization.yaml:

resources:
- namespace.yaml
- deployment.yaml
- service.yaml
apiVersion: v1
kind: Namespace
metadata:
name: docs

Every resource for the docs app lives in the docs namespace. Declaring it explicitly means kubectl apply creates it if it doesn’t exist.

The deployment runs one replica of the cluster-docs:latest image. imagePullPolicy: Never tells Kubernetes to use the image already loaded into the local cluster rather than pulling from a registry — the right setting for a dev image built and imported locally.

spec:
replicas: 1
selector:
matchLabels:
app: docs
template:
metadata:
labels:
app: docs
spec:
containers:
- name: docs
image: cluster-docs:latest
imagePullPolicy: Never
ports:
- containerPort: 80
resources:
limits:
memory: 64Mi
cpu: 100m
requests:
memory: 32Mi
cpu: 50m

Both a liveness probe and a readiness probe hit GET / on port 80. The liveness probe starts after 5 seconds and runs every 10 seconds; the readiness probe is slightly tighter, starting at 3 seconds and running every 5.

spec:
type: ClusterIP
selector:
app: docs
ports:
- port: 80
targetPort: 80

A ClusterIP service routes traffic to any pod with the label app: docs. It is not reachable outside the cluster on its own — the overlay adds that.

The dev overlay lives at apps/overlays/dev/docs/. Its kustomization.yaml references the base and adds one more resource:

resources:
- ../../../base/docs
- ingressroute.yaml

Kustomize merges the base resources with the overlay’s additions. Anything in the base that the overlay doesn’t patch passes through unchanged.

The overlay adds a Traefik IngressRoute that exposes the service over HTTPS at docs.k8s.local:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: docs
namespace: docs
spec:
entryPoints:
- websecure
routes:
- match: Host(`docs.k8s.local`)
kind: Rule
services:
- name: docs
port: 80
tls: {}

Setting tls: {} activates TLS on this route. Traefik will only serve the route on the websecure entrypoint — it ignores the web (HTTP) entrypoint for routes with tls set. To also serve over HTTP, add a second IngressRoute targeting the web entrypoint (see the commented-out block in ingressroute.yaml).

Apply the dev overlay with kubectl:

Terminal window
kubectl apply -k apps/overlays/dev/docs

Kustomize builds the full manifest set — base resources plus overlay additions — and streams them to kubectl. To preview what would be applied without sending it to the cluster:

Terminal window
kubectl kustomize apps/overlays/dev/docs

Once the deployment rolls out, the docs site is available at https://docs.k8s.local.