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.
Directory structure
Section titled “Directory structure”A typical Kustomize layout for Nantian Gateway looks like this:
deploy/├── base/│ ├── kustomization.yaml│ ├── namespace.yaml│ ├── gatewayclass.yaml│ ├── controlplane/│ │ ├── deployment.yaml│ │ ├── service.yaml│ │ ├── configmap.yaml│ │ ├── rbac.yaml│ │ └── pdb.yaml│ ├── dataplane/│ │ ├── deployment.yaml│ │ ├── service.yaml│ │ ├── configmap.yaml│ │ └── pdb.yaml│ └── dashboard/│ ├── deployment.yaml│ └── service.yaml└── overlays/ ├── dev/ │ └── kustomization.yaml ├── staging/ │ └── kustomization.yaml └── production/ ├── kustomization.yaml ├── controlplane-patch.yaml ├── dataplane-patch.yaml └── tls-secret.yamlThe base/ directory contains the resource definitions shared across all environments. Each overlay in overlays/ patches the base for a specific environment.
Base kustomization
Section titled “Base kustomization”The base kustomization.yaml declares all resources and common labels:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomization
namespace: nantian-gw
resources: - namespace.yaml - gatewayclass.yaml - controlplane/deployment.yaml - controlplane/service.yaml - controlplane/configmap.yaml - controlplane/rbac.yaml - controlplane/pdb.yaml - dataplane/deployment.yaml - dataplane/service.yaml - dataplane/configmap.yaml - dataplane/pdb.yaml - dashboard/deployment.yaml - dashboard/service.yaml
commonLabels: app.kubernetes.io/name: nantian-gw app.kubernetes.io/part-of: nantian-gw
images: - name: nantian-controlplane newName: ghcr.io/nantian-gw/nantian-controlplane newTag: latest - name: nantian-dataplane newName: ghcr.io/nantian-gw/dataplane newTag: latestProduction overlay
Section titled “Production overlay”The production overlay patches the base with higher replica counts, resource limits, TLS configuration, and stricter security contexts:
apiVersion: kustomize.config.k8s.io/v1beta1kind: Kustomization
resources: - ../../base - tls-secret.yaml
patches: - path: controlplane-patch.yaml - path: dataplane-patch.yamlControl plane patch
Section titled “Control plane patch”apiVersion: apps/v1kind: Deploymentmetadata: name: nantian-gw-controlplanespec: 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-tlsData plane patch
Section titled “Data plane patch”apiVersion: apps/v1kind: Deploymentmetadata: name: nantian-gw-dataplanespec: 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"Applying
Section titled “Applying”kubectl apply -k deploy/overlays/productionKustomize merges the base with the overlay patches, builds the final manifests, and applies them to the cluster.
GitOps integration
Section titled “GitOps integration”If you’re using Argo CD, point the application at the overlay directory:
apiVersion: argoproj.io/v1alpha1kind: Applicationmetadata: name: nantian-gwspec: project: default source: repoURL: https://github.com/your-org/nantian-gw-deploy path: deploy/overlays/production targetRevision: main destination: server: https://kubernetes.default.svc namespace: nantian-gw syncPolicy: automated: prune: true selfHeal: trueConfigMap management
Section titled “ConfigMap management”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.yamlconfigMapGenerator: - name: nantian-gw-controlplane-config behavior: replace files: - config.yaml=controlplane-config.yamlThis is a cleaner pattern than embedding config in the Deployment patch, especially for larger configurations.