출처 - https://kubernetes.io/blog/2021/05/14/using-finalizers-to-control-deletion/
Finalizer는 Kubernetes 객체가 삭제되기 전에 특정 작업을 수행하도록 보장하는 메커니즘입니다. 이는 metadata.finalizers
필드에 키로 추가되며, 객체의 삭제를 지연시켜 자원 정리나 다른 필요한 작업이 완료될 수 있게 합니다. 객체에 Finalizer가 있는 경우, 모든 Finalizer가 제거될 때까지 객체는 실제로 삭제되지 않습니다.
이처럼 Finalizer는 Kubernetes 환경에서 자원 관리의 일관성과 신뢰성을 보장하는 중요한 도구입니다.
예시:
apiVersion: v1
kind: Pod
metadata:
name: mypod
finalizers:
- example.com/my-finalizer
Argo CD는 Kubernetes에 선언적 GitOps 연속 배포를 제공하며, Finalizer를 통해 애플리케이션과 관련 자원 삭제를 관리합니다.
resources-finalizer.argocd.argoproj.io
Finalizer는 애플리케이션 삭제 시 관련 자원들을 함께 삭제합니다.Finalizer를 사용할 때 몇 가지 일반적인 문제 상황이 발생할 수 있습니다. 다음은 몇 가지 예시와 해결 방법입니다.
Finalizer로 인해 삭제 중 상태에 고착됨:
Terminating
상태에 고착되어 삭제되지 않는 경우가 있습니다. 이는 주로 Finalizer가 정리 작업을 완료하지 못했기 때문입니다.kubectl proxy
를 사용하여 Kubernetes API 서버와 직접 상호작용하고, Finalizer를 수동으로 제거할 수 있습니다.kubectl proxy &
kubectl get namespace example-ns -o json > example-ns.json
# example-ns.json 파일에서 "finalizers" 필드를 빈 배열로 수정
curl -X PUT --data-binary @example-ns.json http://127.0.0.1:8001/api/v1/namespaces/example-ns/finalize
Finalizer가 제거되지 않음:
kubectl patch
명령어를 사용하여 Finalizer를 강제로 제거할 수 있습니다.kubectl patch <resource-type>/<resource-name> -p '{"metadata":{"finalizers":[]}}' --type=merge
Finalizer를 사용하면 리소스 정리가 더 확실해지지만, 위와 같은 문제들이 발생할 수 있으므로 주의가 필요합니다. 문제 발생 시에는 해당 리소스의 상태와 Finalizer 설정을 면밀히 확인하고, 필요에 따라 수동으로 정리 작업을 수행해야 합니다.
처음 EKS에서 ArgoCD GitOps 패턴을 사용하여 App-of-Apps를 운영하던 중 argocd 부트스트랩 디렉토리 구조 변경으로 인해 Finalizer가 제거되지 않는 문제에 빠진 경험이 있습니다.
다행(?)스럽게도 애플리케이션이 올바르게 삭제되지 않아서, 장애가 발생할 수 있는 상황을 대처 할 수 있었습니다. ( 본문에서는 다행이라고 했지만, 원래 동작사항은 어플리케이션이 모두 삭제 되어야 하는 상황입니다. )
기존에 구성되어 있던 App-of-Apps 디렉토리를 변경하면서, 이전 경로를 참조하는 Finalizer가 제대로 제거되지 않아 애플리케이션이나 네임스페이스가 삭제되지 않는 문제 발생.
OutOfSync
상태로 남아 있음.올바른 프로젝트 구조를 적용한 뒤, 리소스에 적용되어있는 finalizer 관련 내용을 제거하여 Argocd가 다시 싱크를 맞출 수 있도록 구성하여 장애상황을 회피할 수 있었습니다.
kubectl patch some-resource/some-name \
--type json \
--patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
애플리케이션 경로 업데이트:
values.yaml
파일을 수정합니다.repoURL: https://github.com/your-repo
path: new-folder-path
기존 애플리케이션 삭제:
kubectl patch application <application-name> -n argocd -p '{"metadata":{"finalizers":[]}}' --type=merge
네임스페이스 강제 삭제:
Terminating
상태에 고착된 경우, Finalizer를 수동으로 제거합니다.kubectl proxy &
kubectl get namespace example-ns -o json > example-ns.json
# example-ns.json 파일에서 "finalizers" 필드를 빈 배열로 수정
curl -X PUT --data-binary @example-ns.json http://127.0.0.1:8001/api/v1/namespaces/example-ns/finalize
새로운 App-of-Apps 생성:
argocd app create app-of-apps \
--repo https://github.com/your-repo \
--path new-folder-path \
--dest-server https://kubernetes.default.svc \
--dest-namespace argocd
동기화 상태 확인 및 갱신:
argocd app sync app-of-apps
캐시 갱신:
kubectl rollout restart deployment/argocd-server -n argocd
Kubernetes와 Argo CD에서 Finalizer를 이해하고 사용하는 방법에 대해서 정리해 보았습니다.
Finalizer는 객체 삭제 전 정리 작업을 보장하며, 특히 App-of-Apps 패턴을 사용할 때 유용합니다.
디렉토리 변경으로 인해 발생할 수 있는 문제를 해결하기 위해, 애플리케이션 경로를 업데이트하고, 강제로 Finalizer를 제거하며, 새로운 App-of-Apps를 생성하는 과정을 통해 문제를 해결할 수 있습니다.
이러한 절차를 통해 Argo CD를 안정적으로 운영하고, GitOps 환경에서 효율적으로 리소스를 관리할 수 있습니다.