From 8e6cf6b82074586f18464127fc6c9d305ba0d715 Mon Sep 17 00:00:00 2001 From: Zhongwei Li Date: Sat, 29 Nov 2025 18:15:16 +0800 Subject: [PATCH] Initial commit --- .claude-plugin/plugin.json | 14 ++ README.md | 3 + commands/disk-cleanup.md | 37 +++++ plugin.lock.json | 57 ++++++++ skills/argocd-management/SKILL.md | 166 +++++++++++++++++++++++ skills/helm-practices/SKILL.md | 110 +++++++++++++++ skills/vault-secrets/SKILL.md | 216 ++++++++++++++++++++++++++++++ 7 files changed, 603 insertions(+) create mode 100644 .claude-plugin/plugin.json create mode 100644 README.md create mode 100644 commands/disk-cleanup.md create mode 100644 plugin.lock.json create mode 100644 skills/argocd-management/SKILL.md create mode 100644 skills/helm-practices/SKILL.md create mode 100644 skills/vault-secrets/SKILL.md diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json new file mode 100644 index 0000000..7070e05 --- /dev/null +++ b/.claude-plugin/plugin.json @@ -0,0 +1,14 @@ +{ + "name": "nk-devops-tools", + "description": "Helm, ArgoCD, Vault best practices and disk space management for Minikube/Skaffold workflows", + "version": "1.0.0", + "author": { + "name": "Cole Kennedy" + }, + "skills": [ + "./skills" + ], + "commands": [ + "./commands" + ] +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..623420a --- /dev/null +++ b/README.md @@ -0,0 +1,3 @@ +# nk-devops-tools + +Helm, ArgoCD, Vault best practices and disk space management for Minikube/Skaffold workflows diff --git a/commands/disk-cleanup.md b/commands/disk-cleanup.md new file mode 100644 index 0000000..ee4ae01 --- /dev/null +++ b/commands/disk-cleanup.md @@ -0,0 +1,37 @@ +--- +description: Clean Docker build cache in Minikube to free disk space +--- + +# Disk Space Cleanup for Minikube + +Minikube docker build cache can grow to 200GB+ from repeated Skaffold builds. This command checks disk usage and cleans the cache without destroying cluster state. + +## Check Disk Usage + +```bash +docker exec minikube df -h /var/lib/docker +``` + +## Clean Build Cache + +This frees ~240GB+ without destroying cluster state (PVCs, volumes remain intact): + +```bash +docker exec minikube docker builder prune -af && docker exec minikube docker image prune -af +``` + +## What Gets Cleaned + +- Docker build cache +- Dangling images +- Unused images + +## What Remains Intact + +- Running containers +- Persistent Volume Claims (PVCs) +- Kubernetes volumes +- Current pod states +- Cluster configuration + +Execute the disk check first, show the results, then ask if the user wants to proceed with cleanup. diff --git a/plugin.lock.json b/plugin.lock.json new file mode 100644 index 0000000..a4e0934 --- /dev/null +++ b/plugin.lock.json @@ -0,0 +1,57 @@ +{ + "$schema": "internal://schemas/plugin.lock.v1.json", + "pluginId": "gh:colek42/claude-plugins:nk-devops-tools", + "normalized": { + "repo": null, + "ref": "refs/tags/v20251128.0", + "commit": "3e587faa63f0c544b06de868b4d973e9d3f0778e", + "treeHash": "57573c94b8f55bef8991ac14d3b588057fc336ce43435edcba0987abc2246ee4", + "generatedAt": "2025-11-28T10:15:45.624208Z", + "toolVersion": "publish_plugins.py@0.2.0" + }, + "origin": { + "remote": "git@github.com:zhongweili/42plugin-data.git", + "branch": "master", + "commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390", + "repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data" + }, + "manifest": { + "name": "nk-devops-tools", + "description": "Helm, ArgoCD, Vault best practices and disk space management for Minikube/Skaffold workflows", + "version": "1.0.0" + }, + "content": { + "files": [ + { + "path": "README.md", + "sha256": "4bce29b5f8f1e12184b22e89555a5f8edac7db9b5b2b19a57cf2e0fb7187e298" + }, + { + "path": ".claude-plugin/plugin.json", + "sha256": "9c2884233fd851e307d263c5a48059599aaa0a638ae22951b8d25225ee020c67" + }, + { + "path": "commands/disk-cleanup.md", + "sha256": "94ec42d30cc36f6c737d3eb01ed58a8b40141c17c7bd905e258885a97fd83db6" + }, + { + "path": "skills/helm-practices/SKILL.md", + "sha256": "4a493c01a1b1389ff221d03b0bba4c8d519b8d8cf0317050a3b5e90e15adb8bf" + }, + { + "path": "skills/argocd-management/SKILL.md", + "sha256": "0655da8f3d32d04d780c727af521e375cd94da16a49de2ee71ccd87b1f85dfe8" + }, + { + "path": "skills/vault-secrets/SKILL.md", + "sha256": "36fd76b5c101da5ca3b7db79eebe0846977b61afa642f50d81e22f20f9049cb1" + } + ], + "dirSha256": "57573c94b8f55bef8991ac14d3b588057fc336ce43435edcba0987abc2246ee4" + }, + "security": { + "scannedAt": null, + "scannerVersion": null, + "flags": [] + } +} \ No newline at end of file diff --git a/skills/argocd-management/SKILL.md b/skills/argocd-management/SKILL.md new file mode 100644 index 0000000..31a2cb1 --- /dev/null +++ b/skills/argocd-management/SKILL.md @@ -0,0 +1,166 @@ +# ArgoCD Management Best Practices + +This skill provides ArgoCD application management patterns. + +## When to Use + +Activates when: +- Working with ArgoCD-managed applications +- Creating or modifying Kubernetes resources in ArgoCD repos +- Deploying applications via ArgoCD + +## Core Principle + +**Never manually create/modify Kubernetes resources when using ArgoCD.** + +ArgoCD manages the lifecycle of your Kubernetes resources. Manual kubectl operations will be overwritten by ArgoCD's sync process. + +## The ArgoCD Way + +### Creating Resources + +❌ **Wrong - Manual kubectl:** +```bash +kubectl apply -f deployment.yaml +kubectl apply -f service.yaml +``` + +✅ **Correct - ArgoCD Application CR:** +```bash +# Only kubectl apply for ArgoCD Application CRs +kubectl apply -f argocd-application.yaml +``` + +Then let ArgoCD handle the actual application resources. + +### Application CR Pattern + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: my-app + namespace: argocd +spec: + project: default + source: + repoURL: https://github.com/org/repo + targetRevision: HEAD + path: k8s/manifests + destination: + server: https://kubernetes.default.svc + namespace: my-app + syncPolicy: + automated: + prune: true + selfHeal: true +``` + +## Workflow + +### 1. Update Source Repository +```bash +# Modify your Kubernetes manifests or Helm charts in git +git add k8s/ +git commit -m "update deployment configuration" +git push +``` + +### 2. Let ArgoCD Sync +```bash +# ArgoCD automatically detects changes and syncs + +# Or manually trigger sync +argocd app sync my-app + +# Check sync status +argocd app get my-app +``` + +### 3. Verify Deployment +```bash +# Use kubectl for read-only operations +kubectl get pods -n my-app +kubectl logs -n my-app deployment/my-app +kubectl describe deployment -n my-app my-app +``` + +## ArgoCD CLI Commands + +### Application Management +```bash +# List applications +argocd app list + +# Get application details +argocd app get my-app + +# Sync application +argocd app sync my-app + +# Check sync status +argocd app wait my-app --health + +# View application logs +argocd app logs my-app + +# Diff current state vs desired +argocd app diff my-app +``` + +### Debugging +```bash +# See why sync failed +argocd app get my-app + +# View events +kubectl get events -n my-app + +# Check ArgoCD controller logs +kubectl logs -n argocd deployment/argocd-application-controller +``` + +## Best Practices + +✅ **Do:** +- Use `kubectl apply -f` ONLY for ArgoCD Application CRs +- Let ArgoCD handle all application resources +- Use git as the single source of truth +- Use automated sync policies for continuous deployment +- Use read-only kubectl commands for debugging + +❌ **Don't:** +- Manually create/modify Kubernetes resources with kubectl +- Edit resources directly with `kubectl edit` +- Use `kubectl apply` for app resources in ArgoCD-managed namespaces +- Fight with ArgoCD by manually changing resources + +## GitOps Workflow + +1. **Code Change** → Commit to git repository +2. **ArgoCD Detects** → Automatic or manual sync trigger +3. **ArgoCD Applies** → Resources created/updated in cluster +4. **ArgoCD Monitors** → Health and sync status tracked +5. **Self-Heal** → Auto-corrects manual changes (if enabled) + +## Emergency Override + +If you absolutely must make a manual change: + +```bash +# 1. Pause auto-sync temporarily +argocd app set my-app --sync-policy none + +# 2. Make your manual change +kubectl apply -f emergency-fix.yaml + +# 3. Update git to match your change +git add k8s/emergency-fix.yaml +git commit -m "emergency fix applied" +git push + +# 4. Re-enable auto-sync +argocd app set my-app --sync-policy automated +``` + +**But prefer:** Make the change in git first, then let ArgoCD apply it. diff --git a/skills/helm-practices/SKILL.md b/skills/helm-practices/SKILL.md new file mode 100644 index 0000000..8100131 --- /dev/null +++ b/skills/helm-practices/SKILL.md @@ -0,0 +1,110 @@ +# Helm Best Practices + +This skill provides Helm chart development and maintenance patterns. + +## When to Use + +Activates when: +- Working with Helm charts +- Modifying Chart.yaml dependencies +- Updating Helm values +- Deploying applications with Helm + +## Dependency Management + +### Critical Rules + +**Always use `helm dependency update`** - NOT `helm dependency build` + +```bash +# Correct +helm dependency update + +# Wrong - Don't use this +helm dependency build +``` + +**After changing Chart.yaml dependencies:** + +1. Run `helm dependency update` to fetch updated dependencies +2. Run `make check-deps` before committing changes +3. Pre-commit hooks automatically rebuild dependencies + +### Common Workflow + +```bash +# 1. Modify Chart.yaml +vim Chart.yaml + +# 2. Update dependencies +helm dependency update + +# 3. Check dependencies +make check-deps + +# 4. Commit changes (pre-commit hook runs automatically) +git add Chart.yaml Chart.lock charts/ +git commit -m "update helm dependencies" +``` + +## Helm Commands + +### Testing Charts + +```bash +# Template and check output +helm template + +# Template with specific values +helm template -f values.yaml + +# Dry-run install +helm install --dry-run --debug +``` + +### Debugging + +```bash +# Check current values +helm get values + +# Check all computed values +helm get values --all + +# Get manifest +helm get manifest +``` + +## Best Practices + +### Chart Structure +- Keep templates focused and modular +- Use helpers (`_helpers.tpl`) for repeated logic +- Document all values in `values.yaml` with comments +- Use semantic versioning for chart versions + +### Values Organization +- Use nested structures for related values +- Provide sensible defaults +- Document required vs optional values +- Use `.Values` consistently + +### Dependency Management +- Pin dependency versions explicitly +- Use repository URLs, not local paths in production +- Keep `Chart.lock` in version control +- Run `make check-deps` before committing + +## Common Gotchas + +❌ **Don't:** +- Use `helm dependency build` (use `update` instead) +- Forget to run `make check-deps` before committing +- Commit without running pre-commit hooks +- Hard-code values that should be configurable + +✅ **Do:** +- Use `helm dependency update` for dependency changes +- Run `make check-deps` as part of your workflow +- Let pre-commit hooks rebuild dependencies automatically +- Make values configurable and well-documented diff --git a/skills/vault-secrets/SKILL.md b/skills/vault-secrets/SKILL.md new file mode 100644 index 0000000..69acf3e --- /dev/null +++ b/skills/vault-secrets/SKILL.md @@ -0,0 +1,216 @@ +# Vault & Secrets Management + +This skill provides HashiCorp Vault best practices for secrets management. + +## When to Use + +Activates when: +- Working with secrets in Kubernetes +- Managing Vault initialization and unsealing +- Using External Secrets Operator +- Setting up new environments + +## Vault Lifecycle + +### Initialization + +**Command:** `make vault-init` + +This initializes a new Vault instance and saves keys to `vault-init/` directory. + +```bash +# Initialize Vault (first time only) +make vault-init + +# Keys are saved to vault-init/ directory: +# - vault-init/unseal-key-1 +# - vault-init/unseal-key-2 +# - vault-init/unseal-key-3 +# - vault-init/root-token +``` + +### Unsealing + +**Command:** `make vault-unseal` + +Required after pod restarts. Vault starts in a sealed state and must be unsealed with keys. + +```bash +# Unseal Vault (after pod restart) +make vault-unseal +``` + +**Why unsealing is needed:** +- Vault pods restart (manual restart, node failure, updates) +- Vault starts sealed for security +- Must provide unseal keys to make Vault operational + +## Security Best Practices + +### Never Commit Vault Keys or Tokens + +❌ **Don't:** +```bash +# Don't commit these files +git add vault-init/ +git commit -m "vault keys" # NEVER DO THIS +``` + +✅ **Do:** +```bash +# Ensure vault-init/ is in .gitignore +echo "vault-init/" >> .gitignore + +# Store keys securely offline +# - Password manager +# - Encrypted backup +# - Secure key management system +``` + +### Secrets in Code + +❌ **Don't:** +```go +// Don't hardcode secrets +const apiKey = "sk-1234567890abcdef" +password := "supersecret123" +``` + +✅ **Do:** +```go +// Use environment variables from Vault +apiKey := os.Getenv("API_KEY") + +// Or use External Secrets Operator +// which automatically creates k8s Secrets from Vault +``` + +## External Secrets Operator + +**External Secrets Operator manages Kubernetes Secret creation from Vault.** + +### How It Works + +1. Secrets stored in Vault +2. ExternalSecret CR references Vault path +3. ESO fetches secret from Vault +4. ESO creates/updates Kubernetes Secret automatically + +### Example ExternalSecret + +```yaml +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: app-secrets +spec: + refreshInterval: 1h + secretStoreRef: + name: vault-backend + kind: SecretStore + target: + name: app-secrets + creationPolicy: Owner + data: + - secretKey: api-key + remoteRef: + key: secret/data/app + property: api_key +``` + +This creates a Kubernetes Secret named `app-secrets` with data from Vault. + +## Common Workflows + +### Storing a New Secret + +```bash +# 1. Write secret to Vault +vault kv put secret/myapp/config \ + api_key=abc123 \ + db_password=secretpass + +# 2. Create ExternalSecret CR +kubectl apply -f external-secret.yaml + +# 3. Verify Kubernetes Secret was created +kubectl get secret app-secrets +kubectl describe secret app-secrets +``` + +### Rotating a Secret + +```bash +# 1. Update secret in Vault +vault kv put secret/myapp/config api_key=newkey123 + +# 2. ESO automatically syncs (based on refreshInterval) +# Or manually trigger sync by deleting the k8s Secret +kubectl delete secret app-secrets + +# 3. ESO recreates Secret with new value +kubectl get secret app-secrets -o yaml +``` + +### Debugging Secrets + +```bash +# Check Vault status +kubectl exec -it vault-0 -- vault status + +# Check if Vault is sealed +kubectl logs vault-0 | grep sealed + +# Check External Secrets Operator +kubectl logs -n external-secrets deployment/external-secrets + +# Check ExternalSecret status +kubectl describe externalsecret app-secrets +``` + +## Vault Initialization Checklist + +When setting up Vault in a new environment: + +- [ ] Run `make vault-init` to initialize Vault +- [ ] Securely save unseal keys and root token from `vault-init/` +- [ ] Add `vault-init/` to `.gitignore` +- [ ] Run `make vault-unseal` to unseal Vault +- [ ] Configure Vault policies and auth methods +- [ ] Set up External Secrets Operator integration +- [ ] Test secret retrieval and rotation + +## Pod Restart Recovery + +When Vault pods restart: + +```bash +# 1. Check Vault status +kubectl get pods -l app=vault + +# 2. Vault will be sealed - check logs +kubectl logs vault-0 | tail -20 + +# 3. Unseal Vault +make vault-unseal + +# 4. Verify Vault is operational +kubectl exec vault-0 -- vault status +``` + +## Best Practices Summary + +✅ **Do:** +- Initialize Vault with `make vault-init` +- Unseal Vault after restarts with `make vault-unseal` +- Use External Secrets Operator for Kubernetes secrets +- Store unseal keys securely offline +- Never commit Vault keys to git +- Rotate secrets regularly + +❌ **Don't:** +- Commit vault-init/ directory to git +- Hardcode secrets in code +- Manually create Kubernetes Secrets for Vault-backed data +- Leave Vault sealed +- Share root token unnecessarily