참교육(Teach You a Lesson)

몇일전 넷플릭스에 하는 "참교육"(Teach You a Lesson)이라는 드라마를 봤다.
이 나라 교육에 사악한 요소들을 그대로 꼬집고 비틀다 사이다로 참교육 하는 드라마.
그 사이다 맛에 완주하게 됐다. 그리고 생각나는 것들을 적어본다.

이 드라마에서는 나쁜 학생,교사,학부모,정치인이 등장한다. 개인적으로 학원강사 악당도 추가하고 싶다.
인터넷 유명 강사들이 수십,수백억을 벌어 성공한 인물로 묘사되고 유명해지고선 여기저기서 이런 저런 얘기를 한다.
공부를 어떻게 해야 한다느니 성실을 말하고 미래의 성공을 내세우며 우리를 가르치듯 말한다.
조언이라고 하지만 가만히 듣고 있으면 다그치고 겁준다. 물리적 폭력은 없지만 주늑들게 한다.
사실 드라마에서 교육 컨설턴트 하는 사람이 잠깐 나오는데 선행학습과 레벨을 들먹이며 학부모를 무시하는듯한 말투는 현실에서도 많이 봤다.
100을 위하는척 하지만 사실 상위 10명의 성적커트라인을 들이대고 있는 사회에 맞게 우리를 맞추려고 한다.
공부하기 싫으면 하지마 어차피 공부는 10%만 하고 거기서 경쟁하는거야.
우리는 이런 대답을 듣고서 비판없이 받아드린다. 교육을 10%를 위한게 아니다. 10%를 만들기 위한 90%가 존재하는게 아니다.
물론 학원강사인데 학교 선생이 아닌데 뭔 큰 의미를 두냐 하지만 학원 강사도 학생들에겐 선생님으로 불린다.
강사에게 뭔 기대를 하겠느냐만은 성적에 울고 웃는 전국의 수많은 학생,수험생들에게 냉정한 말은 도움보단 자존감을 갉아 먹는 악수가 될 수 있도 있다.
솔직히 그냥 자기는 인생 성공한 사람이고 내말을 잘들어라 하는식의 싸가지 없는 말들이 싫다.

알게 모르게 개인의 무능/어리숙함 이런것들은 이제 DNA 에 박힌 주홍글씨 같은 세상이다.
말은 안하지만 겉으로 웃으면서 속으론 미워하고 보듬다가도 정작 도움의 필요할땐 돕지 않고 경쟁할때 그냥 남이 된다.
그게 세상이라고 적응하고 노력해서 세상에 어울려 살아야 한다고, 그러려면 니가 지금 그렇게 나태하게 있으면 안된다고.
내가 어렸을때 몇몇 어른들에게 종종 들었던 소리다.
방구석 한쪽에 잔뜩 쌓인 수능 비디오 테잎들이 플레이 한번 안되고 그냥 먼지만 쌓인 기억이 난다.
자식을 위해 뭐라도 더 해주려고 하는 부모의 맘으로 시골에서도 학원을 보내고 과외를 시켰지만 난 집중하지 못하고 시간을 보냈다.
그렇다고 그 시간이 편했던건 아니다. 미래에 대한 불안감만 잔뜩 않고 어떻게 해야될지 몰랐고 애써 괜찮다고 스스로를 위로했다.
내 머리가 그정도 밖에 안된다는건 그때는 인지조차 하지 못했다.
그냥 컴퓨터를 가지고 노는 것을 좋아했던 나만 있었고 그렇게 요즘의 눈에는 나태한 유년시절을 보냈다.
그냥 젊으니까 학교/숙제/학원/시험 이런것만 빼고 컴퓨터만 할 수 있으면 행복했던 때였던것 같다.
자식을 키우는 부모가 되서는 나는 부모로써 나태해지고 있다.
학원을 많이 보내지도 않고 셤을 잘 못봐서 화나긴 해도 잘했다고 말하고 소리를 지르거나 아이를 크게 나무라진 않는다. (어쩌면 중고등학생이 되면 아이에게 기대를 하고 성적 때문에 화낼 지도 모르겠다.)
하지만 이런 나를 보고 주위에선 어떤 반응일지 상상이 간다.
그렇게 하면 안되다고 애를 너무 방치한다고 그래도 그말도 틀리지 않지.
난 항상 그런 생각을 한다. 꼴지는 어떻게 살아야 하나, 모두들 1등만 보고 달리라는 무수히 많은 말들이 있지만 꼴지, 아니 성적 하위권 학생들에게 관심을 기울이지 않는다.
교육은 성적을 올리는게 아닌데 등수로 사람의 인생이 달라지니 그냥 치열하게 경쟁에서 계속 이겨내야만 할까?
꼴지도 행복하게 살 수 있는 기회를 주고 길을 찾아 주는게 우리 아이가 매일 학교에 가는 중요한 이유중에 하나다.

