Bullshitting Blog

개소리하는 블로그

Simple is the best

Tags = [ architecture ]

simple-is-the-best.md

이전까지는 회사에서 제품 설치 난이도를 줄이기 위해 쿠버네티스 설치를 간편하게 하는데 집중하고 있었다. 그러다가 문득, 쿠버네티스를 사용하는 이유에 대해 고민해보게 되었다. 고민해보게 된 이유는 간단하다. 매번 장애가 나면 대부분 네트워크인데, 이 네트워크 문제를 더 복잡하게만 만들고, 스케일아웃을 하지 않는 온프레미스 서버이기 때문에 클라우드처럼 비용 최적화를 위해 오토스케일을 할 필요가 없기 때문이다.

결론은 금방 나왔다.

쿠버네티스를 사용하는 이유

쉽게 말해서 한 명의 인프라 관리자가 커버할 수 있는 서버를 늘리는 것이다(일자리 냠냠). 이전엔 각 서버를 따로따로 관리하면서 진행했겠지만, 쿠버네티스를 서버에 설치하고 노드를 엮는 순간 한 관리자가 API 호출을 통해 프로세스를 원하는 노드에 쉽게 올릴 수 있다. 심지어 인프라를 코드로서 관리할 수 있게 된다. 인프라 구성을 yaml파일로 만들어 두면, 그냥 kubectl apply -f filename.yaml 한 방에 구성된다. 코드로서 관리한다는 것은 라이브러리화가 가능하다는 것도 시사한다. 마치 npm처럼 사용할 수 있는 helm이 등장한다. 클라우드 세팅까지 함께 진행 가능한 Terraform도 등장한다. 꽤 큰 변화가 아닌가 싶다.

문제점

소프트웨어를 제품을 타사에 설치해주는 경우, 쿠버네티스가 여기에 포함된다면, 그리고 상주인력을 파견하지 않는 형태라면, 대참사가 벌어진다. 일단 겪어본 것만 나열해 보겠다.

  1. 서비스에 장애가 발생했는데, 다수의 Restart 후 etcd의 리소스 사용량이 치솟더니 호스트가 죽어버린 케이스가 발생했다. 문제를 전달받고 방문했을 땐 이미 디버깅조차 할 기회가 없었다. 디버깅을 위해 루트 권한이 필요함은 물론 기본이다.
  2. Calico CNI를 오랫 동안 켜두면 어느 순간 멈춘다. → 매일 서비스 가동과 함께 재시작한다.
  3. 로그 용량을 제한할 정책을 제대로 만들지 않고 서비스를 방치하면 거래량이 많거나 다른 문제가 있는 경우 터진다.
  4. 리눅스의 자동 업데이트 기능으로 인해 도커 데몬이 영향을 받으면 다 터진다. → 자동 업데이트를 해제한다.
  5. Kubeadm으로 설치할 때 발급된 API call 시 사용할 인증서의 유효기간은 1년이다. → 1년 마다 모든 고객사를 방문해서 루트 권한을 받아 인증서를 갱신해야 한다.
  6. 고객사의 쿠버네티스 버전을 업데이트하기 위해서는 루트 권한을 받아서, 현재 클러스터를 내리고, kubelet도 내리고, kubelet, kubeadm, kubectl 바이너리를 새 것으로 교체하고, 쿠버네티스의 새 버전 이미지들을 로드하여 kubeadm init만 하는 과정이면 정말 쉬울텐데... 1.18버전에서 1.21버전 올라갈 땐 몇몇 피쳐가 정식 피쳐로 바뀌면서 서비스의 yaml 파일들을 싹 업데이트해야 했고, 1.26버전을 올라갈 땐 도커 지원을 중단하는 큰 변화가 발생해서 containerd를 추가로 세팅해야 했다. 솔직히 또 1년 안에 무슨 큰 변화가 발생할 지 겁이 난다.

보다시피, 쿠버네티스는 인프라를 직접 관리하는 운영자가 사용하기 위한 것이지, 타사에 납품할 제품에 심는 그런 것이 아니다.

그럼 어떻게?

이미 내 눈 밖에 났다. 쿠버네티스를 날려버렸다. 내가 관리하는 마이크로서비스가 쿠버네티스에 요청을 날려서 모델을 로드할 워커의 개수와 모델에 등록할 작업의 개수를 관리하는 역할을 하는데, 여기서 쿠버네티스 환경인지 아닌지를 탐지해서 쿠버네티스가 아닌 경우 해당 피쳐를 off시키도록 바꿨다. 애초에 제품이 스케일아웃을 고려하여 stateless하게 개발되었기 때문에 다른 마이크로서비스들엔 딱히 이슈가 없었다. 그리고, 도커 이미지가 아닌, 바이너리로 그대로 가져다 쓰는 것도 문제 없도록 했다. 물론, 새 고객사엔 podman으로 서비스를 운영한다. 도커 이 살찐고래는 너무 많은 권한을 가지고 있다. 단지 포트 열고 통신하고 로직을 돌릴 프로그램을 적재하는데 루트권한은 투머치다. podman은 루트가 필요없다. 만만세. 아, 그리고 이후 시간이 날 땐 rpm, deb 패키징도 해볼 생각이다.

결과

편해졌다.

그런데, 뜬금없이 이 과정에서 엄청난 일이 발생했다. 사용하고 있는 메시지큐의 리소스 요구량이 확 줄어든 것이다. 기존엔 2000개 동시작업을 처리하기 위해 broker와 bookie를 3개씩 올리고 거기다 각각 3cpu를 할당하고, 워커에 4개를 할당하고 zookeeper, proxy까지 합하면 최소 25cpu를 할당해야 했는데, 그냥 standalone 이미지 하나로 올리니, 12-thread cpu 서버에서 2000개 잡을 비슷한 수준의 레이턴시를 보이며 돌려버렸다.

결국, 2.0의 흔적은 신규 학습에서 제외된 몇몇 모델을 제외하고, 대부분 사라졌다. 물론 사내에서 실장 레코드를 쌓기 위한 서버는 여전히 쿠버네티스를 이용 중이다. 실시간으로 관리하고 있으니까 말이다.