지난번 IT 인프라를 공부한 이후, 현재 IT 서비스에서 중요하게 떠오르고 있는 개념인(떠오른지 한참 된)
DevOps와 이러한 용어 및 개념이 등장한 배경에 대해서 정리하고 알아보는 시간을 가졌다.
DevOps란 개념을 설명하기에 앞서, DevOps가 등장하게된 근본적인 이유 혹은 DevOps를 설명하기 위해 빼놓을 수 없는 기술들부터 나열하며 포스팅을 진행할 계획이다.
MSA(Micro Service Architecture) with Monolithic
모놀리식 아키텍처(Monolithic Architecture)를 하나의 목적을 갖는 서비스 또는 애플리케이션에 여러가지 기능이 통합되어있는 기존의 소프트웨어 아키텍쳐를 의미한다.
즉, 소프트웨어가 하나의 결합된 코드로 구성되어있는 구조를 의미한다.
모놀리식 아키텍처가 갖는 장점과 단점은 분명했다. 소프트웨어 초기 단계에서 설계하기 용이하며, 개발이 단순하고 코드 관리가 간편하다는 이점이 존재한다.
다만, 모든 기능이 하나로 합쳐져있는 소프트웨어에 기능 하나를 추가하게 된다면 어떤 일이 발생할까? 또는 리팩토링 등의 유지보수 작업을 수행하려한다면 무슨 일이 발생할까?
결과는 뻔하다. 기능을 추가하면서 기존에 존재하는 기능에서 에러가 발생할 수 있고, 이러한 오류를 해결하는데 들어가는 노력과 시간은 훨씬 스트레스를 받는 작업이다.
즉, 모놀리식 아키텍쳐에서는 어떤 서비스에서 이루어진 수정이 연관된 다른 서비스에 영향을 미칠 가능성이 굉장히 커진다는 단점이 존재한다.
어떤 소프트웨어든 사용자 요구 혹은 유지보수 작업을 통해 기능들이 추가될수록 규모와 복잡도가 상승할 수 밖에 없는데, 초반 단계에선 단순했던 전체 소프트웨어 구조가 시간이 지나면서 매우 복잡해질 수 있는 구조이다.
추가적으로, 모놀리식 아키텍처에서 특정 기능의 트래픽이 폭발하여 서버를 증설할 수 밖에 없는 상황일 때, 해당 기능을 위한 인프라 확장은 좋지만 다른 서비스가 포함된 애플리케이션까지 확장하는 것은 비효율을 가져올 수 있다.
단일 구조를 갖는 모놀리식 아키텍처는 어떤 서비스를 수정하고자 할 때 이를 제외한 전체 서비스를 멈춰야 한다는 문제 또한 존재하며, 만약 특정 기능에 문제가 발생했을 때 이 부분이 전체 시스템에 영향을 주는 구조라는 점도 분명한 단점이다.
이러한 단점을 보완하기 위해 등장한 소프트웨어 구조가 마이크로 서비스 아키텍쳐(Micro Service Architecture)이다.
이는 하나의 큰 서비스를 위해 작은 서비스(기능)들을 느슨하게 결합하는 구조를 의미한다.
즉, 시스템이 하나의 목적을 지향한다는 점은 모놀리식과 동일하지만, 각각의 서비스들을 독립적으로 개발하고 이들을 연결하여 전체 시스템을 구성하는 점에서 차이점을 갖는다.
앞서 느슨하게 결합한다라는 것은 각각의 서비스별로 API(Application Programming Interface)를 바탕으로 네트워크 기반의 연결이라는 의이다.
각각의 서비스들을 연결하는 구조를 갖기 때문에, 서비스들을 독립적으로 개발하는 것과 동작하는 것이 가능해지는 구조이다.
이러한 구조는 개발된 서비스를 재사용하기 쉽다는 이점과, 향후 서비스의 추가나 확장을 수행할 때 다른 서비스에 영향을 미칠 가능성이 줄어들어 사용량의 변화에 따라 특정 서비스만 확장하는 것이 가능하다는 이점을 갖는다.
따라서 사용자의 요구 사항에 따라 가용성을 확보하고 확장해야하는 Cloud 인프라 환경에 적합하다.
하지만, 마이크로 서비스 아키텍처는 모놀리식 아키텍처보다 기본적인 복잡도가 높고 초반 단계에서 설계하고 구현하기가 어렵다는 단점이 존재한다.
또한, 각 서비스가 서로 통신하는 구조로 설계되기 때문에 네트워크를 통한 호출 횟수가 증가해 성능에 나쁜 영향을 미칠 수 있다.
마이크로 서비스 아키텍쳐의 구조 덕분에 트래픽이 증가하는 기능에 대한 확장과 수정이 유연해지고, 특정 서비스가 동작하지 않더라도 전체 서비스의 동작에는 영향을 미치지 않을 수 있는 소프트웨어를 개발할 수 있다!
하지만, 마이크로 서비스 아키텍처를 적용하는 것은 복잡하고 오히려 개발 능률을 떨어뜨린다는 얘기가 종종 들린다.
분명히 소프트웨어 시스템을 개발하는 단계에서 어떤 구조를 선택할지에 대한 고민은 분명하다.
미래를 생각해 마이크로 서비스 아키텍쳐를 선택하자니 복잡하고 속도도 느리고, 모놀리식을 선택하자니 별로 좋은 구조가 아닌 것 같고... 일상적으로 하는 고민처럼
이러한 문제에 대해 마틴 파울러의 블로그 글에 인용해보자,
begin with a monolith, keep it modular, and split it into microservices once the monolith becomes a problem.
- Martin flower -
위의 의미에 첨언하면, "모놀리식으로 시작하여, 모듈식으로 서비스를 분리하여 유지하고, 만약 모놀리식의 구조가 문제가 된다면 그때 마이크로 서비스로 분리해가라"고 해석할 수 있다.
즉, 초반 단계에선 모놀리식 아키텍쳐를 선택하여 빠르게 서비스를 완성해나가고, 만약 서비스가 커져 기능 확장 등에 문제가 발생하기 시작한다면 그때서야 마이크로 서비스 아키텍처로 변경하는 것이 한 가지의 조언이 될 수 있다고 볼 수 있다.
아무튼 모놀리식 아키텍처와 마이크로 서비스 아키텍처의 장단점은 분명하지만,
모놀리식의 분명한 단점을 보완하기 위한 구조를 갖는 마이크로 서비스 아키텍처는 후술할 컨테이너, DevOps와도 연관성이 높은 구조라 생각하여 이에 대한 배경을 살펴보았다.
컨테이너(Container)
우리가 일상적으로 사용하는 컨테이너의 의미는 무엇일까?
흔히, 거대한 선박에 쌓여있는 네모난 박스들을 떠올릴 수 있는데, 본인은 위의 네모난 컨테이너를 이렇게 정의해보고자 한다.
화물에 실린 컨테이너는 "배송"이라는 공통된 목적을 갖고 있고, 어떤 선박에서든지 배송을 수행하기 위해 포장한 객체라고 볼 수 있다. "배송"이라는 행위를 기준으로 삼았을 때 컨테이너 내부에 어떤 내용물이 들어있는지는 중요하지 않다.
IT에서의 컨테이너 또한 비슷한 의미로 받아들일 수 있다고 생각하고, 본인은 아래와 같이 IT분야에서의 컨테이너를 정의를 해보았다.
"실행"이라는 공통된 목적을 갖고, 서비스 혹은 애플리케이션의 실행에 필요한 애플리케이션 코드 및 의존성 라이브러리 등의 모든 요소를 포함하여 관리하는 패키지
서비스 혹은 애플리케이션을 실행하기 위해 필요한 소스 코드와 라이브러리 등을 모두 포함하여 관리하고, 컨테이너를 통해 다양한 환경에서 실행 되는 구조는 다양한 이점이 존재한다.
- 개발자가 실행 환경에 미치는 영향을 고려하지 않고 빠르게 서비스 구현이 가능하다.
- 컨테이너는 일반적으로 경량화되어 관리되므로 실행 시에 효율적이고 일관성을 갖는다.
- 컨테이너는 이를 사용할 수 있는 환경에서 모두 동작하므로 폭 넓은 환경에서 구동이 가능하다.
- 서비스의 컨테이너화를 통해 책임을 분리할 수 있다. 개발자는 애플리케이션의 로직과 의존성 라이브러리들을 관리하여 컨테이너를 생성하고, 운영자는 컨테이너 세부사항을 고려하는 대신 배포와 관리에 집중할 수 있다.
이러한 장점을 살펴보았을 때, 앞서 말한 마이크로 서비스 아키텍쳐에서 컨테이너를 사용하기에 적절하다고 말할 수 있다.
만약, 마이크로 서비스 아키텍쳐에서 소개한 독립된 서비스를 컨테이너로 실행시키고 배포한다면, 컨테이너가 갖는 장점과 마이크로 서비스 아키텍처가 갖는 장점을 극대화할 수 있기 때문이다! 시너지!!
하나의 단위인 모놀리식 아키텍쳐에서 컨테이너를 통하여 실행 및 배포를 수행한다면 컨테이너가 갖는 장점은 가져갈 수 있겠지만, 컨테이너에서 관리해야하는 요소들이 많아지고, 기존에 모놀리식 아키텍쳐의 단점은 변하지 않음을 알 수 있다,
물론, 쿠버네티스와 같은 컨테이너 오케스트레이션 도구를 사용하여 서비스의 가용성을 확보하는 방법은 존재하지만, 이는 컨테이너 자체로 이를 보완할 수 없다.
결국 컨테이너의 등장으로 애플리케이션을 실행하는데 필요한 소스 코드와 필요한 패키지 및 라이브러리들을 결합하여 관리할 수 있게 되므로, 컨테이너를 실행할 수 있는 환경만 갖춰진다면 어떤 실행환경에서도 애플리케이션을 동작시킬 수 있어, 서비스를 빠르게 개발하고 배포하는 것이 가능해졌다.
컨테이너를 다루는 대표적인 도구는 아래와 같다. 도구에 대해서는 설명하지 않는다.
- 도커(Docker)
- 크라이(Cri-O)
컨테이너 오케스트레이션(Container Orchestration)
컨테이너 오케스트레이션은 쉽게 컨테이너 라이프사이클을 자동화하여 관리한다고 표현할 수 있다.
이 의미는 컨테이너들의 배포, 관리, 확장 및 네트워킹을 자동화한다는 의미를 포함한다.
실제 서비스 환경에서는 수많은 호스트(기기)를 운영하게 되는데, 이러한 기기들에게 서비스를 컨테이너 기반으로 자동화된 관리 방법을 제공하는 기술이다.
컨테이너 오케스트레이션에서 수행하는 작업을 자세히 살펴보면 아래와 같다.
- 프로비저닝 및 배포
- 구성 및 일정 조정
- 리소스 할당
- 컨테이너 가용성
- 인프라 전반의 워크로드 밸런싱을 기반으로 컨테이너 스케일링 또는 제거
- 로드 밸런싱 및 트래픽 라우팅
- 컨테이너 상태 모니터링
- 실행될 컨테이너를 기반으로 애플리케이션 설정
- 컨테이너 간 상호 작용의 보안 유지
즉, 컨테이너의 등장으로 개발자가 실행 환경과 관련된 노력을 기울이지 않아 개발 속도가 이전보다 빨라지게 되었고, 이러한 컨테이너를 자동화하여 배포하고 관리하고 확장하는 컨테이너 오케스트레이션을 통해 배포하는 과정 또한 이전보다 빨라지게 된 것이다. 엄청난 시너지!!
컨테이너 오케스트레이션은 컨테이너를 사용하는 어떤 환경에서든 사용이 가능하기 때문에, 컨테이너가 갖는 이점을 그대로 이용할 수 있다!
컨테이너 오케스트레이션이 갖는 장점을 아래와 같이 정리해볼 수 있다.
- 컨테이너의 라이프사이클을 관리하고 상태를 추적하고 보존하는 등의 기능을 통해 컨테이너를 안정적으로 사용할 수 있게 한다.
- 컨테이너의 생성, 실행, 종료, 외부로의 노출 등을 수행하는 것을 자동화할 기반을 제공한다.
- 자동화된 기능을 바탕으로 컨테이너의 고가용성 확보가 가능하고 트래픽 증가에 따른 확장 등이 가능하다.
궁극적으로 컨테이너 오케스트레이션 기술을 통해 얻을 수 있는 장점은 "컨테이너를 배포하는 것이 편리해졌다!" 라는 점이다.
컨테이너 오케스트레이션의 대표적인 도구는 아래와 같다.
- 쿠버네티스(Kubernetes)
- 도커 스웜(docker swarm)
DevOps
DevOps의 정의를 살펴보면 특정한 기능이나 도구가 아니라 "문화"라는 표현을 사용한다. "어떤 문화이길래 IT 기업의 표준적인 위치를 갖고 이러한 인지도를 갖고 있는 것일까?" 에 대한 질문을 해소할 수 있는 계기가 되었다.
DevOps는 Developement 와 Operation에서 비롯된 일종의 개발 문화 & 양식이다.
즉, 개발과 운영을 결합하는 구조를 갖는 문화인 것인데, 기존에 애플리케이션을 개발하고 운영할 때 분리되어 구조를 변화시키자는 의미이다.
일반적인 조직에서 서비스를 기획하고 개발 하는 부서와 이를 운영하고 고객에게 전달하는 서비스 부서는 분리되어 있기 마련이다.
이러한 구조적인 간극은 어떤 측면에선 불필요한 절차를 야기할 수도 있고, 궁극적으로 고객에게 서비스가 제공되는 시간이 길어질 수 있다는 점은 부정할 수 없다.
아무리 빠르게 개발해도 배포되고 운영되는 데 의사소통 과정이 길고 시간이 오래걸리면 무슨 소용이 있겠는가!
DevOps가 추구하는 궁극적인 목표는 "빠르게 고품질의 서비스를 제공하여 비즈니스 가치를 창출하는 것"이다.
DevOps는 이러한 역량을 갖추기 위해 필요한 기술적인 도구와 조직의 문화를 포괄하는 아이디어와 방식이다.
DevOps 문화를 구축하기 위해서 아래와 같은 요인들을 포함시킬 수 있다.
- 개발 팀과 운영 팀간의 협업을 중요시하는 문화
- 개발에서 배포까지 이르는 프로세스의 자동화 - CI/CD
- 마이크로 서비스 아키텍쳐 - 작은 단위의 서비스
- 컨테이너 - 실행 환경과 독립된 구동
- 코드형 인프라(IaaC) - 프로비저닝 작업의 일관성 및 자동화
이보다 많은 요인들이 DevOps 문화를 만드는 데 필요할 것이지만, 이를 크게 나누면 "문화"와 "도구"로 나눌 수 있다는 점은 분명하다. 이러한 요인들을 바탕으로 DevOps 문화를 만들어갈 수 있을 것이다.
CI/CD
DevOps를 뒷받침하는 도구로써 CI/CD를 꼽을 수 있다.
CI/CD는 지속적 통합(Continuous Intergration)과 지속적 배포(Continuous Deployment)를 결합한 단어이다.
이는 소프트웨어를 지속적으로 통합하고 배포하는 프로세스라는 의미를 갖는다.
CI/CD 파이프라인을 구축하는 것은 DevOps를 이루기 위해 필수적인데, 개발부터 배포까지의 과정을 자동화하여 소요되는 노력과 시간을 줄임으로써 개발자와 운영팀간의 협업을 지원할 수 있기 때문이다.
이러한 CI/CD 파이프라인을 구축하는 도구에는 Jenkins가 존재하는데,
CI/CD 파이프라인을 구축하기 위한 근본적인 명령어나 설정들은 앞서 설명한 컨테이너와 컨테이너 오케스트레이션 도구를 통하여 일반적으로 이루어진다.
지속적 통합은 컨테이너 도구와 SCM(소스 코드 관리 도구 - github)들을 통하여 애플리케이션의 변동 사항을 병합하고 이를 바탕으로 애플리케이션 이미지를 빌드하여 전체 서비스에 통합시키는 과정을 수행하고,
지속적 배포는 컨테이너 오케스트레이션 도구들을 통하여 컨테이너화된 서비스를 실시간으로 배포하는 과정을 수행한다.
이러한 CI/CD 파이프라인을 통하여 서비스가 변동될 때 발생할 수 있는 개발 및 운영팀에 대한 문제를 해결하기 위한 방법으로 사용할 수 있고, 나아가 DevOps 문화를 만들 수 있다.
결론
DevOps란 문화를 정의하기 위하여 수많은 기술 및 개념들을 살펴보았다.
하나하나의 기술로도 하나의 포스팅을 할 수 있을 만큼의 분야이지만, 이를 상세히 다루는 것은 추후에 기회가 된다면 수행해보도록 한다.
서비스 및 기능이 복잡해지고 구조가 복잡해지면서 떠오르게된 마이크로 서비스 아키텍쳐.
이를 통해 소규모 서비스 단위의 개발을 진행하게 되었다.
다양한 실행 환경에서 개발자의 고려를 제외하기 위해 떠오른 컨테이너.
이를 통해 개발자는 서비스 개발에 구동 환경에 대한 고려를 분리할 수 있게 되었다.
컨테이너들의 라이프사이클을 관리하는 기능을 수행하는 컨테이너 오케스트레이션.
이를 통해 배포 과정이 자동화되고 배포 프로세스에 필요한 지식과 노력이 적어질 수 있게 되었다.
애플리케이션의 통합과 배포 과정을 빠르고 자동화해주는 CI/CD.
이를 통해 애플리케이션 개발에서 배포까지의 과정을 자동화해 다양한 노력들이 줄어들게 되었다.
이러한 모든 것들은, 궁극적으로 "빠르게 소비자에게 서비스를 제공하자"라는 애자일(Agile) 개발 방법론의 지향점과 맞물려 DevOps라는 하나의 문화를 구축하게 된 기반이 되었다고 생각한다.
'Infra > Cloud' 카테고리의 다른 글
ALB Route53 및 인증서 등록 - HTTPS 구성 (2) | 2023.10.29 |
---|---|
K8s Ingress와 AWS LB Controller 사용하여 EKS ALB 구성 및 노출 (2) | 2023.10.29 |
멀티 AZ(가용 영역)이란? (0) | 2023.06.10 |
IT 인프라란? - 온프레미스부터 Cloud까지 (2) | 2023.04.18 |