Deploying a New Service¶
This guide walks through deploying a new service to the Kubernetes cluster using GitOps.
Prerequisites¶
- Git repository access
- kubectl configured with cluster access
- Basic understanding of Kubernetes resources
Step 1: Create the App Directory Structure¶
Example for deploying my-app in the default namespace:
Step 2: Create the HelmRelease (or Deployment)¶
Option A: Using a Helm Chart¶
Create kubernetes/apps/default/my-app/app/helmrelease.yaml:
---
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: my-app
spec:
interval: 30m
chart:
spec:
chart: my-app
version: 1.0.0
sourceRef:
kind: HelmRepository
name: my-repo
namespace: flux-system
values:
# Your Helm values here
replicaCount: 2
image:
repository: my-app
tag: latest
Option B: Using Raw Manifests¶
Create kubernetes/apps/default/my-app/app/deployment.yaml:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
Step 3: Create the HTTPRoute (Ingress)¶
Create kubernetes/apps/default/my-app/app/httproute.yaml:
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: my-app
spec:
parentRefs:
- name: envoy-internal
namespace: network
hostnames:
- "my-app.ragas.cc"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: my-app
port: 80
Step 4: Create the Kustomization¶
Create kubernetes/apps/default/my-app/app/kustomization.yaml:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- helmrelease.yaml # or deployment.yaml
- httproute.yaml
Step 5: Create the Flux Kustomization¶
Create kubernetes/apps/default/my-app/ks.yaml:
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: my-app
namespace: flux-system
spec:
targetNamespace: default
commonMetadata:
labels:
app.kubernetes.io/name: my-app
path: ./kubernetes/apps/default/my-app/app
prune: true
sourceRef:
kind: GitRepository
name: flux-system
wait: true
interval: 30m
timeout: 5m
Step 6: Update Parent Kustomization¶
Edit kubernetes/apps/default/kustomization.yaml to include your app:
---
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- echo/ks.yaml
- homepage/ks.yaml
- my-app/ks.yaml # Add this line
Step 7: Commit and Push¶
Step 8: Monitor Deployment¶
# Watch Flux reconciliation
flux get ks -A --watch
# Check HelmRelease status
flux get hr -A
# Check pods
kubectl get pods -n default -l app=my-app
# Check HTTPRoute
kubectl get httproute -A
Step 9: Verify Access¶
- Ensure DNS is configured (AdGuard should forward to k8s_gateway)
- Access https://my-app.ragas.cc
- Check certificate status:
Troubleshooting¶
App not deploying¶
# Check Flux logs
flux logs --kind=Kustomization --name=my-app
# Check HelmRelease status
kubectl describe hr my-app -n default
HTTPRoute not working¶
# Check gateway status
kubectl get gateway -n network
# Check route status
kubectl describe httproute my-app -n default
# Check Envoy logs
kubectl logs -n network -l app.kubernetes.io/name=envoy
Certificate issues¶
# Check cert-manager logs
kubectl logs -n cert-manager -l app=cert-manager
# Check certificate status
kubectl describe certificate -n network
Best Practices¶
- Use HelmRelease for complex apps with many config options
- Pin versions - never use
latestin production - Add health checks to your deployments
- Use resource limits to prevent resource exhaustion
- Enable PodDisruptionBudgets for HA apps
- Use SOPS for secrets, never commit plain secrets