Explore plans starting at ₹699/mo →
DevOps

GitOps Workflow for Kubernetes Deployments: Declarative Infrastructure

S
ServerRaja
11 min read
#Infrastructure#Automation#DevOps#Best Practices#CI/CD#Containers#Kubernetes
GitOps Workflow for Kubernetes Deployments: Declarative Infrastructure

What is GitOps?

GitOps is an operational framework where Git repositories serve as the single source of truth for infrastructure and application deployments. Instead of running imperative commands like `kubectl apply`, you declare your desired state in Git, and a GitOps operator continuously reconciles your cluster to match that state.

This approach brings version control, audit trails, and automated rollbacks to Kubernetes operations. When running Kubernetes on ServerRaja cloud servers, GitOps provides a robust deployment model that scales with your team.

Core Principles of GitOps

GitOps rests on four key principles:

  • **Declarative Configuration**: The entire system state is described declaratively in YAML or Helm charts stored in Git
  • **Version Controlled**: Every change to infrastructure or applications goes through a Git commit, providing a complete audit history
  • **Automated Delivery**: Approved changes in Git are automatically applied to your cluster without manual intervention
  • **Continuous Reconciliation**: The GitOps agent constantly watches for drift between the desired state in Git and the actual cluster state

Repository Structure for GitOps

Organize your GitOps repository to separate application code from deployment configuration:

gitops-repo/
├── apps/
│   ├── frontend/
│   │   ├── base/
│   │   │   ├── kustomization.yaml
│   │   │   ├── deployment.yaml
│   │   │   ├── service.yaml
│   │   │   └── ingress.yaml
│   │   └── overlays/
│   │       ├── staging/
│   │       │   └── kustomization.yaml
│   │       └── production/
│   │           └── kustomization.yaml
│   └── backend/
│       ├── base/
│       └── overlays/
├── infrastructure/
│   ├── cert-manager/
│   ├── ingress-nginx/
│   ├── monitoring/
│   └── sealed-secrets/
└── clusters/
    ├── staging/
    └── production/

Setting Up ArgoCD

Install ArgoCD on your Kubernetes cluster:

# Create the namespace
kubectl create namespace argocd

# Install ArgoCD kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml

# Wait for pods to be ready kubectl wait --for=condition=Ready pods --all -n argocd --timeout=300s

# Get the initial admin password kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d

# Access the ArgoCD UI via port forward kubectl port-forward svc/argocd-server -n argocd 8080:443

# Install ArgoCD CLI curl -sSL -o argocd https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64 chmod +x argocd sudo mv argocd /usr/local/bin/

# Login via CLI argocd login localhost:8080 --username admin --password <password> --insecure ```

Defining an ArgoCD Application

Create an Application resource that points to your Git repository:

# argocd-app.yaml
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: frontend-production
  namespace: argocd
spec:
  project: default
  source:
    repoURL: https://github.com/yourorg/gitops-repo.git
    targetRevision: main
    path: apps/frontend/overlays/production
  destination:
    server: https://kubernetes.default.svc
    namespace: production
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
      - CreateNamespace=true
    retry:
      limit: 5
      backoff:
        duration: 5s
        factor: 2
        maxDuration: 3m

Apply it to your cluster:

kubectl apply -f argocd-app.yaml

Using Kustomize for Environment Management

Kustomize lets you customize base configurations for different environments:

# apps/frontend/base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 2
  selector:
    matchLabels:
      app: frontend
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
        - name: frontend
          image: yourorg/frontend:latest
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: 100m
              memory: 128Mi
            limits:
              cpu: 500m
              memory: 512Mi
# apps/frontend/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - ../../base
namespace: production
patches:
  - target:
      kind: Deployment
      name: frontend
    patch: |
      - op: replace
        path: /spec/replicas
        value: 5
      - op: replace
        path: /spec/template/spec/containers/0/resources/requests/cpu
        value: 250m

Flux as an Alternative GitOps Operator

Flux is another popular GitOps tool by the FluxCD project:

# Install Flux CLI
curl -s https://fluxcd.io/install.sh | sudo bash

# Bootstrap Flux on your cluster flux bootstrap github \ --owner=yourorg \ --repository=gitops-repo \ --branch=main \ --path=clusters/production \ --personal ```

Create a Flux Kustomization:

apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: frontend
  namespace: flux-system
spec:
  interval: 10m
  path: ./apps/frontend/overlays/production
  prune: true
  sourceRef:
    kind: GitRepository
    name: gitops-repo
  healthChecks:
    - apiVersion: apps/v1
      kind: Deployment
      name: frontend
      namespace: production

Handling Secrets in GitOps

Never store plain-text secrets in Git. Use Sealed Secrets or External Secrets:

# Install Sealed Secrets controller
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.24.0/controller.yaml

# Install kubeseal CLI kubeseal --fetch-cert > pub-cert.pem

# Seal a secret echo -n mydbpassword | kubectl create secret generic db-pass --dry-run=client --from-file=password=/dev/stdin -o yaml | kubeseal --cert pub-cert.pem > sealed-db-pass.yaml

# Commit sealed-db-pass.yaml safely to Git git add sealed-db-pass.yaml && git commit -m "Add sealed database password" ```

Deployment Workflow

The typical GitOps deployment workflow follows these steps:

1. Developer pushes application code to the app repository 2. CI pipeline builds, tests, and pushes a new container image 3. CI pipeline updates the image tag in the GitOps repository 4. GitOps operator detects the change in Git 5. Operator automatically syncs the new configuration to the cluster 6. If sync fails, the operator retries based on the configured policy

To roll back, simply revert the Git commit:

git revert HEAD
git push origin main
# ArgoCD or Flux automatically rolls back the deployment

Conclusion

GitOps brings the rigor of version control to Kubernetes operations. By storing your desired state in Git and using ArgoCD or Flux for automatic reconciliation, you get auditable, repeatable, and rollback-friendly deployments. ServerRaja Kubernetes clusters work seamlessly with both GitOps tools, giving your team confidence in every deployment.

GitOps for Kubernetes Deployments | ServerRaja