AI 로 만든영화가 칸영화제에 갔지만 환대 받지 못했다는 뉴스를 봤다.
AI 사용하면 감독,작가,예술가가 아니다라고 주장하는 유명인들이 있다.
나같이 프로그래머는 AI가 코딩을 해주니 대체될수 있는 인력이지만 이런 예술가들은 철저히 자신들은 AI 와 격이 다른 존재라고 선을 긋는듯 하다.
AI시대가 되면서 개인적으로 좋은점 좀 통쾌한 점은 이런 잘난 지식인/예술가들 엿먹일 수 이는 환경이 만들어 지고 있다는 사실이다.
똑똑하다는것의 기본은 암기부터 시작된다고 본다.
수학공식을 철저히 이해하고 푸는 1%의 천재들외 1~20의 상위권은 공식을 외워 적용하는게 시험 점수를 더 잘받는 당연한 원리였다.
두뇌라는 성능 좋은 하드웨어를 가진 자들이 좋은 점수로 세상을 리드하고 성공하는 세상이었다.
많이 안다는것 머리속에 지식을 많이 쌓아 언제든지 끄집어 낼 수 있는 훌륭한 무기인 세상이었다.
머리속에 외우두면 반은 먹고 들어가는 시험들이 주가 됐고 시험을 통과하면 권력이 기다리고 있었다.
쌓아올린 지식에 비해 낙후된 인성은 그 똑똑이들을 때론 사슬 없는 도사견으로 만들어 버리기도 했다.
똑똑한 의사의 역할이 앞으로 기대될 신약으로 힘을 잃는 시대를 솔직히 기대한다.
이런 시대의 변화중에서도 우리의 교육은 아이를 성적으로 재고 있고 그 순위 경쟁에만 매몰된 교육 환경이 이 드라마에서 보이는 악의 씨앗이 되버렸다.
인권을 들먹이며 제대로된 처방을 놓치고 수십년을 방치한 결과 우리나라 교육의 비극적 사건들은 늘어났다.
드라마 처럼 사이다 해결이 아니라면 도대에 어떻게 교육의 악당들을 처벌할 수 있고 각종 학원범죄를 막을 수 있을까?
토론을 통한 사회적 합의? 토론은 수없이 했고 서로가 옳다고 외치고는 제대로 해결은 하지 않는다. 말만 주절주절.
결단을 내리고 실행할 수 있는 의지는 과연 있었던건지 나를 포함한 어른들에 묻고 싶다.
어떤 신문 사설에 이 드라마가 사이다라 좋지만 경계해야 한다는등의 글을 봤다.
이런식이다. 뭔가 정답이 없는 문제에 최소한의 정답을 찾은듯한 말투로 어정쩡한 중립을 말하며 그게 마치 최선인 양 그래도 폭력은 안된다 그래도 복수는 안된다 하는 그런 소리들.
살면서 모두가 납득하고 이해를 할수 있는 해결책이 얼마나 될까? 최소한 상식은 이제 내가 알던 그 옛날의 상식이 아니다.
비단 학교 뿐이 아니라 나라꼴 돌아가는 걸 보면 TV 에 보이는 밉상들 나태와 탐욕에 쩌든 기득권들에게 김무열의 화끈한 싸대기가 함께하길.

trash to /dev/null

