Skip to content

Kustomize Installation

Kustomize gives you a declarative, patch-based approach to deploying Nantian Gateway. Instead of templating, you define a base set of manifests and layer environment-specific patches on top. This works especially well with GitOps tools like Argo CD and Flux, where every change is a commit to a Git repository.

This guide assumes you’re familiar with Kustomize basics. If you haven’t used it before, the Kustomize documentation is a good place to start.

A typical Kustomize layout for Nantian Gateway looks like this:

deploy/kubernetes/
├── base/
│ ├── kustomization.yaml
│ ├── namespace-gatewayclass.yaml
│ ├── priorityclass.yaml
│ ├── rbac.yaml
│ ├── controlplane.yaml
│ ├── dataplane.yaml
│ ├── dashboard.yaml
│ ├── services-networkpolicy.yaml
│ ├── aiservice-crd.yaml
│ ├── tokenpolicy-crd.yaml
│ └── wasmplugin-crd.yaml
└── overlays/
├── kind/
├── kind-conformance/
├── kind-hostnetwork/
├── kind-pprof/
├── observability-enabled/
└── production/

The base/ directory contains the resource definitions shared across all environments. Each overlay in overlays/ patches the base for a specific environment.

The base kustomization.yaml declares all resources and common labels:

deploy/kubernetes/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace-gatewayclass.yaml
- priorityclass.yaml
- rbac.yaml
- controlplane.yaml
- dataplane.yaml
- dashboard.yaml
- services-networkpolicy.yaml
- aiservice-crd.yaml
- tokenpolicy-crd.yaml
- wasmplugin-crd.yaml
generatorOptions:
disableNameSuffixHash: true
configMapGenerator:
- name: nantian-gw-controlplane-config
namespace: nantian-gw
files:
- config.yaml=../../../configs/controlplane/config.yaml
- name: nantian-gw-dataplane-config
namespace: nantian-gw
files:
- config.yaml=../../../configs/dataplane/config.yaml

The production overlay patches the base with higher replica counts, resource limits, TLS configuration, and stricter security contexts:

deploy/kubernetes/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
- tls-secret.yaml
patches:
- path: controlplane-patch.yaml
- path: dataplane-patch.yaml
deploy/kubernetes/overlays/production/controlplane-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nantian-gw-controlplane
spec:
replicas: 3
template:
spec:
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
containers:
- name: controlplane
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
resources:
requests:
cpu: "200m"
memory: "256Mi"
limits:
cpu: "1"
memory: "1Gi"
volumeMounts:
- name: grpc-tls
mountPath: /etc/nantian-gw/grpc-tls
readOnly: true
volumes:
- name: grpc-tls
secret:
secretName: nantian-grpc-tls
deploy/kubernetes/overlays/production/dataplane-patch.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nantian-gw-dataplane
spec:
replicas: 4
template:
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
app.kubernetes.io/component: dataplane
topologyKey: kubernetes.io/hostname
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app.kubernetes.io/component: dataplane
securityContext:
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
fsGroup: 65532
containers:
- name: dataplane
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: [ALL]
add: [NET_BIND_SERVICE]
resources:
requests:
cpu: "2"
memory: "512Mi"
limits:
memory: "2Gi"

The base kustomization.yaml references config files outside the kustomize root directory, which requires relaxed load restrictions:

Terminal window
kustomize build deploy/kubernetes/overlays/production \
--load-restrictor LoadRestrictionsNone | kubectl apply -f -

Kustomize merges the base with the overlay patches, builds the final manifests, and applies them to the cluster.

If you’re using Argo CD, point the application at the overlay directory:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: nantian-gw
spec:
project: default
source:
repoURL: https://github.com/your-org/nantian-gw-deploy
path: deploy/kubernetes/overlays/production
targetRevision: main
destination:
server: https://kubernetes.default.svc
namespace: nantian-gw
syncPolicy:
automated:
prune: true
selfHeal: true

Kustomize’s configMapGenerator can replace the manual ConfigMap approach. Define your config in a separate file and let Kustomize generate the ConfigMap with a content hash suffix. This triggers a rolling update whenever the config changes:

# In the overlay kustomization.yaml
configMapGenerator:
- name: nantian-gw-controlplane-config
behavior: replace
files:
- config.yaml=controlplane-config.yaml

This is a cleaner pattern than embedding config in the Deployment patch, especially for larger configurations.