ArgoCD etcdserver: request is too large — Application przekracza limit 1 MB
Diagnoza i naprawa błędu etcdserver: request is too large w ArgoCD, gdy Application CRD przekracza limit 1 MB w etcd.
ResourceExhausted. Ten runbook pokazuje jak zdiagnozować problem i naprawić go w kilka minut.
Ten runbook jest częścią serii o blokadach synchronizacji ArgoCD. Zobacz też: HPA OutOfSync loop i deadlock operacji. Jeśli interesuje Cię szerszy kontekst GitOps i ArgoCD, przeczytaj nasz post o GitOps i ArgoCD.
Objaw
W logach argocd-application-controller pojawia się błąd:
# Error in argocd-application-controller logs:
# rpc error: code = ResourceExhausted desc = etcdserver: request is too large
kubectl get application <APP_NAME> -n argocd -o json | wc -c
# Output > 1048576 (1 MB) = problem confirmed
Application nie przechodzi w stan Synced. Każda próba sync kończy się tym samym błędem. ArgoCD UI może wyświetlać status Unknown lub Syncing bez postępu.
Przyczyna
Każdy obiekt w Kubernetes (w tym Application CRD) jest przechowywany w etcd, który ma twardy limit 1.5 MB na pojedynczy obiekt (domyślnie konfigurowany na 1 MB w wielu dystrybucjach). ArgoCD zapisuje w Application CRD nie tylko konfigurację, ale też:
.status.history— pełną historię poprzednich synchronizacji (manifesty, parametry, wyniki).status.resources— listę wszystkich zarządzanych zasobów z ich stanemmanagedFields— metadata Kubernetes śledząca, kto zmienił jakie pole
Przy dużych Helm chartach (100+ zasobów) lub przy długiej historii synchronizacji, Application CRD rośnie powyżej limitu etcd. Problem narasta z czasem — każdy sync dodaje wpis do historii. Domyślna wartość revisionHistoryLimit to 10, ale w środowiskach z częstymi deploymentami (np. kilka razy dziennie) historia kumuluje się szybko.
Dodatkowym czynnikiem jest managedFields — metadata dodawana przez Kubernetes server-side apply. Każde pole w każdym zarządzanym zasobie ma wpis o tym, kto je ostatnio zmodyfikował. Przy setkach zasobów te metadane potrafią same zająć setki kilobajtów.
Rozwiązanie
A) Ogranicz historię synchronizacji (natychmiastowa ulga):
# Check current history size
kubectl get application <APP_NAME> -n argocd \
-o jsonpath='{.status.history}' | wc -c
# Patch: reduce history to last 3 entries
kubectl patch application <APP_NAME> -n argocd --type merge -p '
{
"spec": {
"revisionHistoryLimit": 3
}
}'
# Force cleanup of existing oversized history
kubectl get application <APP_NAME> -n argocd -o json | \
jq '.status.history = .status.history[-3:]' | \
kubectl apply -f -
B) Skonfiguruj resource.customizations w argocd-cm ConfigMap:
# argocd-cm ConfigMap patch — strip managedFields from tracked resources
apiVersion: v1
kind: ConfigMap
metadata:
name: argocd-cm
namespace: argocd
data:
resource.customizations.ignoreDifferences.all: |
managedFields:
- manager: "*"
resource.compareoptions: |
ignoreResourceStatusField: all
# Apply and restart repo-server to pick up changes
kubectl apply -f argocd-cm-patch.yaml
kubectl rollout restart deployment argocd-repo-server -n argocd
C) Podziel dużą aplikację na mniejsze Applications (ApplicationSet):
Jeśli Twój Helm chart zarządza ponad 100 zasobami, rozważ podział na logiczne grupy. ApplicationSet pozwala generować wiele Applications z jednego szablonu:
# Instead of one monolithic Application with 200+ resources,
# split into logical groups using ApplicationSet
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
name: platform-components
namespace: argocd
spec:
generators:
- list:
elements:
- chart: networking
path: charts/networking
- chart: monitoring
path: charts/monitoring
- chart: workloads
path: charts/workloads
template:
metadata:
name: "platform-"
spec:
project: default
source:
repoURL: https://github.com/org/infra.git
targetRevision: main
path: ""
destination:
server: https://kubernetes.default.svc
namespace: ""
syncPolicy:
automated:
prune: true
selfHeal: true
Podział na mniejsze Applications ma dodatkową zaletę — poszczególne grupy zasobów synchronizują się niezależnie, co skraca czas pojedynczej operacji sync i poprawia metryki DORA (deployment frequency, lead time for changes).
Walidacja
# 1. Verify Application resource size is under 1 MB
kubectl get application <APP_NAME> -n argocd -o json | wc -c
# Expected: < 1048576
# 2. Verify sync status is Synced
argocd app get <APP_NAME> --output json | jq '.status.sync.status'
# Expected: "Synced"
# 3. Verify health status
argocd app get <APP_NAME> --output json | jq '.status.health.status'
# Expected: "Healthy"
# 4. Check controller logs for recurring errors
kubectl logs statefulset/argocd-application-controller -n argocd \
--since=5m | grep -c "error"
# Expected: 0 or minimal
Jeśli rozmiar Application spada poniżej 1 MB i sync przechodzi bez błędów, problem jest rozwiązany. Monitoruj przez kilka cykli reconciliation (3-5 minut), aby upewnić się, że obiekt nie rośnie z powrotem.
Pipeline CI/CD blokuje Twój zespół?
Umów bezpłatną 30-minutową rozmowę. Przejrzymy konfigurację ArgoCD i wskażemy, co naprawić od razu.