화가 치밀어 오늘때가 있다. 예전엔 안그랬는데, 사소한것에 신경이 날카로워지고 꾹꾹 참다 애꿎은 곳에 화풀이 한다.
크게 소리를 질러보다가 욕을 크게 함질러 볼까 하다가 조용히 내뱉고 삼킨다.
왜 그럴까 했는데 그런 생각은 안하기로 했다. 그냥 그럴 수 밖에 없는 나라는 물질의 특성이라고 인정하고 더 이상 깊게 파보려 하지 않는다.
마트에 가서 장을 보다 요거트에 1+1 행사 상품을 보고 집어 들었다. 그런데 팩이 아닌 낱개로 되어 있었다.
8개나 되는 요거트를 어떻게 들고 갈까 고민을 잠시했다. 정문에 있는 바구니를 가져오면 될것을 그냥 양손과 몸을 바구니 삼아 쌓아 올려 계산대까지 갔다. 계산대에 내려 놓다 1개가 떨어지고 바닥에 요거트가 터져 흘렀다.
순간 계산대 아주머니는 이거 사야한다고 말하고, 나는 연신 죄송하다고 얼른 터진 요겉를 집어 세웠다.
주위에 사람들이 많지 않았지만 쪽팔림과 함께 왜 이런 멍청한 짓을 했는지 속으로 나를 탓하고 있었다.
집에서 가져간 장바구니가 있었지면 아직 사지도 않은 제품을 여기 넣는건 왠지 물건 훔치는 모슴으로 비춰지는것 같아  사용하지 못했다.
나가서 장바구니를 가져올걸, 1+1 아닌 다른 요거 상품을 살걸하면서, 후회한다.
그렇게 집에 오는 길에 아씨 아씨 하면서 잔뜩 성난 표정으로 한숨을 내쉬며 온다.
이 모습은 내가 봐도 화가 풀리지 않는 어린아이 행동 처럼 보인다.
뭐가 분한건지 그 누구도 아닌 내 잘못인것을 마치 누명이 씌워진 것 처럼 억울해 한다.
그래 안다. 이런 욕하고 투덜거림이 좋지 않다는것을.
하지만 또 한번 생각해보면 이걸 악스런 구린내 감정들을 어디다 퍼붓지 않으면 폭발할것 같았다.
그때의 그 감정이 남들이 보기에 흉측해 보여도 그 감정을 어찌할 방법을 몰라 발을 동동 굴리는 안쓰런 내가 있었다.
차라리 힘을 빼버릴까 그러면서 욕할 힘도 사라질테니
그냥 베개라도 실컷 때려볼까 그럼 좀 나아질 수도
그 당시 그 통제할 수 없는 그 감정은 바로 해결까진 아니더라고 내와 내가 사랑하는 이들이 실망하지 않게 다치지 않게 안전 장치가 있었으면 하는 생각이 들었다.
그 쓰레가 같은 욕도 감정도 모두 담아 둘 수 없기에 난 cat trash >! /dev/null 가 되길 바란다.
하지만 이 물질 세계의 존재인 내 말들은 /dev/stdout /dev/stderr 로 흘러갈 수 밖에 없다.

vector memory growth issue in argo-workflow

k8s 환경의 특정 노드에서 동작중인 vector pod 1개가 메모리가 계속증가하고 있었다.
이유는 argo workflow 노드1개에만 스케쥴링되어서다.

[스케쥴링 원인]
argo-workflow(controller) 가 직접 스케줄링 하는 게 아니라 k8s 기본 스케줄러 (kube-scheduler) 가 워크플로우 task 파드를 노드에 배치한다.
workflow spec 에 nodeSelector/affinity 가 없어 다음 스케줄러의 기본 점수 두 개로 결정된다.
1. NodeResourcesFit(과거 k8s v1.22 이전 NodeResourcesLeastAllocated, NodeResourcesMostAllocated, RequestedToCapacityRatio 등이 통합됨)
- 각 노드의 요청(request) 점유율이 가장 낮은 노드에 가장 높은 점수.
- 당시 CPU request worker01 34% / worker02 35% / worker03 25% <- 최저 / worker04 30% / worker05 30%
- 그래서 새로 들어오는 워크플로우 task 가 매번 worker03 으로 떨어짐.

