Deploy Your First Application
Purpose: For app developers and platform engineers, walks through deploying a sample application on an openCenter cluster using the multi-team GitOps workflow with Gateway API routing and TLS (15 minutes).
What You'll Do
- Create an application repository with Kubernetes manifests, Gateway API routing, and TLS
- Register the application with FluxCD in the cluster overlay repo
- Verify the deployment, HTTPRoute, and TLS certificate
End result: A running application exposed via Gateway API with automatic TLS from cert-manager, deployed and reconciled by FluxCD using the multi-team GitOps pattern from openCenter-customer-app-example.
Prerequisites
- A running openCenter cluster (any provider — Quick Start if you need one)
kubectlconfigured to access the cluster- FluxCD bootstrapped and reconciling (
flux get kustomizationsshowsReady=True) - Gateway API and cert-manager services deployed (included by default in all openCenter clusters)
- Git CLI installed
How Application Deployment Works
openCenter uses a multi-team GitOps model (demonstrated in openCenter-customer-app-example):
- Platform team creates
GitRepository+Kustomizationmanifests in the cluster overlay repo to watch application repos - App team manages their own repository with Kubernetes manifests — Deployments, Services, HTTPRoutes
FluxCD reconciles both continuously.
Step 1: Create Your Application Repository
mkdir my-app && cd my-app
git init
Create the Kustomize root kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gateway-resources/
- app/
Step 2: Define Gateway Resources
Gateway API provides standardized ingress routing. Create shared gateway resources:
mkdir -p gateway-resources
Create gateway-resources/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- gateway.yaml
Create gateway-resources/gateway.yaml:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: app-gateway
namespace: my-app
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
gatewayClassName: eg
listeners:
- name: https
port: 443
protocol: HTTPS
hostname: my-app.example.com
allowedRoutes:
namespaces:
from: Same
tls:
mode: Terminate
certificateRefs:
- kind: Secret
name: my-app-tls
The cert-manager.io/cluster-issuer annotation tells cert-manager to automatically issue and renew the TLS certificate referenced by my-app-tls.
Step 3: Create Application Manifests
mkdir -p app
Create app/kustomization.yaml:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- deployment.yaml
- service.yaml
- httproute.yaml
Create app/namespace.yaml:
apiVersion: v1
kind: Namespace
metadata:
name: my-app
Create app/deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: my-app
labels:
app: web
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
Create app/service.yaml:
apiVersion: v1
kind: Service
metadata:
name: web-app
namespace: my-app
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
Create app/httproute.yaml:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: web-app
namespace: my-app
spec:
hostnames:
- my-app.example.com
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: app-gateway
namespace: my-app
sectionName: https
rules:
- backendRefs:
- kind: Service
name: web-app
port: 80
matches:
- path:
type: PathPrefix
value: /
Step 4: Push the Application Repository
git add .
git commit -m "feat: initial application deployment"
git remote add origin git@github.com:your-org/my-app.git
git push -u origin main
Step 5: Platform Team Registers the Application
The platform team adds these manifests to the cluster overlay repository (not the app repo):
Create managed-services/my-app/source.yaml:
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: my-app
namespace: flux-system
spec:
interval: 1m
url: https://github.com/your-org/my-app
ref:
branch: main
Create managed-services/my-app/kustomization.yaml:
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
interval: 10m
prune: true
wait: true
path: ./
sourceRef:
kind: GitRepository
name: my-app
Commit and push to the cluster overlay repo. FluxCD detects the change and deploys the application.
Step 6: Verify the Deployment
# Watch FluxCD pick up the change
flux get kustomizations --watch
# Check application pods
kubectl get pods -n my-app
# Check the HTTPRoute is attached to the Gateway
kubectl get httproutes -n my-app
# Check the TLS certificate is issued
kubectl get certificates -n my-app
Check Your Work
- Namespace
my-appexists - Two
web-apppods are Running - HTTPRoute shows
Accepted=True - cert-manager issued a certificate (
kubectl get cert -n my-appshowsReady=True) - FluxCD kustomization
my-appshowsReady=True
Validation Before Commit
Run locally before pushing:
kustomize build .
kubeconform <(kustomize build .)
Next Steps
- Deploying Applications — Full application deployment patterns
- Add a Helm Application — Deploy Helm charts via GitOps (see
app2/in the example repo) - Multi-Team GitOps — Separation of concerns between platform and app teams
- Configure Gateway & TLS — Advanced Gateway API configuration