보안과 신뢰성의 관점에서 보는 안정적인 소프트웨어 서비스 제공 환경 구성하기
1. 서론
“SRE를 위한 시스템 설계와 구축” 도서 리뷰는 한빛미디어 <나는 리뷰어다> 활동을 위해서 책을 제공받아 작성된 서평이다.
최근 Applied AI Scientist 라는 포지션으로 근무를 시작하게 되면서, MLops라던지, 머신러닝을 관리하는 인프라 부분과 서비스 안정성에 대해 다룰 일이 급격하게 많아지게 되었다.
“서비스 안정성”, 여태껏 소프트웨어를 공부하면서 이론적으로는 수도 없이 다른 개발자들이 작성한 블로그 글이나 테크 회사가 기고한 글들로 접했지만, 그 동안 내게는 쉽사리 접할 수 없는 분야였다.
21년도에 “오픈소스 컨트리뷰션 아카데미”의 오픈 스택 팀에 참여하던 시기에 AWS에서 서버 장애가 발생해 국내에서 배민이나 여러 서비스 등이 운영하는데 막심한 차질을 빚고 있다는 기사를 봤었다. 서비스 안정성은 정말 중요한 이슈이고, 개발을 업으로 삼는 사람들이 직접 개발은 하지 않더라도 충분히 이해하고 있어야하는 분야라고 본다.
한빛 미디어에서 리뷰 책을 선택할 때, 이 책을 선택할지 말지 한참 고민했지만, 결국 내가 하게 되는 업무가 앞으로 “서비스를 안정적으로 운영하는” 일들을 많이 담당하게 될 것이고, 이제 갓 개발 커리어를 시작하는 주니어 개발자지만 미리 미리 알아두면 앞으로도 많이 업무 진척도를 높일 수 있을 것이라는 기대에 이 책을 선택하게 되었다.
2. 본론 : 일반적인 프로그래밍 상황에서 안정적인 서비스 운영하기
개발을 하는 누구나라면 이해할 수 있는 개념에서 먼저 이 책에서 언급된 내용들을 정리해보고자 한다.
사용자 권한 분리하기
개발할 때, 서버는 물론이고 프론트에서도 이용하는 서비스의 접근 권한을 분리해서 코드를 작업해주는 것이 정말 중요하다. 이러한 이유는 서비스를 이용하는 유저별 접근할 수 있는 기능을 필터링 해주는 것은 물론이고, 자연스럽게 각 권한에 따른 유저별로 관리자 입장에서 보안상의 관리가 용이해지기 때문에, 서비스를 운영하는 시점에는 적절하게 사용자 권한이 분리되어 있어야한다.
지금 일하고 있는 곳도 어떤 서비스인지는 정확하게 얘기할 수 없지만, 권한을 5개로 나눠 운영하고 있고, 권한 별로 할 수 있는 서비스가 플랫폼 내부에서 명확하다 (이 서비스를 개발한 회사 CTO님이 이전에 보안 회사에서 근무한 경력이 길다보니…)
잘 생각해보면 정말 간단한 쇼핑몰을 구축한다고 해도, 관리자 / 판매자 / 소비자 등 3개 권한이 필요한데, 일반적인 서비스 개발에 이러한 권한 분리가 명확하게 머릿 속에 명확하게 잡히지 않으면, 서비스 운영이 어렵지 않을까?
공통 프레임워크, 언어, 라이브러리 구축하기
보편적인 보안 취약점과 신뢰성 이슈는 이런 문제에 회복성을 갖도록 설계된 견고한 프레임워크와 라이브러리를 이용하면 피할 수 있다.
우리가 무의식적으로 코드를 짜서 잘 못느낄 수 있지만, Django에서도 template 코드 작성할 때, {% csrf_token %} 이라는 것을 넣는다. CSRF(Cross Site Request Forgery) 공격에 대한 방어를 위해 보통 form 태그 등에 삽입해서 사용하는 값인데, 프레임워크를 사용하면 이렇게 보안 취약점과 신뢰성 이슈를 이미 어느 정도 구축이 된 채로 개발자는 개발만 할 수 있게 된다.
좀 더 나아가 보자면, Java를 사용하면 스프링이라는 프레임워크를 이용할 수 있고, 지금 근무지에서도 Java로 서버를 구성했다. @log4j2 등을 사용하면 로깅을 기록할 수 있고, 자바로 코드를 구성하면 제일 좋은 점은 파이썬에 비해 보안 관련 모듈이 이미 다 개발되어 있어서, 서비스를 구축하는 사람이 보안 문제를 거의 신경 쓸 필요가 없다는 점이다.
(하지만 난 자바를 좋아하지 않는다… 자바 어렵다)
서비스가 이미 어느 정도 커져서, 기능에 따라 성능 이슈가 하나의 언어로 통제가 어려울 경우에는 불가피하게 프레임워크나 모듈을 하나로 통일하기 어려워지겠지만, 그럼에도 회사 내의 공통적인 부분에 대한 합의가 있어야하고 개발이 되어야할 것이다. 견고한 프레임워크가 보안 취약성을 낮춘다.
(세간에 잘 알려져 있는 프레임워크가 사랑받는데는 이유가 있다)
기술 부채 해소하기
이건 거의 대부분의 기업이 해소 못하고 있는 이슈 중 하나일텐데, 서비스 확장에 따른 기존 코드나 프레임워크의 기술적인 결함을 발견 직후 해결하는 것이 아니라, 당장 서비스 운영에는 큰 문제가 없어보이니 눈 감고 지나가는 경우 등을 얘기할 수 있을 것 같다.
당장 이 문제도 내가 직접 겪을 수 있는 것도 아니고, 서비스가 일정 수준 이상 커지면 기업에서 스스로 문제점을 느끼고 기술 부채 해소를 위해 새로운 언어와 프레임워크, 그리고 모듈을 도입하는 것이기 때문에 (일례로 당근마켓 & 마이리얼트립은 초기 서비스 런칭 시에 루비로 빌드했고, 지금은 Node.js와 Go를 서비스 확장에 따라 도입했다고 알고 있다) 코드 상태에 대해 지속적으로 기여하는 팀 문화를 만들어야 덮어놓고 악취가 나던 문제들을 꾸준히 관리할 수 있게 되지 않을까 싶다.
강력한 타입 검사하기
엄밀히 말하자면 타입 검사는 보안 보다는 신뢰성 이슈를 재고하는데 많이 언급되지 않을까 싶다. 자바스크립트와 파이썬은 안타깝지만 이런 강력한 타입 검사를 제공하고 있지 않고, 서비스를 사용할 때 종종 문제가 발생하기 때문에 (숫자와 문자의 덧셈 연산 결과 값이 두 값을 일렬로 연결한 문자열로 반환하는 등…) 타입스크립트와 타입 힌팅(Type Hinting, 파이썬에서 타입 검사를 위해 사용하는 명칭들) 등을 꼭 사용해주는 것이 좋다.
국내에서 개발자 채용할 때, 파이썬 개발자보다 자바 개발자를 더 많이 찾는 이유는 자바가 오랜 시간 사용되면서 서비스 운영 과정에 발견할 수 있었던 여러가지 버그나 문제점 등을 찾아 개선해 나갔고, 그 덕분에 서비스 운영 과정에서 필요한 많은 기능들이 모듈화 되어 있다. 게다가 자바는 정적 타이핑이 의무로 적용되어 있기 때문에 타입 지정을 하지 않았을 때 발생하는 신뢰성 문제가 개발자의 실수가 아니면 거의 발생하지 않는다.
테스트 코드 추가하기
오픈스택 컨트리뷰션할 때, 테스트 코드 작업할 일이 종종 있었는데, 엔터프라이즈급 서비스가 되면 테스트 코드는 상용 서비스 운영 관점에서 필수다.
하지만 테스트 코드도 일단 기능 구현하고 짜는 것이 아니다. 순서가 테스트 코드가 필요한 기능을 먼저 명세서를 작성하고, 그것에 따른 테스트 코드 로직 구현, 그리고 기능 구현 순이다.
테스트 코드는 서비스를 배포하기 전에 작업한 로직에서 발생할 수 있는 문제점들을 미리 찾을 수 있고, 버그나 보안 문제 등에 대한 이슈도 해결해준다.
단순하게 OpenStack 기능 구현 및 테스트 코드 작성 이후에 커밋하게 되면, Zuul이라는 CI가 30분 정도 실행되면서 보안이나 테스트 및 안정성 등을 검사하게 된다.
그리고 maintainer들이 커밋한 코드를 읽어보고 merge를 수행한다.
보안과 신뢰성 이슈는 모두 결국 하나의 공통된 목표를 갖고 있다. 바로 안정적인 서비스 운영이다.
틈틈이 테스트 코드 한 번 짜보는 것을 연습하면서, 하다 못해 간단한 To-Do 앱을 빌드하고 거기에 테스트 코드 추가해보는 작업도 나름대로 도움이 되지 않을까 생각해본다.
결론 : 서비스는 결국 사람이 만든다.
서비스 개발, 시스템 유지 보수, 서비스 보안 및 신뢰성 관리, 그리고 서비스를 관리하는 조직과 문화는 모두 사람이 만든다.
서비스를 만들고 나서 끝! 으로 기업이 운영되면 분명 그 기업이 운영하는 서비스는 언젠가 큰 위기를 맞고 기업의 위기로 봉착하게 될 것이다.
서비스를 어떻게 운영할 것이고, 그 운영을 위해 조직 구성원은 특정 상황에 어떤 행동을 해야하는지 평소에 훈련이 되어 있지 않으면, 구글이 그랬던 것처럼 서버 장애가 터졌을 때, 원인에 대해 빠른 대처를 하지 못할 가능성은 언제나 존재할 것이다. (21년 AWS 서버 장애도 마찬가지다. 당장 국내 개발자들이 손 쓸 수 없는 문제 상황을 고객들이 보고만 있는 상황이 만들어진다)
따라서 이제 커리어를 시작하는 개발자로서, 단순히 작성하는 코드에만 관심 갖는 것이 아니라, 서비스를 운영하는 조직 문화에도 충분히 신경쓸 필요가 있고, 비즈니스 트렌드에 따라 발생할 수 있는 운영 문제점 등도 꾸준히 팔로우업을 해줄 필요가 있다.
한빛 미디어 도서 리뷰는 이번이 처음인데, 꾸준히 퇴근하고 와서 읽으면서 스스로 학습할 수 있는 시간을 만들 수 있어 좋다. 결국 누구에게나 하루는 동일하게 주어지지만, 스스로 시간 내는 것은 본인의 의지에 따라 만들어진다.