feat: complete ArgoCD migration for Radarr and Sonarr with lessons learned
- Fix ArgoCD multi-source applications (remove conflicting source: section) - Restore original volume mount configuration using plex-data PVC - Update ingress class from nginx to traefik for K3s compatibility - Remove unnecessary compatibility patches (myvolume PVC) - Document comprehensive ArgoCD migration guidelines in CLAUDE.md - Add chart-specific configuration patterns for Bananaspliff charts - Include pre/post migration checklists and verification commands Both applications now working exactly as before migration with: - Original service ports (Radarr:7878, Sonarr:8989) - Complete access to existing configurations and databases - External accessibility via radarr.gilgamezh.me and sonarr.gilgamezh.me - Automatic image updates enabled for latest tag tracking 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -20,7 +20,7 @@ This repository contains Kubernetes configuration files for a K3s homelab cluste
|
|||||||
- **Storage**: NFS-backed persistent volumes from turing3.lan:/mnt/ssd
|
- **Storage**: NFS-backed persistent volumes from turing3.lan:/mnt/ssd
|
||||||
- **Load Balancer**: MetalLB for bare metal LoadBalancer services
|
- **Load Balancer**: MetalLB for bare metal LoadBalancer services
|
||||||
- **SSL**: cert-manager with Let's Encrypt (staging/production cluster issuers)
|
- **SSL**: cert-manager with Let's Encrypt (staging/production cluster issuers)
|
||||||
- **Ingress**: Nginx with LAN-only restrictions
|
- **Ingress**: Traefik (K3s default) with LAN-only restrictions
|
||||||
|
|
||||||
## Application Stack
|
## Application Stack
|
||||||
|
|
||||||
@@ -109,4 +109,167 @@ The kube-plex/ directory contains a Go application that replaces the standard Pl
|
|||||||
- Creates Kubernetes pods for each transcode job
|
- Creates Kubernetes pods for each transcode job
|
||||||
- Requires AMD64 nodes (configured via nodeSelector)
|
- Requires AMD64 nodes (configured via nodeSelector)
|
||||||
- Mounts shared NFS volumes for media access
|
- Mounts shared NFS volumes for media access
|
||||||
- Environment variables: DATA_PVC, CONFIG_PVC, TRANSCODE_PVC, PMS_IMAGE, PMS_INTERNAL_ADDRESS
|
- Environment variables: DATA_PVC, CONFIG_PVC, TRANSCODE_PVC, PMS_IMAGE, PMS_INTERNAL_ADDRESS
|
||||||
|
|
||||||
|
## ArgoCD Migration Guidelines
|
||||||
|
|
||||||
|
### Critical Configuration Preservation Rules
|
||||||
|
When migrating applications from direct Helm deployment to ArgoCD GitOps:
|
||||||
|
|
||||||
|
1. **NEVER change working configurations** - If an application was working with specific values files and service configurations, maintain those exact settings
|
||||||
|
2. **NO PATCHES OR WORKAROUNDS** - Do not create additional PVCs, port forwards, or other patches to "fix" configuration mismatches
|
||||||
|
3. **Root Cause Analysis Required** - Always identify why a configuration that worked before is now failing after ArgoCD migration
|
||||||
|
4. **Preserve Original Service Ports** - Applications should maintain their original service port configurations (e.g., Radarr:7878, Sonarr:8989)
|
||||||
|
5. **Respect Existing PVC Structure** - Use the existing PVC and storage configuration patterns, don't create compatibility layers
|
||||||
|
|
||||||
|
### Troubleshooting Process
|
||||||
|
1. Compare working Helm values with ArgoCD application configuration
|
||||||
|
2. Verify that Helm chart sources and versions match original deployments
|
||||||
|
3. Ensure service definitions in ArgoCD match original working services
|
||||||
|
4. Check that ingress configurations align with actual service ports
|
||||||
|
5. Fix the root configuration issue, don't patch around it
|
||||||
|
|
||||||
|
### Common Migration Pitfalls
|
||||||
|
- Creating unnecessary "myvolume" PVCs for chart compatibility - instead fix the chart values
|
||||||
|
- Changing service ports to match ingress instead of fixing ingress to match services
|
||||||
|
- Using generic chart defaults instead of preserving working custom configurations
|
||||||
|
|
||||||
|
## ArgoCD GitOps Implementation Lessons
|
||||||
|
|
||||||
|
### Successfully Migrated Applications
|
||||||
|
- **Plex**: Multi-source setup (kube-plex chart + turingpi values)
|
||||||
|
- **Radarr**: Bananaspliff chart with custom volume configuration
|
||||||
|
- **Sonarr**: Bananaspliff chart with custom volume configuration
|
||||||
|
|
||||||
|
### Critical ArgoCD Configuration Patterns
|
||||||
|
|
||||||
|
#### Multi-Source Application Structure
|
||||||
|
For applications requiring custom values from Git repository:
|
||||||
|
```yaml
|
||||||
|
spec:
|
||||||
|
project: default
|
||||||
|
sources:
|
||||||
|
- repoURL: https://chart-repository.com/charts
|
||||||
|
chart: app-name
|
||||||
|
targetRevision: "*"
|
||||||
|
ref: charts
|
||||||
|
helm:
|
||||||
|
releaseName: app-name
|
||||||
|
valueFiles:
|
||||||
|
- $values/helm-values/app_values.yaml
|
||||||
|
- repoURL: http://gitea-http.gitea.svc.cluster.local:3000/admin/turingpi.git
|
||||||
|
targetRevision: HEAD
|
||||||
|
ref: values
|
||||||
|
```
|
||||||
|
|
||||||
|
**CRITICAL**: Never use both `source:` and `sources:` sections - this creates conflicts where `source:` overrides `sources:` configuration.
|
||||||
|
|
||||||
|
#### Image Auto-Update Configuration
|
||||||
|
For applications using "latest" tags with automatic updates:
|
||||||
|
```yaml
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
argocd-image-updater.argoproj.io/image-list: app=registry/image:latest
|
||||||
|
argocd-image-updater.argoproj.io/app.update-strategy: digest
|
||||||
|
argocd-image-updater.argoproj.io/write-back-method: git
|
||||||
|
argocd-image-updater.argoproj.io/git-branch: master
|
||||||
|
argocd-image-updater.argoproj.io/git-commit-user: argocd-image-updater
|
||||||
|
argocd-image-updater.argoproj.io/git-commit-email: argocd@turing.lan
|
||||||
|
```
|
||||||
|
|
||||||
|
### Chart-Specific Configuration Requirements
|
||||||
|
|
||||||
|
#### Bananaspliff Charts (Radarr/Sonarr)
|
||||||
|
These charts require specific volume configuration syntax:
|
||||||
|
```yaml
|
||||||
|
# CORRECT: Direct volumes/volumeMounts (working configuration)
|
||||||
|
volumes:
|
||||||
|
- name: "plex-data"
|
||||||
|
persistentVolumeClaim:
|
||||||
|
claimName: "plex-data"
|
||||||
|
|
||||||
|
volumeMounts:
|
||||||
|
- name: "plex-data"
|
||||||
|
mountPath: "/config"
|
||||||
|
subPath: "configs/app-name"
|
||||||
|
- name: "plex-data"
|
||||||
|
mountPath: "/nfs"
|
||||||
|
|
||||||
|
# INCORRECT: persistence syntax (doesn't work with these charts)
|
||||||
|
persistence:
|
||||||
|
config:
|
||||||
|
enabled: true
|
||||||
|
existingClaim: "plex-data"
|
||||||
|
subPath: "configs/app-name"
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Service Port Configuration
|
||||||
|
Bananaspliff charts use simple service structure:
|
||||||
|
```yaml
|
||||||
|
service:
|
||||||
|
type: ClusterIP
|
||||||
|
port: 7878 # Direct port specification
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ingress Controller Configuration
|
||||||
|
|
||||||
|
#### K3s Default Setup
|
||||||
|
- **Default Controller**: Traefik (not Nginx)
|
||||||
|
- **Ingress Class**: Use `kubernetes.io/ingress.class: traefik`
|
||||||
|
- **Common Mistake**: Using `nginx` class when Traefik is the active controller
|
||||||
|
|
||||||
|
#### Verification Commands
|
||||||
|
```bash
|
||||||
|
# Check active ingress controller
|
||||||
|
kubectl get pods -A | grep traefik
|
||||||
|
kubectl get pods -A | grep ingress
|
||||||
|
|
||||||
|
# Verify ingress class in configurations
|
||||||
|
kubectl get ingress -o yaml | grep "ingress.class"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pre-Migration Checklist
|
||||||
|
Before migrating any application to ArgoCD:
|
||||||
|
|
||||||
|
1. **Capture Current Configuration**:
|
||||||
|
```bash
|
||||||
|
helm get values <release-name> > original_values.yaml
|
||||||
|
helm get manifest <release-name> > original_manifest.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Document Volume Mounts**:
|
||||||
|
```bash
|
||||||
|
kubectl describe deployment <app-name> | grep -A 10 "Mounts:"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verify Service Configuration**:
|
||||||
|
```bash
|
||||||
|
kubectl get svc <app-name> -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Test Chart Template Locally**:
|
||||||
|
```bash
|
||||||
|
helm template <app-name> <chart> --values <values-file> | grep -A 20 "kind: Service"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Post-Migration Verification
|
||||||
|
|
||||||
|
1. **Check Volume Mounts Match Original**:
|
||||||
|
```bash
|
||||||
|
kubectl describe pod -l app=<app-name> | grep -A 10 "Mounts:"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verify Service Ports**:
|
||||||
|
```bash
|
||||||
|
kubectl get svc <app-name>
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Test Application Access**:
|
||||||
|
```bash
|
||||||
|
curl -I http://<app-domain>
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Confirm Configuration Persistence**:
|
||||||
|
```bash
|
||||||
|
kubectl exec -it deployment/<app-name> -- ls -la /config
|
||||||
|
```
|
||||||
@@ -17,19 +17,15 @@ metadata:
|
|||||||
argocd-image-updater.argoproj.io/git-commit-message: "chore: update Radarr image to {{.NewTag}}"
|
argocd-image-updater.argoproj.io/git-commit-message: "chore: update Radarr image to {{.NewTag}}"
|
||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
|
||||||
repoURL: https://bananaspliff.github.io/geek-charts
|
|
||||||
chart: radarr
|
|
||||||
targetRevision: "*"
|
|
||||||
helm:
|
|
||||||
releaseName: radarr
|
|
||||||
valueFiles:
|
|
||||||
- $values/helm-values/radarr_values.yaml
|
|
||||||
sources:
|
sources:
|
||||||
- repoURL: https://bananaspliff.github.io/geek-charts
|
- repoURL: https://bananaspliff.github.io/geek-charts
|
||||||
chart: radarr
|
chart: radarr
|
||||||
targetRevision: "*"
|
targetRevision: "*"
|
||||||
ref: charts
|
ref: charts
|
||||||
|
helm:
|
||||||
|
releaseName: radarr
|
||||||
|
valueFiles:
|
||||||
|
- $values/helm-values/radarr_values.yaml
|
||||||
- repoURL: http://gitea-http.gitea.svc.cluster.local:3000/admin/turingpi.git
|
- repoURL: http://gitea-http.gitea.svc.cluster.local:3000/admin/turingpi.git
|
||||||
targetRevision: HEAD
|
targetRevision: HEAD
|
||||||
ref: values
|
ref: values
|
||||||
|
|||||||
@@ -17,19 +17,15 @@ metadata:
|
|||||||
argocd-image-updater.argoproj.io/git-commit-message: "chore: update Sonarr image to {{.NewTag}}"
|
argocd-image-updater.argoproj.io/git-commit-message: "chore: update Sonarr image to {{.NewTag}}"
|
||||||
spec:
|
spec:
|
||||||
project: default
|
project: default
|
||||||
source:
|
|
||||||
repoURL: https://bananaspliff.github.io/geek-charts
|
|
||||||
chart: sonarr
|
|
||||||
targetRevision: "*"
|
|
||||||
helm:
|
|
||||||
releaseName: sonarr
|
|
||||||
valueFiles:
|
|
||||||
- $values/helm-values/sonarr_values.yaml
|
|
||||||
sources:
|
sources:
|
||||||
- repoURL: https://bananaspliff.github.io/geek-charts
|
- repoURL: https://bananaspliff.github.io/geek-charts
|
||||||
chart: sonarr
|
chart: sonarr
|
||||||
targetRevision: "*"
|
targetRevision: "*"
|
||||||
ref: charts
|
ref: charts
|
||||||
|
helm:
|
||||||
|
releaseName: sonarr
|
||||||
|
valueFiles:
|
||||||
|
- $values/helm-values/sonarr_values.yaml
|
||||||
- repoURL: http://gitea-http.gitea.svc.cluster.local:3000/admin/turingpi.git
|
- repoURL: http://gitea-http.gitea.svc.cluster.local:3000/admin/turingpi.git
|
||||||
targetRevision: HEAD
|
targetRevision: HEAD
|
||||||
ref: values
|
ref: values
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: myvolume
|
|
||||||
namespace: default
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
- ReadWriteMany
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: 450Gi
|
|
||||||
storageClassName: nfs-client
|
|
||||||
Reference in New Issue
Block a user