2. ImageLocality
- 노드에 이미 캐시된 이미지를 쓰는 파드 에 추가 점수.
- 첫 워크플로우가 worker03 으로 떨어지면 그 노드에 이미지가 캐시 -> 다음 워크플로우도 worker03 이 더 높은 점수 -> 눈덩이 효과.

결과적으로 워크플로우 task 생성되면 -> kube-scheduler 점수 계산 -> worker03 선택 -> 이미지 더 강하게 캐시됨 -> 다음 task 도 같은 결과 -> 누적

[vector 로그 대상]
vector 의 kubernetes_logs source 는 pod들을 watch 한다.
pod 가 살아있으면 vector 는 그 파드를 수집 대상으로 계속 인식하고 다음을 메모리에 들고 있는다.
- 파드 메타데이터 캐시: namespace / pod_name / container_name / labels / annotations / node_name 등 100여 개 누적되면 무시 못할 양.
- file watcher state: 각 컨테이너 로그 파일의 inode, 마지막 read offset(checkpoint), open file descriptor.
- glob rescanning: config 에 glob_minimum_cooldown_ms: 8000 이라 8초마다 /var/log/pods/** 를 다시 스캔. 완료된 파드 디렉토리가 매번 결과에 잡혀 비교 작업이 일어남.

[조치1]
ns:argo-workflow > cm:workflow-controller-configmap > 아래 내용을 설정한다.
data:
  config: |
    workflowDefaults: # 각 워크플로가 별도의 설정이 없다면 사용될 디폴트 설정
       spec:
         podGC: # 워크플로우 task 파드 정리 전략1 - 상태 기반
           strategy: OnWorkflowSuccess # 워크플로우 전체가 성공으로 끝났을 때 task 파드들을 일괄 삭제. 실패하면 파드를 남겨 두어 사후 디버깅.
           deleteDelayDuration: 1m # strategy 가 발동한 뒤 1분 대기 후 실제 삭제. 로그 수집기(vector 등) 가 마지막 라인을 읽어 Kafka 까지 보낼 시간 확보.
         ttlStrategy: # 워크플로우 task 파드 정리 전략2 - 시간 기반
           secondsAfterSuccess: 3600 # 성공한 Workflow CR 을 1시간 뒤 삭제.
           secondsAfterFailure: 86400 # 실패한 Workflow CR 은 24시간 보존 후 삭제.

podGC + ttlStrategy 로 스케줄링 노드 편중을 막진 않지만 누적을 끊어 영향 자체를 무력화시킨다.
podGC , ttlStrategy 는 둘중 하나만 만족되면 정리가 되네 일정기간 유지하고 싶다면 podGC는 빼고 ttlstrategy 만 사용해야 한다.

argo workflows v2.4+ 부터 controller 가 ConfigMap 변경을 watch 해서 자동 reload 해서 별도 재시작이 필요 없다.
workflowDefaults(podGC/ttlStrategy)는 신규 워크플로우 부터만 적용된다.

[조치2]
이미 진행 중이거나 완료된 워크플로우에는 적용 안되니 작업이 끝난 workflow pod들을 종료한다.
kubectl -n argo-workflow delete pod --field-selector=status.phase=Succeeded
kubectl -n argo-workflow delete pod --field-selector=status.phase=Failed

[조치3]
vector 는 rust 로 작성되어 있고 jemalloc 을 기본 할당자로 사용한다.
jemalloc 은 한번 so 로 부터 받은 메모리를 내부 free pool 로 두고 잘 OS 로 돌려주지 않는다.
즉 vector 가 내부적으로 이제 안 쓰는 메모리가 됐어도 프로세스 RSS / working set 은 그대로 보인다.
새로 들어오는 워크로드는 이 free pool 을 재활용하므로 메모리는 더 늘지 않지만, 줄어들지도 않는다.
이런 이유로 메모리가 증가된 vector pod1개는 새로띄운다.(vector daemonset 이라 pod 삭제하면 해당노드새 새 vector pod 생성된다.)
kubectl -n vector delete pod vector-abc123

사실 개별 workflow 는 ttl 설정이 되어 있어 자동 정리(삭제)가 되는데, cronworkflow 부분이 빠져 있어 문제가 됐다.