Container는 응용 프로그램과 프로그램을 실행하는데 필요한 모든 것을 단일 단위로 포장함으로써 Process를 표준화하는 Deplyoment 방식을 의미한다.
기존 VM이나 Physical Server에서 Application을 배포시킬 때는 오로지 Application을 패키징하고 배포시켜야 했기 때문에 Local 컴퓨터와의 환경이 달라 동일한 동작 방식이 보장되지 않는다는 단점이 존재하였는데 Container는 프로그램 실행에 필요한 모든 것을 포함하여 포장하기 때문에 Local 컴퓨터와 동일하게 동작하는 것을 어느 정도 보장할 수 있게 된 것이다.
위 사진에서 볼 수 있듯 Conatiner는 VM과 유사한 형태를 가졌으나 Guest OS가 없다는 특징을 가지고 있다.
따라서 Conainer는 OS를 따로 설치하지 않아도 됐고 Guest OS에 의존적이였던 Application의 실행이라는 단점을 지웠으며 OS가 없는 만큼 가벼운 배포가 가능해졌다.
단지 VM은 Guest OS를 설치할 수 있었지만 Container에서는 Host OS의 제약을 받기 때문에 개발을 진행할 때 어떤 OS를 활용하여 Conatiner를 실행시킬지는 미리 정해놓아야 한다.
위 사진에서 Conatiner Runtime이라는 부분이 존재하는데, 이제 이 부분에 Docker Engine 등이 들어가서 Docker Container를 실행시킬 수 있게 만들어주는 것이다.
이 부분은 훗날 Docker와 Kubernetes를 공부할 때 자세히 다루도록 하자.
Container도 VM과 마찬가지로 Container끼리는 간섭을 일으킬 수 없는 장벽이 존재하여 마치 분리된 공간에서 실행되는 것처럼 수행된다.
단지 VM은 OS까지 분리된 "완벽히 분리된 환경"에서 Application이 실행되는 개념이라면 Conainer는 분리된 환경에서 실행되는 것처럼 보이지만 사실 Host OS는 공유하며 실행된다는 차이점이 존재한다.
그래서 만약 Conainer에서 Host OS까지 영향을 끼칠 수 있는 문제가 발생할 경우 다른 Conainer에도 문제가 확산되는 문제점이 존재한다.
개인적으로는 매우 높은 Portable이 Container의 유명세에 큰 이유가 되었다고 생각한다.
Conainer는 Application과 실행되는 환경까지 포함하여 Packing되고 배포되기 때문에 서비스를 확장시킬 때마다 설정에 대한 스트레스를 받을 필요 없이 Conainer만 전달하면 된다.
이로 인해 Local에서는 되는데 Server에서 안되는, 개발자로서 가장 답답한 문제가 해결되는 것이다.
추가적으로 Container는 Load Balancing을 자동으로 수행해주기 때문에 VM보다 필요한 Server 컴퓨터의 수가 적으며 Version 관리를 수행할 때 서비스를 중단하고 재배포시키지 않아도 되는 장점 또한 Container의 인기가 높아지는데 큰 역할을 했다.
그리고 Cloud 환경 또한 Container의 인기에 한 몫 했다.
Container를 실행시키기 위해서는 원래라면 여전히 물리적 Infra, Physical Server나 VM이 필요했다.
하지만 Cloud를 통해 물리적 환경의 구축이 필요 없어지면서 개발자 입장에서는 오로지 Service만 배포하면 되었고 운영에 대해 신경 쓰기보다는 Application이 정상적으로 작동하는 것이 더욱 중요해졌다.
운영팀에서 직접 관리할 수 있는 부분이 제한된 Cloud Server 활용에 있어 모든 환경에서 정상적으로 작동하는 것이 보장된 Container는 매우 매력적인 기술이었다.
동시에 Container 기술을 활용하면 MSA를 활용하기가 더욱 수월해졌기 때문에 MSA와 Cloud 기술을 동시에 활용하는 데에 있어 핵심 기술로 떠오르게 된 것이다.
앞서 말했듯 Container는 VM과 달리 Guest OS가 존재하지 않는다.
OS라는 것이 크기가 매우 크기 때문에 Guest OS가 없는 Container는 VM보다 매우 가볍다는 장점을 가지게 된다.
Container가 가볍다는 것은 배포가 빠르며 복제 및 공유가 빠르다는 장점을 가지게 된다.
또한 Container Image를 생성하는 데에 있어서도 OS까지 포함하여 만들 필요가 없으므로 생성이 쉽다는 장점을 가지고 온다.
결국 Container가 가벼워 Packaging 및 Deployment가 빠르다는 장점은 신속히 변화하는 시장에 적응해야 하는 최근 개발 Trend에 적절한 기술이라고 말할 수 있다.
위에서 이미 말했듯 Container는 Application 뿐만이 아닌 Application이 실행되기 위한 환경까지 포함해서 Container Image를 만들게 된다.
따라서 개발 환경에서 제대로 작동하였다면 운영 환경에서도 동일하게 작동되는 것이 보장되어 있으므로 개발과 운영 단계에서 차이가 발생하는 것에 대한 우려를 줄일 수 있다
Container는 Application이 실행되는데 필요한 만큼의 자원을 할당받을 수 있다.
이는 MSA에 최적화되어 있다고 볼 수 있는데, MSA에서 쪼개진 Component를 개발하고 이를 Container Image로 만들어 배포할 경우 Component에 대해 최소한의 자원을 통하여 서비스를 제공할 수 있게 된다.
따라서 DevOps가 요구되는 MSA 입장에서 운영과 개발 사이의 차이에 대해 크게 우려하지 않아도 되며 자원의 낭비를 최대한 줄여주는 Container는 환상의 짝꿍이라고 할 수 있을 것이다.
이처럼 Container는 MSA에 최적화되어 있는데, 이 점은 메모리 관리가 효율적으로 된다는 장점 또한 가지고 오게 된다.
VM이나 Physical Server 같은 경우 Server를 확장시킬 때 Application 1개 전체를 배포함으로써 서버를 확장시켰다.
만약 A, B, C 기능이 존재하는데 B 기능에만 Traffic이 몰린다고 하더라도 서버를 확장시키기 위해서는 A, B, C 모든 기능이 확장되게 되며 이는 A와 C 입장에서 메모리 낭비로 이어졌다.
하지만 Container는 A, B, C 기능이 모두 Microservice로 쪼개져있기 때문에 필요한 기능만 배포함으로써 Scale-out이 가능하다.
따라서 확장이 필요한 기능의 Container Image를 Server에 배포함으로써 쉽게 기능별 Server 확장이 가능하기 때문에 메모리 관리를 효율적으로 진행할 수 있다.
Contianer는 VM보다 Container 1개를 보호하는데 더 많은 보안적 관심을 가져야 한다.
VM은 머신 별로 Guest OS가 따로 존재하기 때문에 1개의 VM이 보안적으로 뚫렸더라도 Host OS 및 다른 VM까지 뚫릴 확률은 매우 낮다.
하지만 Container는 1개의 Host OS를 활용하여 여러 개의 Container가 구동되는 방식이다.
즉, Container가 보안적으로 뚫리게 되면 Host OS도 보안적으로 위험해지며, Host OS가 위험해질 경우 Host OS와 연결된 모든 Container가 보안적으로 위험해진다.
즉, Container 1개의 보안 취약점이 Server에 존재하는 모든 Container의 보안 취약점이 되는 것이다.
따라서 Container 기술을 활용하기 위해서는 모든 Container에 대해 더욱 신중하게 보안적 관심을 가져야 하는 것이다.
사실 이 부분이 큰 단점이라고 생각하지는 않는다.
결국 개발자들은 신기술이 나올 때마다 익혀야 하는 숙명을 가지고 있고 이는 Container에서도 큰 차이는 없기 때문이다.
IT Infra에서 Container를 다루기 위해서는 Docker와 Kubernetes라는 새로운 기술을 익혀야 한다.
원래라면 Application에 대한 기술은 개발팀만 알면 됐지만 Container를 활용하기 위해선 개발팀이 만든 Container Image를 실제 서버에 실행시킬 수 있는 방법에 대해 알아야 한다.
따라서 Container Image 활용법을 알아야 하며, 이를 위해 Docker와 Kubernetes 같은 기술을 익혀야 한다. 이는 운영팀과 개발팀의 경계선을 모호하게 한다.(물론 최근 DevOps라는 개발 방법론이 나온 시점에서 큰 단점은 아니라고 생각한다)
Virtual Server에서는 VM별로 Guest OS가 존재하기 때문에 Application 별로 다양한 OS를 활용할 수 있었다.
하지만 Container는 Container끼리 격리되어 있는 것은 맞지만 모든 Container는 결국 Host OS라는 동일한 OS를 활용하게 된다.
따라서 Container가 어떤 OS에서 구동되는지 정확히 명시되어야 하며 다른 OS에서 동작해야 하는 Container들을 1개의 Server에서 관리하기는 어려워진다.