도커 운영 시의 장애 대책
주로 dockerd 자체보다는 운영하는 사람의 실수나 부주의에서 비롯되거나 서버 리소스에 의한것이많다.
장애를 막기 위한 이미지 운영
의도하지 않은 컨테이너가 실행되는 경우
- 운영 환경에서 latest버전의 이미지를 실행하거나 컨테이너 오케스트레이션 과정에서 최신 이미지를 실행한 상황
- latest 외의 버전 이미지를 덮어쓴 상황
- example/aaa:latest 태그로 빌드해야될 이미지를 example/bbb:latest 태그로 빌드한 상황(다른 이미지와 바뀜)
이미지 테스트
실행단계에서 이미지가 잘못되었는지 판단하면 늦다. 이전에 이미지 테스트를 거치는것이 좋은데 이를 위해 container-structure-test가 많이 사용된다.
container-structure-test는 구글에서 오픈 소스로 공개한 테스트 프레임워크로 도커이미지를 테스트 대상으로 한다. 컨테이너안에 특정 파일의 존재여부, 파일 내용확인등을 진행할 수 있다.
디스크 용량 부족
도커 호스트 역시 디스크 용량 부족을 주의해야 한다. 용량이 가득차면 새로운 컨테이너를 만들수도 없고 기존 컨테이너의 실행에도 지장이 생긴다. 서드파티 모니터링 도구를 사용한 호스트 디스크 용량 모니터링은 필수이며 도커에서도 디스크 용량을 낭비하지 않도록 해야한다. 이를 위해 불필요한 이미지나 컨테이너는 디스크에서 삭제하는것이 좋다. 이럴경우 docker prune 명령어(사용하지 않는 이미지나 컨테이너 일괄 삭제)를 cron을 통해 야간에 실행하면 좋다
쿠버네티스 운영 시의 장애 대책
쿠버네티스는 장애에 강한 컨테이너 오케스트레이션 시스템이지만, 노드 다운등 장애를 일으킬 수 있는 몇 가지 요인이 있다.
노드가 장애를 일으켰을 때 쿠버네티스의 동작?
노드가 장애를 일으켜 다운됐을 때 노드에 배포된 파드가 어떻게 되는지 알아봐야한다. 한 노드가 다운되면 정지된 파드들은 다른 노드로 배치된다. 이는 파드를 생성하는 레플리카 세트가 지정된 수의 파드를 유지하려고 하기 때문이다. 이를 오토힐링이라 한다. 레플리카세트가 관리하는 파드를 노드에서 의도적으로 삭제한 경우에도 같은 일이 일어난다. 즉 쿠버네티스에서는 레플리카세트를 관리하는 디플로이먼트나 스테이트풀세트, 데몬세트를 이용해 파드를 생성하는것이 가장 좋은 대책이다.
파드 안티 어피니티를 이용해 장애에 강한 파드 배치 전략 수립하기
레플리카세트의 오토힐링은 강력하지만 다른 노드로 파드가 재배치되는 동안에는 다운타임을 피할 수 없다.(replicas=1일때 치명적.)
그러므로 이러한 문제점의 피해를 최소화 하기위해 파드가 여러 노드에 나눠 배치되어야 한다. 이를 위해 replicas 값을 적절히 조절하는 방법을 사용한다. 파드가 여러 노드에 걸쳐 배치돼 있는 만큼 다운타임 없이 파드가 재배치 될 수 있을것이다.
하지만 파드 여러개가 한노드에 배치되어있는경우 해당 노드가 죽을경우 모두 정지되므로 파드가 여러개라도 다운타임이 생기게 된다. 쿠버네티스는 시스템 리소스가 여유 있는 노드를 골라 파드를 배치하기 때문에 앞서말한 가능성을 배제할 수 없다. 이를 해결하는 기능이 바로 파드 안티 어피니티(pod antiaffinity)
이다. 이것은 파드간 상성을 고려한 배치전략을 규칙으로 정의한다. 이를 통해 C파드가 정의된 노드에는 D파드를 배치하지 말것과 같은 규칙을 정의할 수 있다. 디플로이먼트 정의에서 spec.affinity.podAntiAffinity설정에 이를 정의할 수 있다.
만약 replicas=3으로 했을 때 존재하는 노드가 2개 뿐이라면 하나의 파드는 펜딩상태가 되고 노드가 클러스터에 추가된 시점에 배치된다.
파드 어피니티라는 기능도 있는데 이는 파드 A는 파드 B와 자주 통신하므로 같은 노드에 배치한다 와 같은 경우에 활용할 수 있다.
CPU 부하가 큰 파드를 노드 어피니티로 격리하기
어플리케이션에 따라 CPU 부하가 큰 특성을 갖기도 한다. 배치잡처럼 CPU 부하가 클 경우 같은 노드 내 다른 파드의 성능을 떨어뜨린다. 이 경우 배치잡 파드를 전용 노드로 격리해야할 필요가 있다. 이를 위해 노드에 용도별로 구분짓는 레이블을 부여하고 파드 배치 규칙에 해당 레이블을 갖는 노드에만 파드를 배치하면 된다. 특정 레이블이 부여된 노드에만 파드를 배치하는 규칙을 정의하는 것이 노드 어피니티 이다.
노드에 레이블을 부여하기 위해 instancegroup 값을 설정하고 웹 어플리케이션이나 API파드만을 배치할 노드에는 webapi, 배치 잡만을 처리할 노드에는 batch라는 레이블을 붙여 용도를 구분한다. 정의된 규칙에 부합하는 노드가 없는경우 파드는 배치되지 않고 Pending 상태로 남는다.
HPA를 이용한 파드 오토 스케일링
HPA(Horizontal pod autoscaler)는 시스템 리소스 사용률에 따라 파드 수를 자동으로 조정하는 쿠버네티스 리소스이다. HPA는 파드의 오토 스케일링 조건을 디플로이먼트나 레플리카세트에 부여하기 위한 리소스다. 노드에 대한 파드의 CPU 사용률이 40퍼센트를 넘었을 때 파드에 오토 스케일링을 적용하고 싶을 때 사용하면 된다. 설정된 CPU 사용률 기준을 초과하면 자동으로 새로운 파드를 만들고 maxReplicas에 설정된 개수 이상의 파드는 생성하지 않는다.
HPA는 Cluster Autoscaler와 함께 사용할 때 효과가 극대화 된다.
Cluster Autoscaler를 이용한 노드 오토 스케일링
HPA가 파드의 오토 스케일링을 제공한다고 해도 파드를 배치할 노드 리소스가 충분하지 못할 수 있다. 이경우 Cluster Autoscaler을 사용한다. Cluster Autoscaler는 쿠버네티스 클러스터의 노드 수를 자동 조정한는 역할을 한다. 이는 쿠버네티스 리소스가 아니라 노드 오토 스케일링 기능을 제공하는 별도의 도구이다.
헬름의 릴리스 히스토리 제한
헬름으로 어플리케이션을 배포하는 경우 릴리즈 히스토리로 인한 문제가 발생할 수 있다. kubectl -n kube-system get configmap
을 입력하면 어플리케이션명, 버전명이 붙은 컨피그 맵이 생성되어 있다. 헬름을 통해 설치, 업데이트를 반복하면 그만큼 컨피그 맵이 생기게 된다. 이를 피하기 위해 helm init 명령으로 틸러를 배포할 때 –history-max 옵션으로 히스토리 저장 최대 건수를 정한늑서이 좋다.