mirror of
https://github.com/fosrl/docs-v2.git
synced 2026-09-22 13:59:08 +02:00
docs(self-host/kubernetes): add Kubernetes deployment guides with Helm, Kustomize, Helmfile, and GitOps for Newt and Pangolin
Signed-off-by: Marc Schäfer <git@marcschaeferger.de>
This commit is contained in:
@@ -0,0 +1,468 @@
|
||||
---
|
||||
title: "Argo CD"
|
||||
description: "Deploy Pangolin and Newt using Argo CD for Git-driven GitOps reconciliation."
|
||||
---
|
||||
|
||||
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
|
||||
|
||||
<PangolinCloudTocCta />
|
||||
|
||||
|
||||
Argo CD is a declarative GitOps tool that continuously syncs your cluster state to your Git repository. This guide covers installing Pangolin and Newt using Argo CD.
|
||||
|
||||
## Argo CD overview
|
||||
|
||||
Argo CD watches your Git repository (or Helm chart repository) and automatically reconciles Kubernetes resources to match the desired state defined in Git.
|
||||
|
||||
**Key concepts**:
|
||||
|
||||
- **Application**: Argo CD custom resource that defines what to deploy, where, and how
|
||||
- **Helm source**: Argo CD uses Helm to render charts; you provide values
|
||||
- **Kustomize source**: Argo CD uses Kustomize to build manifests
|
||||
- **Sync**: Process of applying desired state to the cluster
|
||||
- **Drift**: When cluster state diverges from Git (Argo CD can detect and correct)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Argo CD installed in your cluster (in `argocd` namespace, typically)
|
||||
- Helm repo configured: `helm repo add fossorial https://charts.fossorial.io`
|
||||
- Git repository with Argo CD configuration (optional, can use chart repo as source)
|
||||
- Newt auth secret (if installing Newt)
|
||||
|
||||
## Install Argo CD
|
||||
|
||||
If you don't have Argo CD yet:
|
||||
|
||||
```bash
|
||||
# Create namespace
|
||||
kubectl create namespace argocd
|
||||
|
||||
# Install Argo CD
|
||||
helm repo add argo https://argoproj.github.io/argo-helm
|
||||
helm repo update argo
|
||||
helm install argocd argo/argo-cd -n argocd
|
||||
```
|
||||
|
||||
Access the Argo CD UI:
|
||||
|
||||
```bash
|
||||
# Port-forward
|
||||
kubectl port-forward -n argocd svc/argocd-server 8080:443
|
||||
|
||||
# Visit https://localhost:8080
|
||||
# Default username: admin
|
||||
# Password: kubectl get secret -n argocd argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
|
||||
```
|
||||
|
||||
## Install Pangolin with Argo CD using Helm
|
||||
|
||||
### Step 1: Create Pangolin namespace
|
||||
|
||||
```bash
|
||||
kubectl create namespace pangolin
|
||||
```
|
||||
|
||||
### Step 2: Create Application
|
||||
|
||||
Create an Argo CD Application resource that tells Argo CD to deploy Pangolin using the Helm chart:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: https://charts.fossorial.io
|
||||
chart: pangolin
|
||||
targetRevision: 0.1.0-alpha.0 # or use ~0.1.0 for range
|
||||
helm:
|
||||
values: |
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
|
||||
database:
|
||||
mode: cloudnativepg
|
||||
|
||||
pangolin:
|
||||
config:
|
||||
app:
|
||||
dashboard_url: https://pangolin.example.com
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: example.com
|
||||
gerbil:
|
||||
base_endpoint: vpn.example.com
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
hosts:
|
||||
- host: pangolin.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: pangolin-tls
|
||||
hosts:
|
||||
- pangolin.example.com
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: pangolin
|
||||
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
Apply the Application:
|
||||
|
||||
```bash
|
||||
kubectl apply -f pangolin-app.yaml
|
||||
```
|
||||
|
||||
### Step 3: Monitor in Argo CD
|
||||
|
||||
In the Argo CD UI, you should see the `pangolin` application. Argo CD will:
|
||||
|
||||
1. Fetch the Helm chart from `https://charts.fossorial.io`
|
||||
2. Render the chart with your inline `values`
|
||||
3. Create all resources in the `pangolin` namespace
|
||||
4. Continuously monitor for drift
|
||||
|
||||
### Step 4: Verify deployment
|
||||
|
||||
```bash
|
||||
# Check Argo CD status
|
||||
kubectl describe app -n argocd pangolin
|
||||
|
||||
# Check pod status
|
||||
kubectl get pods -n pangolin
|
||||
```
|
||||
|
||||
## Install Newt with Argo CD using Helm
|
||||
|
||||
### Step 1: Create Newt auth secret
|
||||
|
||||
```bash
|
||||
kubectl create secret generic newt-auth \
|
||||
-n pangolin \
|
||||
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
|
||||
--from-literal=NEWT_ID=<your-newt-id> \
|
||||
--from-literal=NEWT_SECRET=<your-newt-secret>
|
||||
```
|
||||
|
||||
### Step 2: Create Newt Application
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: newt
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: https://charts.fossorial.io
|
||||
chart: newt
|
||||
targetRevision: 1.4.0
|
||||
helm:
|
||||
values: |
|
||||
newtInstances:
|
||||
- name: main-tunnel
|
||||
enabled: true
|
||||
auth:
|
||||
existingSecretName: newt-auth
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: pangolin
|
||||
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
Apply:
|
||||
|
||||
```bash
|
||||
kubectl apply -f newt-app.yaml
|
||||
```
|
||||
|
||||
## Using Argo CD with Git repository
|
||||
|
||||
Instead of inline values, you can store configuration in Git and have Argo CD deploy from there:
|
||||
|
||||
### Repository structure
|
||||
|
||||
```
|
||||
infrastructure/
|
||||
├── apps/
|
||||
│ ├── pangolin/
|
||||
│ │ ├── values-base.yaml
|
||||
│ │ ├── values-prod.yaml
|
||||
│ │ └── app.yaml (Argo CD Application CRD)
|
||||
│ └── newt/
|
||||
│ ├── values.yaml
|
||||
│ └── app.yaml
|
||||
└── clusters/
|
||||
└── production/
|
||||
├── pangolin.yaml (reference to app)
|
||||
└── newt.yaml
|
||||
```
|
||||
|
||||
### Git-based Application
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: https://github.com/my-org/infrastructure
|
||||
path: apps/pangolin
|
||||
targetRevision: main
|
||||
helm:
|
||||
valuesObject:
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
releaseName: pangolin
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: pangolin
|
||||
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
Argo CD will watch the Git repository and auto-sync on changes to `apps/pangolin`.
|
||||
|
||||
## Using Argo CD with Kustomize
|
||||
|
||||
Deploy Pangolin using Kustomize overlays:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
|
||||
source:
|
||||
repoURL: https://github.com/my-org/infrastructure
|
||||
path: overlays/production
|
||||
targetRevision: main
|
||||
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: pangolin
|
||||
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
## Sync policies
|
||||
|
||||
### Automated sync
|
||||
|
||||
**prune: true**: Deletes resources in cluster that are no longer in Git
|
||||
|
||||
**selfHeal: true**: Resyncs if cluster drifts from Git (e.g., manual `kubectl apply`)
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
allowEmpty: false # prevent accidental deletion of all resources
|
||||
```
|
||||
|
||||
### Manual sync
|
||||
|
||||
Sync only when you explicitly trigger it:
|
||||
|
||||
```yaml
|
||||
syncPolicy:
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
|
||||
Manually sync:
|
||||
|
||||
```bash
|
||||
argocd app sync pangolin
|
||||
# or use UI
|
||||
```
|
||||
|
||||
## Advanced: ApplicationSet for multi-environment
|
||||
|
||||
Deploy Pangolin and Newt across multiple clusters or environments:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: ApplicationSet
|
||||
metadata:
|
||||
name: pangolin-multienv
|
||||
namespace: argocd
|
||||
spec:
|
||||
generators:
|
||||
- list:
|
||||
elements:
|
||||
- cluster: production
|
||||
env: prod
|
||||
- cluster: staging
|
||||
env: staging
|
||||
template:
|
||||
metadata:
|
||||
name: pangolin-{{ .cluster }}
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://github.com/my-org/infrastructure
|
||||
path: clusters/{{ .cluster }}/pangolin
|
||||
targetRevision: main
|
||||
destination:
|
||||
name: '{{ .cluster }}'
|
||||
namespace: pangolin
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
## OCI Helm sources (if available)
|
||||
|
||||
If the Helm chart is available in an OCI registry:
|
||||
|
||||
```yaml
|
||||
source:
|
||||
repoURL: oci://registry.example.com/fossorial
|
||||
chart: pangolin
|
||||
targetRevision: 0.1.0-alpha.0
|
||||
helm:
|
||||
values: |
|
||||
# ... values ...
|
||||
```
|
||||
|
||||
OCI chart references work the same as traditional Helm repository references in Argo CD.
|
||||
|
||||
## Troubleshooting Argo CD deployments
|
||||
|
||||
### Check Application status
|
||||
|
||||
```bash
|
||||
kubectl describe app -n argocd pangolin
|
||||
kubectl get app -n argocd pangolin -o yaml
|
||||
```
|
||||
|
||||
### Check sync status
|
||||
|
||||
```bash
|
||||
argocd app get pangolin
|
||||
argocd app logs pangolin
|
||||
```
|
||||
|
||||
### Manual sync
|
||||
|
||||
```bash
|
||||
argocd app sync pangolin --force
|
||||
```
|
||||
|
||||
### Refresh from repository
|
||||
|
||||
```bash
|
||||
argocd app diff pangolin
|
||||
```
|
||||
|
||||
### Delete Application
|
||||
|
||||
```bash
|
||||
kubectl delete app -n argocd pangolin
|
||||
```
|
||||
|
||||
## Common patterns
|
||||
|
||||
### Different values per environment
|
||||
|
||||
Use multiple Applications:
|
||||
|
||||
```yaml
|
||||
# production/pangolin-app.yaml
|
||||
spec:
|
||||
source:
|
||||
helm:
|
||||
values: |
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 2Gi
|
||||
replicas: 3
|
||||
|
||||
# staging/pangolin-app.yaml
|
||||
spec:
|
||||
source:
|
||||
helm:
|
||||
values: |
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
replicas: 1
|
||||
```
|
||||
|
||||
### Secrets with sealed-secrets
|
||||
|
||||
Use sealed-secrets to safely store secrets in Git:
|
||||
|
||||
```yaml
|
||||
# In Git
|
||||
apiVersion: bitnami.com/v1alpha1
|
||||
kind: SealedSecret
|
||||
metadata:
|
||||
name: newt-auth
|
||||
namespace: pangolin
|
||||
spec:
|
||||
encryptedData:
|
||||
PANGOLIN_ENDPOINT: AgC4F5qd...
|
||||
NEWT_ID: AgB9l2pK...
|
||||
NEWT_SECRET: AgDq3jX...
|
||||
```
|
||||
|
||||
Argo CD applies the sealed secret; the cluster decrypts it.
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="GitOps Overview" href="/self-host/manual/kubernetes/gitops/overview" icon="code-branch" />
|
||||
<Card title="Flux" href="/self-host/manual/kubernetes/gitops/flux" icon="code-branch" />
|
||||
<Card title="Pangolin Configuration" href="/self-host/manual/kubernetes/pangolin/configuration" icon="sliders" />
|
||||
<Card title="Troubleshooting" href="/self-host/manual/kubernetes/pangolin/troubleshooting" icon="circle-question" />
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,559 @@
|
||||
---
|
||||
title: "Flux"
|
||||
description: "Deploy Pangolin and Newt using Flux for Git-driven GitOps reconciliation."
|
||||
---
|
||||
|
||||
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
|
||||
|
||||
<PangolinCloudTocCta />
|
||||
|
||||
|
||||
Flux is a declarative GitOps tool that uses Kubernetes-native Custom Resources to manage deployments. This guide covers installing Pangolin and Newt using Flux.
|
||||
|
||||
## Flux overview
|
||||
|
||||
Flux watches your Git repository and continuous reconciles cluster state using Kubernetes CRDs:
|
||||
|
||||
- **HelmRepository**: Defines a Helm chart repository
|
||||
- **HelmRelease**: Declaratively manages a Helm chart deployment
|
||||
- **GitRepository**: References a Git repository
|
||||
- **Kustomization**: Reconciles Kustomize overlays
|
||||
- **OCIRepository**: References an OCI-based container registry (for Helm charts)
|
||||
|
||||
**Key benefits**:
|
||||
|
||||
- Native Kubernetes reconciliation (no separate UI needed, though one exists)
|
||||
- Lightweight footprint
|
||||
- Excellent for multi-cluster deployments
|
||||
- Declarative everything: sources, releases, dependencies
|
||||
|
||||
## Flux prerequisites
|
||||
|
||||
- Kubernetes 1.25+
|
||||
- `flux` CLI installed: [Flux install guide](https://fluxcd.io/flux/installation/)
|
||||
- Git repository for configuration (optional, can use built-in sources)
|
||||
- GitHub, GitLab, or other Git provider account (optional)
|
||||
|
||||
Install Flux CLI:
|
||||
|
||||
```bash
|
||||
# macOS/Linux with brew
|
||||
brew install flux
|
||||
|
||||
# or curl
|
||||
curl -s https://fluxcd.io/install.sh | sudo bash
|
||||
|
||||
# Verify
|
||||
flux --version
|
||||
```
|
||||
|
||||
## Install Flux on your cluster
|
||||
|
||||
### Option 1: Bootstrap Flux from GitHub
|
||||
|
||||
Flux `bootstrap` automatically installs Flux and configures Git sync:
|
||||
|
||||
```bash
|
||||
flux bootstrap github \
|
||||
--owner=my-org \
|
||||
--repo=infrastructure \
|
||||
--personal \
|
||||
--path=clusters/production
|
||||
```
|
||||
|
||||
This creates the Git repository structure and installs Flux components.
|
||||
|
||||
### Option 2: Manual Flux installation
|
||||
|
||||
```bash
|
||||
# Create flux-system namespace and install Flux
|
||||
flux install --namespace=flux-system --network-policy=true
|
||||
```
|
||||
|
||||
## Install Pangolin with Flux using HelmRelease
|
||||
|
||||
### Step 1: Create HelmRepository
|
||||
|
||||
Define the Fossorial Helm chart repository:
|
||||
|
||||
```yaml
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: HelmRepository
|
||||
metadata:
|
||||
name: fossorial
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 5m
|
||||
url: https://charts.fossorial.io
|
||||
```
|
||||
|
||||
Apply:
|
||||
|
||||
```bash
|
||||
kubectl apply -f helmrepo.yaml
|
||||
|
||||
# Verify
|
||||
kubectl get helmrepo -n flux-system
|
||||
```
|
||||
|
||||
### Step 2: Create Pangolin HelmRelease
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
version: 0.1.0-alpha.0 # or use ~0.1.0 for auto-upgrades
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: fossorial
|
||||
namespace: flux-system
|
||||
|
||||
install:
|
||||
crds: Create
|
||||
upgrade:
|
||||
crds: CreateReplace
|
||||
|
||||
values:
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
|
||||
database:
|
||||
mode: cloudnativepg
|
||||
|
||||
pangolin:
|
||||
config:
|
||||
app:
|
||||
dashboard_url: https://pangolin.example.com
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: example.com
|
||||
gerbil:
|
||||
base_endpoint: vpn.example.com
|
||||
|
||||
ingress:
|
||||
enabled: true
|
||||
className: traefik
|
||||
hosts:
|
||||
- host: pangolin.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: pangolin-tls
|
||||
hosts:
|
||||
- pangolin.example.com
|
||||
```
|
||||
|
||||
Create namespace:
|
||||
|
||||
```bash
|
||||
kubectl create namespace pangolin
|
||||
```
|
||||
|
||||
Apply:
|
||||
|
||||
```bash
|
||||
kubectl apply -f pangolin-helmrelease.yaml
|
||||
```
|
||||
|
||||
### Step 3: Monitor reconciliation
|
||||
|
||||
```bash
|
||||
# Check HelmRelease status
|
||||
kubectl get helmrelease -n pangolin
|
||||
|
||||
# Watch live
|
||||
kubectl get helmrelease -n pangolin -w
|
||||
|
||||
# Describe for details
|
||||
kubectl describe helmrelease pangolin -n pangolin
|
||||
|
||||
# Check Flux logs
|
||||
flux logs --all-namespaces --follow
|
||||
```
|
||||
|
||||
## Install Newt with Flux using HelmRelease
|
||||
|
||||
### Step 1: Create Newt auth secret
|
||||
|
||||
```bash
|
||||
kubectl create secret generic newt-auth \
|
||||
-n pangolin \
|
||||
--from-literal=PANGOLIN_ENDPOINT=https://pangolin.example.com \
|
||||
--from-literal=NEWT_ID=<your-newt-id> \
|
||||
--from-literal=NEWT_SECRET=<your-newt-secret>
|
||||
```
|
||||
|
||||
### Step 2: Create Newt HelmRelease
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: newt
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: newt
|
||||
version: 1.4.0
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: fossorial
|
||||
namespace: flux-system
|
||||
|
||||
values:
|
||||
newtInstances:
|
||||
- name: main-tunnel
|
||||
enabled: true
|
||||
auth:
|
||||
existingSecretName: newt-auth
|
||||
```
|
||||
|
||||
Apply:
|
||||
|
||||
```bash
|
||||
kubectl apply -f newt-helmrelease.yaml
|
||||
```
|
||||
|
||||
### Step 3: Verify
|
||||
|
||||
```bash
|
||||
kubectl get helmrelease -n pangolin
|
||||
kubectl describe helmrelease newt -n pangolin
|
||||
```
|
||||
|
||||
## Using Flux with Git repository (GitOps)
|
||||
|
||||
Store Flux configuration in Git and have Flux automatically reconcile changes:
|
||||
|
||||
### Repository structure
|
||||
|
||||
```
|
||||
infrastructure/
|
||||
├── clusters/
|
||||
│ └── production/
|
||||
│ ├── flux-system/
|
||||
│ │ └── gotk-components.yaml (auto-generated)
|
||||
│ ├── pangolin/
|
||||
│ │ ├── helmrepo.yaml
|
||||
│ │ ├── pangolin-helmrelease.yaml
|
||||
│ │ └── newt-helmrelease.yaml
|
||||
│ └── kustomization.yaml
|
||||
└── apps/
|
||||
├── pangolin/
|
||||
│ └── values.yaml
|
||||
└── newt/
|
||||
└── values.yaml
|
||||
```
|
||||
|
||||
### GitRepository for configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: GitRepository
|
||||
metadata:
|
||||
name: infrastructure
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 1m
|
||||
url: https://github.com/my-org/infrastructure
|
||||
ref:
|
||||
branch: main
|
||||
```
|
||||
|
||||
### Kustomization for syncing
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: production
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: infrastructure
|
||||
path: ./clusters/production
|
||||
prune: true
|
||||
wait: true
|
||||
```
|
||||
|
||||
Flux watches `clusters/production` in Git and auto-applies all resources.
|
||||
|
||||
## Using Flux with Kustomize overlays
|
||||
|
||||
Manage environment-specific overlays with Flux:
|
||||
|
||||
### Repository structure
|
||||
|
||||
```
|
||||
overlays/
|
||||
├── dev/
|
||||
│ ├── kustomization.yaml
|
||||
│ └── pangolin-patch.yaml
|
||||
├── staging/
|
||||
│ └── kustomization.yaml
|
||||
└── prod/
|
||||
├── kustomization.yaml
|
||||
└── pangolin-patch.yaml
|
||||
```
|
||||
|
||||
### Kustomization resource
|
||||
|
||||
```yaml
|
||||
apiVersion: kustomize.toolkit.fluxcd.io/v1
|
||||
kind: Kustomization
|
||||
metadata:
|
||||
name: pangolin-prod
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 10m
|
||||
sourceRef:
|
||||
kind: GitRepository
|
||||
name: infrastructure
|
||||
path: ./overlays/prod
|
||||
prune: true
|
||||
wait: true
|
||||
```
|
||||
|
||||
Flux builds and applies the Kustomize overlay automatically.
|
||||
|
||||
## Using Flux with OCI Helm charts
|
||||
|
||||
If Helm charts are available in an OCI registry:
|
||||
|
||||
```yaml
|
||||
apiVersion: source.toolkit.fluxcd.io/v1beta2
|
||||
kind: OCIRepository
|
||||
metadata:
|
||||
name: fossorial-oci
|
||||
namespace: flux-system
|
||||
spec:
|
||||
interval: 5m
|
||||
url: oci://registry.example.com/fossorial
|
||||
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
version: 0.1.0-alpha.0
|
||||
sourceRef:
|
||||
kind: OCIRepository
|
||||
name: fossorial-oci
|
||||
namespace: flux-system
|
||||
values:
|
||||
# ... values ...
|
||||
```
|
||||
|
||||
## Advanced: Dependency ordering
|
||||
|
||||
Order HelmReleases to install dependencies first:
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: cert-manager
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: cert-manager
|
||||
# ...
|
||||
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
dependsOn:
|
||||
- name: cert-manager
|
||||
namespace: cert-manager
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
# ...
|
||||
```
|
||||
|
||||
Flux ensures `cert-manager` reconciles before `pangolin`.
|
||||
|
||||
## Advanced: valuesFrom ConfigMap/Secret
|
||||
|
||||
Store values in ConfigMaps or Secrets, referenced from HelmRelease:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: pangolin-values
|
||||
namespace: pangolin
|
||||
data:
|
||||
values.yaml: |
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
|
||||
---
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
# ...
|
||||
valuesFrom:
|
||||
- kind: ConfigMap
|
||||
name: pangolin-values
|
||||
```
|
||||
|
||||
Flux extracts values from the ConfigMap and applies them to the HelmRelease.
|
||||
|
||||
## Troubleshooting Flux
|
||||
|
||||
### Check Flux components
|
||||
|
||||
```bash
|
||||
kubectl get deployments -n flux-system
|
||||
flux check --all-namespaces
|
||||
```
|
||||
|
||||
### Check HelmRelease status
|
||||
|
||||
```bash
|
||||
kubectl get helmrelease -n pangolin
|
||||
kubectl describe helmrelease pangolin -n pangolin
|
||||
kubectl get helmrelease pangolin -n pangolin -o yaml
|
||||
```
|
||||
|
||||
### View reconciliation logs
|
||||
|
||||
```bash
|
||||
flux logs --all-namespaces --follow
|
||||
|
||||
# Specific resource
|
||||
kubectl logs -n pangolin deployment/helm-operator -f
|
||||
```
|
||||
|
||||
### Manual reconciliation
|
||||
|
||||
```bash
|
||||
flux reconcile helmrelease pangolin -n pangolin
|
||||
flux reconcile kustomization production -n flux-system
|
||||
```
|
||||
|
||||
### Suspend reconciliation
|
||||
|
||||
```bash
|
||||
flux suspend helmrelease pangolin -n pangolin
|
||||
```
|
||||
|
||||
### Resume reconciliation
|
||||
|
||||
```bash
|
||||
flux resume helmrelease pangolin -n pangolin
|
||||
```
|
||||
|
||||
## Multi-environment example
|
||||
|
||||
### Bootstrap multiple clusters
|
||||
|
||||
```bash
|
||||
# Production cluster
|
||||
flux bootstrap github \
|
||||
--owner=my-org \
|
||||
--repo=infrastructure \
|
||||
--personal \
|
||||
--path=clusters/production
|
||||
|
||||
# Staging cluster (from different checkout)
|
||||
flux bootstrap github \
|
||||
--owner=my-org \
|
||||
--repo=infrastructure \
|
||||
--personal \
|
||||
--path=clusters/staging
|
||||
```
|
||||
|
||||
Each cluster reconciles its own `clusters/*/` directory.
|
||||
|
||||
### Repository structure
|
||||
|
||||
```
|
||||
clusters/
|
||||
├── production/
|
||||
│ ├── kustomization.yaml
|
||||
│ └── pangolin/
|
||||
│ ├── helmrepo.yaml
|
||||
│ └── helmrelease.yaml (prod values)
|
||||
├── staging/
|
||||
│ ├── kustomization.yaml
|
||||
│ └── pangolin/
|
||||
│ ├── helmrepo.yaml
|
||||
│ └── helmrelease.yaml (staging values)
|
||||
└── dev/
|
||||
├── kustomization.yaml
|
||||
└── pangolin/
|
||||
└── helmrelease.yaml (dev values)
|
||||
```
|
||||
|
||||
Each environment's HelmRelease uses environment-specific values.
|
||||
|
||||
## Important notes
|
||||
|
||||
### CRD management
|
||||
|
||||
When using Flux with Helm charts that include CRDs:
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
install:
|
||||
crds: Create # Create CRDs on first install
|
||||
upgrade:
|
||||
crds: CreateReplace # Update CRDs on upgrade
|
||||
```
|
||||
|
||||
### Namespace creation
|
||||
|
||||
Flux automatically creates namespaces if they don't exist. Ensure appropriate RBAC.
|
||||
|
||||
### GitOps best practices
|
||||
|
||||
- Use branches for different environments
|
||||
- Protect production branches with review requirements
|
||||
- Store secrets using sealed-secrets or external-secrets
|
||||
- Track all changes in Git
|
||||
- Use consistent naming conventions
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="GitOps Overview" href="/self-host/manual/kubernetes/gitops/overview" icon="code-branch" />
|
||||
<Card title="Argo CD" href="/self-host/manual/kubernetes/gitops/argocd" icon="code-branch" />
|
||||
<Card title="Pangolin Configuration" href="/self-host/manual/kubernetes/pangolin/configuration" icon="sliders" />
|
||||
<Card title="Troubleshooting" href="/self-host/manual/kubernetes/pangolin/troubleshooting" icon="circle-question" />
|
||||
</CardGroup>
|
||||
@@ -0,0 +1,351 @@
|
||||
---
|
||||
title: "GitOps Overview"
|
||||
description: "Git-driven Kubernetes deployments for Pangolin and Newt using Argo CD or Flux."
|
||||
---
|
||||
|
||||
import PangolinCloudTocCta from "/snippets/pangolin-cloud-toc-cta.mdx";
|
||||
|
||||
<PangolinCloudTocCta />
|
||||
|
||||
|
||||
GitOps is a declarative approach to infrastructure management where your Git repository is the single source of truth for cluster state. Changes go through Git; the GitOps tool automatically reconciles the cluster to match.
|
||||
|
||||
## What is GitOps?
|
||||
|
||||
GitOps reconciliation loop:
|
||||
|
||||
<Steps>
|
||||
<Step title="Declare desired state in Git">
|
||||
**Git repository** contains desired state (manifests, Helm values, Kustomize overlays).
|
||||
</Step>
|
||||
<Step title="GitOps controller watches source">
|
||||
**GitOps tool** (Argo CD or Flux) watches the Git repository.
|
||||
</Step>
|
||||
<Step title="Detect changes and drift">
|
||||
The controller detects new commits or drift between Git and the live cluster.
|
||||
</Step>
|
||||
<Step title="Reconcile cluster">
|
||||
The controller syncs cluster state to match Git state.
|
||||
</Step>
|
||||
<Step title="Continuous convergence">
|
||||
**Result**: Cluster stays aligned with the declared Git configuration.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Benefits
|
||||
|
||||
- **Version control**: All infrastructure changes tracked in Git
|
||||
- **Audit trail**: See who changed what and when
|
||||
- **Rollback**: Revert to previous state by reverting Git commits
|
||||
- **Automation**: No manual `kubectl apply` commands needed
|
||||
- **Drift detection**: Automatic alerts if cluster diverges from Git
|
||||
|
||||
## GitOps tools for Kubernetes
|
||||
|
||||
### Argo CD
|
||||
|
||||
- **UI**: Web-based dashboard for monitoring and manual syncs
|
||||
- **Approach**: External reconciler (watches Git, applies to cluster)
|
||||
- **Supports**: Helm charts, Kustomize overlays, raw YAML
|
||||
- **Best for**: Teams who want GitOps with a UI, hybrid manual/automated workflows
|
||||
|
||||
**Use Argo CD if**:
|
||||
- You want a visual dashboard
|
||||
- You need frequent manual sync capabilities
|
||||
- You're already using Argo CD for other workloads
|
||||
|
||||
See: [Argo CD Install Guide](/self-host/manual/kubernetes/gitops/argocd)
|
||||
|
||||
### Flux
|
||||
|
||||
- **CRDs**: Kubernetes-native Custom Resources (HelmRelease, Kustomization, GitRepository)
|
||||
- **Approach**: Declarative reconciliation using Kubernetes resources
|
||||
- **Supports**: Helm charts, Kustomize overlays, raw YAML, OCI registries
|
||||
- **Best for**: Teams who want declarative Kubernetes-way GitOps, lightweight controllers
|
||||
|
||||
**Use Flux if**:
|
||||
- You prefer Kubernetes-native CRDs
|
||||
- You want a lightweight, modern GitOps tool
|
||||
- You're already using Flux for other workloads
|
||||
|
||||
See: [Flux Install Guide](/self-host/manual/kubernetes/gitops/flux)
|
||||
|
||||
## Recommended repository structure
|
||||
|
||||
For multi-environment Pangolin/Newt deployments, organize your Git repository like this:
|
||||
|
||||
```
|
||||
my-org/infrastructure/
|
||||
├── clusters/
|
||||
│ ├── production/
|
||||
│ │ ├── pangolin/
|
||||
│ │ │ ├── values.yaml
|
||||
│ │ │ └── kustomization.yaml (if using Kustomize)
|
||||
│ │ └── newt/
|
||||
│ │ ├── values.yaml
|
||||
│ │ └── kustomization.yaml
|
||||
│ ├── staging/
|
||||
│ │ ├── pangolin/
|
||||
│ │ └── newt/
|
||||
│ └── dev/
|
||||
│ ├── pangolin/
|
||||
│ └── newt/
|
||||
├── apps/
|
||||
│ ├── pangolin/
|
||||
│ │ ├── helm/
|
||||
│ │ │ ├── values-base.yaml
|
||||
│ │ │ ├── values-prod.yaml
|
||||
│ │ │ └── values-staging.yaml
|
||||
│ │ └── kustomize/
|
||||
│ │ ├── base/
|
||||
│ │ └── overlays/
|
||||
│ └── newt/
|
||||
│ ├── helm/
|
||||
│ └── kustomize/
|
||||
└── .gitignore
|
||||
```
|
||||
|
||||
**Pattern**:
|
||||
- `clusters/` → environment-specific configuration
|
||||
- `apps/` → shared, reusable application configuration
|
||||
- Environment overlays layer on top of app definitions
|
||||
|
||||
## Secrets in GitOps
|
||||
|
||||
<Warning>
|
||||
**Never commit plaintext secrets to Git.** Use secret management tools instead.
|
||||
</Warning>
|
||||
|
||||
Options for managing secrets in GitOps:
|
||||
|
||||
### Sealed Secrets
|
||||
|
||||
- **Tool**: [sealed-secrets](https://github.com/bitnami-labs/sealed-secrets)
|
||||
- **How**: Encrypt secrets with cluster-specific key; safe to commit encrypted secrets
|
||||
- **Decrypt**: Only the cluster can decrypt (uses private key)
|
||||
|
||||
```bash
|
||||
# Encrypt a secret
|
||||
echo -n mypassword | kubeseal -f - > secret.yaml
|
||||
|
||||
# Git tracks encrypted secret.yaml
|
||||
# Cluster auto-decrypts on apply
|
||||
```
|
||||
|
||||
### External Secrets Operator
|
||||
|
||||
- **Tool**: [external-secrets](https://external-secrets.io/)
|
||||
- **How**: Reference secrets stored in external vault (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault)
|
||||
- **Git**: Stores reference only, not secret values
|
||||
|
||||
```yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: SecretStore
|
||||
metadata:
|
||||
name: vault-backend
|
||||
spec:
|
||||
provider:
|
||||
vault:
|
||||
server: "https://vault.example.com"
|
||||
```
|
||||
|
||||
### SOPS (Secrets Operations)
|
||||
|
||||
- **Tool**: [SOPS](https://github.com/mozilla/sops)
|
||||
- **How**: Encrypt YAML files; decrypt at deploy time
|
||||
- **Git**: Stores encrypted files
|
||||
|
||||
```bash
|
||||
sops --encrypt secrets.yaml > secrets.enc.yaml
|
||||
# Commit secrets.enc.yaml; tool decrypts on apply
|
||||
```
|
||||
|
||||
### Cloud Provider Secrets
|
||||
|
||||
- **AWS**: Use AWS Secrets Manager or Parameter Store with IRSA (IAM Roles for Service Accounts)
|
||||
- **Azure**: Use Azure Key Vault with pod identity
|
||||
- **GCP**: Use Google Secret Manager with workload identity
|
||||
|
||||
<Tip>
|
||||
Choose a secret management strategy **before** setting up GitOps. Seal secrets once; keep approach consistent.
|
||||
</Tip>
|
||||
|
||||
## GitOps workflow example
|
||||
|
||||
### 1. Set up Git repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/my-org/infrastructure.git
|
||||
cd infrastructure
|
||||
mkdir -p clusters/production/pangolin
|
||||
cd clusters/production/pangolin
|
||||
```
|
||||
|
||||
### 2. Create configuration
|
||||
|
||||
```bash
|
||||
# values.yaml with Pangolin config
|
||||
cat > values.yaml <<EOF
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
database:
|
||||
mode: cloudnativepg
|
||||
pangolin:
|
||||
config:
|
||||
app:
|
||||
dashboard_url: https://pangolin.example.com
|
||||
domains:
|
||||
domain1:
|
||||
base_domain: example.com
|
||||
gerbil:
|
||||
base_endpoint: vpn.example.com
|
||||
EOF
|
||||
|
||||
git add values.yaml
|
||||
git commit -m "Add production Pangolin config"
|
||||
git push
|
||||
```
|
||||
|
||||
### 3. Install GitOps tool
|
||||
|
||||
```bash
|
||||
# For Argo CD
|
||||
kubectl create namespace argocd
|
||||
helm repo add argo https://argoproj.github.io/argo-helm
|
||||
helm install argocd argo/argo-cd -n argocd
|
||||
|
||||
# For Flux
|
||||
flux bootstrap github \
|
||||
--owner=my-org \
|
||||
--repo=infrastructure \
|
||||
--personal \
|
||||
--path=clusters/production
|
||||
```
|
||||
|
||||
### 4. Create Application/HelmRelease
|
||||
|
||||
**With Argo CD**:
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://github.com/my-org/infrastructure
|
||||
targetRevision: main
|
||||
path: clusters/production/pangolin
|
||||
helm:
|
||||
values: values.yaml
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: pangolin
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
```
|
||||
|
||||
**With Flux**:
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
namespace: pangolin
|
||||
spec:
|
||||
interval: 10m
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
sourceRef:
|
||||
kind: HelmRepository
|
||||
name: fossorial
|
||||
namespace: flux-system
|
||||
values:
|
||||
deployment:
|
||||
type: controller
|
||||
mode: multi
|
||||
```
|
||||
|
||||
### 5. Push to Git
|
||||
|
||||
```bash
|
||||
git add pangolin-app.yaml
|
||||
git commit -m "Add Argo CD Application for Pangolin"
|
||||
git push
|
||||
```
|
||||
|
||||
**Result**: GitOps tool automatically detects the new Application and begins reconciliation.
|
||||
|
||||
### 6. Monitor
|
||||
|
||||
**Argo CD**:
|
||||
|
||||
```bash
|
||||
# Port-forward to UI
|
||||
kubectl port-forward -n argocd svc/argocd-server 8080:443
|
||||
|
||||
# Visit https://localhost:8080
|
||||
```
|
||||
|
||||
**Flux**:
|
||||
|
||||
```bash
|
||||
# Check reconciliation status
|
||||
flux get all
|
||||
|
||||
# View logs
|
||||
flux logs --all-namespaces --follow
|
||||
```
|
||||
|
||||
## Common use cases
|
||||
|
||||
### Multi-environment deployments
|
||||
|
||||
Use Git branches, directories, or environments to manage dev, staging, production:
|
||||
|
||||
```
|
||||
clusters/dev/pangolin → helm values for dev
|
||||
clusters/staging/pangolin → helm values for staging
|
||||
clusters/production/pangolin → helm values for production
|
||||
```
|
||||
|
||||
Each environment syncs independently.
|
||||
|
||||
### Automatic deployments on chart update
|
||||
|
||||
Flux or Argo CD can watch a Helm repository and auto-update when a new chart version is released:
|
||||
|
||||
```yaml
|
||||
apiVersion: helm.toolkit.fluxcd.io/v2
|
||||
kind: HelmRelease
|
||||
metadata:
|
||||
name: pangolin
|
||||
spec:
|
||||
chart:
|
||||
spec:
|
||||
chart: pangolin
|
||||
version: ">=0.1.0" # auto-upgrade to latest 0.1.x
|
||||
```
|
||||
|
||||
### Drift detection and remediation
|
||||
|
||||
Argo CD and Flux both support continuous drift detection:
|
||||
|
||||
- **Argo CD**: Detects drift on demand or continuously; can auto-sync on drift
|
||||
- **Flux**: Reconciles on interval; rolls back manual cluster changes
|
||||
|
||||
## Next steps
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Argo CD Install" href="/self-host/manual/kubernetes/gitops/argocd" icon="code-branch" />
|
||||
<Card title="Flux Install" href="/self-host/manual/kubernetes/gitops/flux" icon="code-branch" />
|
||||
<Card title="Helm Quick-Start" href="/self-host/manual/kubernetes/helm" icon="box" />
|
||||
<Card title="Kustomize Quick-Start" href="/self-host/manual/kubernetes/kustomize" icon="layer-group" />
|
||||
</CardGroup>
|
||||
Reference in New Issue
Block a user