요즘에 뜨고 있는 것은 아니고
요즘 그냥 핫해서 배우지 아니 아니 아니 아니할 수 없어서 알아봤다.
*2023.08.06 업데이트
컨테이너란 무엇인가?
- 우리가 겪는 어려움
우리가 쓰는 많은 프로그램들은 환경 의존적이라고 말할 수 있다.
기본적인 프로그램조차 종속성이 많고 엄청난 수의 패키지, 라이브러리 기타 소프트웨어의 구성에 부합해야 실행할 수 있다.
심지어 동일한 운영체제에서조차 어플리케이션을 실행할 때 문제가 발생하기도 한다.
다시 말해서 프로그램을 쓰는 환경 (ex. OS, 프레임워크 등)이 달라지거나 버전만 달라져도 해당 어플리케이션 프로그램이 정상 작동할 것이라는 보장이 없다.
또한 관련된 구성을 유지하는 것과 같은 관리가 어렵다.
- 가상 머신의 등장
지난 수년 동안 종속성 문제를 해결하기 위해 적용한 방법 중 하나는
각 어플리케이션을 각각 가상 머신에 배치하는 것이다.
가상 머신을 이용하면 동일한 물리적 하드웨어에서 여러 어플리케이션을 실행시키고 소프트웨어 구성 요소 간 충돌이나 하드웨어 리소스 경합을 최소한으로 유지할 수 있게 된다.
다시 말하면 가상 머신(VM)으로 나의 환경을 여러가지로 나누고 그 환경에 맞게 내 하드웨어 리소스를 할당시키고 각각 환경에 독립성을 주어 어플리케이션의 종속성을 해결하고자 하였다.
충분히 VM은 종속성 문제를 해결할 수 있었다.
하지만 사람들은 이에 만족하지 못했다.
개발보다 유지 보수가 중요해져 소프트웨어 공학이 중요해진 지금
소프트웨어의 스택을 최신 상태로 유지하고 비즈니스 니즈에 맞춰 계속 변경할 때 유지 관리와 같은 일들을 VM 환경으로는 하기가 힘들었다.
또한 가상 머신은 일반적으로 크기가 크다.
기가 바이트급 이상이며 이식성, 소프트웨어 업데이트, CI/CD (Continuous Integration / Continuous Delivery) 같은 문제도 해결하지 못했다.
컨테이너는 이러한 불편함을 해소해준다.
컨테이너는 개별 소프트웨어에 실행에 필요한 “환경”들을 “독립”적으로 운용할 수 있는 기반 환경을 제공해주고 다른 실행 환경과는 간섭을 막아 운영체제 수준의 isolated environment를 제공한다.
다시 말해서 컨테이너는 어플리케이션을 실제 구동 환경(Host)으로부터 추상화할 수 있는 논리적 패키징 매커니즘을 제공한다.
VM에서 Hyper-V를 통해 Guest OS 환경 위에 어플리케이션이 구동되는 것이 아니라 하드웨어 에뮬레이트도 필요 없고 Guest OS를 구성하기 위한 자원(CPU, I/O) 또한 필요 없다.
바로 Host OS의 위에서 리눅스 커널과 하드웨어 리소스를 공유하면서 구동하기 때문에 일반적인 프로세스 이용과 차이가 없다.
또한 일반적으로 VM보다 리소스를 적게 사용하고도 사용할 수 있고 동일한 하드웨어에서 훨씬 더 밀도 높게 패키징 할 수 있고 비용이 절감된다.
ð 경량화
또한 모든 컨테이너는 호스트 환경 위에서 돌아가면서도 독자적인 실행 환경을 가지고 있다.
이러한 환경을 파일로 구성하여 가지고 있으며 이를 이미지 형식으로 쉽게 공유하거나 다른 시스템 환경에서도 손쉽게 사용이 가능하다.
ð 이식성
컨테이너는 독자적인 실행환경을 가지고 있기 때문에 다른 컨테이너와의 영향도 없어 안전하다.
ð 격리성
HyperVisor란?
컴퓨터가 가지고 있는 인프라 리소스들에 대해 VM별로 배분 하는 역할들을 한다.
또한 각 VM에서는 독립적인 Guest OS를 가지고 있다.
따라서 독립적인 플랫폼을 하나씩 증가시킬 때마다 불필요한 OS를 만드는 작업에 대해서 계속해서 해야한다.
즉, 확장성이 떨어진다. 메모리나 자원에 관해서 유동적으로 관리 되는게 아니라 처음부터 정해놓고 실행하기에 비효율적이다.
이미지란?
Docker 이미지는 컨테이너를 정의하는 read-only 템플릿이다.
이미지에는 코드에 필요한 라이브러리 및 종속성에 대한 정의를 비롯해 실행되는 코드가 포함되어 있다.
Docker 컨테이너는 인스턴스화된(실행되는) Docker 이미지다.
이미지로 컨테이너를 구동하는 것의 특징은
• 도커 이미지는 컨테이너 실행에 필요한 파일과 라이브러리 및 종속성에 관련된 설정 값 을 포함하고 있다.
• 컨테이너에 따라 수정되거나 변경되지 않는다. 덕분에 라이브러리의 버전이 의도치 않게 바뀜에 따른 의존성 문제가 발생하지 않는다.
• 컨테이너는 이미지를 실행한 상태이며, 변하는 값은 컨테이너에 저장된다. (이미지 자체는 변경될 수 없다).
• 같은 이미지에서 여러 개의 컨테이너를 생성할 수 있다.
• Docker Hub를 통해 버전 관리 및 배포가 용이하다.
• Docker는 Dockerfile이라는 파일로 이미지를 생성한다.
ubuntu의 이미지는 A+B+C이다. nginx의 경우 A+B+C+Nginx를 하고 싶다. 이때 Layer 기능을 이용하여 ubuntu에 nginx만 쌓으면 된다.
Dockerfile이란?
이미지를 빌드하려면 이미지 를 만들고 실행하는 데 필요한 단계를 정의하는 간단한 구문 으로 Dockerfile 을 만들어야 한다. Dockerfile의 각 명령어는 이미지에 레이어를 만든다. Dockerfile을 변경하고 이미지를 다시 빌드하면 변경된 레이어만 다시 빌드된다.
도커 이미지를 만들기 위해 Dockerfile이라는 파일에 DSL(Domain Specific Language) 언어를 이용해 이미지를 생성할 수 있다. 단순 텍스트 파일로 일반적으로 소스와 함께 관리한다. 서버에서 프로그램을 설치하려고 할 때 Dockerfile 을 통하여 관리하면 된다.
도커란?
Docker는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있는 소프트웨어 플랫폼이다.
소프트웨어를 컨테이너라는 표준화된 단위로 패키징을 할 수 있고 만들어진 컨테이너를 관리할 수 있다. 그리고 컨테이너 환경에서 어플리케이션을 실행할 수 있도록 도와준다.
-도커 컨테이너, '분리'와 '조절' 기능 제공
도커 컨테이너는 앱을 서로, 그리고 기반이 되는 시스템으로부터 계속 분리시킨다. 이런 방식으로 더 깔끔한 소프트웨어 스택을 구현한다. 동시에 더 쉽게 분리된 특정 애플리케이션의 CPU와 GPU, 메모리, I/O, 네트워킹 등 시스템 리소스 사용 방식을 규정할 수 있다. 데이터와 코드를 계속 분리해 유지하는 것도 훨씬 더 쉽다.
-이식성을 제공하는 도커 컨테이너
도커 컨테이너는 컨테이너 런타임 환경을 지원하는 모든 장치에서 실행된다. 애플리케이션을 호스트 운영체제와 연결할 필요가 없다. 따라서 애플리케이션 환경과 기반이 되는 운영 환경을 깔끔하게 최소한으로 유지할 수 있다.
- 결합성(Composability)을 제공하는 도커 컨테이너
대부분의 비즈니스 애플리케이션은 웹 서버, 데이터베이스, 인-메모리 캐시 등 하나의 스택으로 구성되는 여러 별개의 구성 요소로 구성된다. 컨테이너는 이런 조각들을 쉽게 변경할 수 있는 부품으로 구성된 기능 유닛으로 결합한다. 여러 컨테이너가 각 조각들을 제공하며, 독립적으로 유지, 업데이트, 교체, 수정을 할 수 있다.
즉, 애플리케이션 디자인의 마이크로서비스(Microservice) 모델이나 다름 없다. 이 마이크로서비스 모델은 애플리케이션 기능을 별개의 셀프-컨테이너 서비스로 분리, 기존의 느린 개발 프로세스와 유연하지 못한 획일적 앱이라는 문제 해결에 도움을 준다. 가볍고 이동이 가능한 컨테이너를 이용하면, 더 쉽게 마이크로서비스 기반 애플리케이션을 빌드 및 유지 관리를 할 수 있다.
- 오케스트레이션과 스케일링이 쉬운 도커 컨테이너
컨테이너는 가볍고, 오버헤드가 거의 없다. 따라서 특정 시스템에서 더 많이 실행시킬 수 있다. 또한 여러 시스템에서의 애플리케이션 스케일링, 수요 증가와 리소스 보존을 위한 서비스 증가 및 다운에도 컨테이너를 사용할 수 있다.
가장 규모가 큰 엔터프라이즈급 컨테이너 배포 및 관리, 스케일링 도구는 서드파티 프로젝트가 제공하고 있다. 컨테이너 배포 및 스케일링(크기 조정)은 물론 연결과 로드 밸런싱, 관리 자동화 시스템인 구글 쿠버네티스(Kubernetes)가 대표적이다. 쿠버네티스는 멀티-컨테이너 애플리케이션 정의(Helm Charts)를 생성 및 재사용할 수 있는 기능도 제공한다. 이를 통해 On-Demand 방식으로 복잡한 앱 스택을 빌드 및 관리할 수 있다.
도커와 관련된 '주의 사항'
개념에서 비롯된 단점, 이런 개념에서 부산물로 파생된 단점이 존재한다.
- 가상 머신이 아닌 도커 컨테이너
개념적으로 가장 많이 하는 실수는 컨테이너를 가상 머신과 동일하게 여기는 것이다. 컨테이너와 가상 머신은 각기 다른 분리 메카니즘을 사용하기 때문에 장점과 단점 또한 크게 다르다.
가상 머신은 운영체제에서 자신의 인스턴스에서 실행되기 때문에 고수준의 프로세스 분리 기능을 제공한다. 운영체제가 호스트에서 실행되는 것과 동일할 필요도 없다. 윈도우 가상 머신을 리눅스 하이퍼바이저에서 실행할 수 있다. 반대의 경우도 가능하다.
대조적으로 컨테이너는 호스트 운영체제에서 통제된 영역을 사용한다. 많은 애플리케이션이 (철저히 관리되는 방식으로) 동일한 운영체제 커널을 공유한다. 컨테이너로 분리된 앱은 가상 머신처럼 철저히 분리되어 있지 않다. 그러나 대부분의 워크로드에서 충분히 적합한 분리성을 제공한다.
- 도커 컨테이너, '베어-메탈' 속도를 제공하지 않는다
컨테이너에는 가상 머신 정도의 오버헤드가 없다. 그러나 성능에는 영향이 초래된다. '베어-메탈' 속도를 요구하는 워크로드를 운영하는 경우, 컨테이너가 VM보다 낫다. 그러나 일정 수준의 오버헤드를 경험할 것이다.
- 변경이 불가능하고, 비저장성이 특징인 도커 컨테이너
컨테이너는 내용을 설명하는 이미지로부터 부팅 및 실행된다. 이미지는 기본적으로 변경이 불가능하다. 일단 생성되면 바뀌지 않는다.
결과적으로 컨테이너는 '영속성(Persistency)'을 갖고 있지 않다. 컨테이너 인스턴스를 시작하면, 컨테이너가 사라지고 재시작 된다. 새 컨테이너 인스턴스에는 기존 인스턴스와 연결된 상태 정보가 없다.
이는 컨테이너와 가상 머신의 또 다른 차이점이다.
가상 머신은 기본적으로 세션에 대한 영속성을 갖고 있다. 자체 파일 시스템을 갖고 있기 때문이다. 컨테이너의 경우, 유일하게 ‘영속’되는 부분은 컨테이너에서 실행되는 소프트웨어 부팅에 사용한 이미지이다. 이를 바꾸는 유일한 방법은 새로운, 또는 수정한 컨테이너 이미지를 생성하는 것이다.
이에 따른 장점도 있다.
컨테이너의 비저장성은 컨테이너 내용을 더욱 일관되게 만든다. 또 더 쉽게 예측해 애플리케이션 스택으로 결합할 수 있다. 또한 개발자들이 애플리케이션 데이터를 애플리케이션 코드와 분리해 유지하도록 만든다.
컨테이너에 영속성을 부여하고 싶다면, 이런 상태를 다룬 장소에 위치시켜야 한다. 부팅 시 컨테이너와 연결되는 독립적인 데이터 볼륨이나 데이터베이스가 이런 장소가 될 수 있다.
마이크로서비스가 아닌 도커 컨테이너
컨테이너를 사용하면 더 쉽게 마이크로서비스 애플리케이션을 구현할 수 있다.
하지만 특정 애플리케이션을 가져와 컨테이너에 연결하면 자동으로 마이크로서비스가 생성된다는 의미는 아니다.
컨테이너 배포용인지 여부와 상관없이, 마이크로서비스 디자인 패턴에 입각해 마이크로서비스 애플리케이션을 빌드해야 한다. 애플리케이션을 마이크로서비스로 변환하는 프로세스의 일부로 컨테이너화 할 수 있지만, 이는 수 많은 방법 중 하나에 불과하다.
가상 머신은 애플리케이션을 실행되는 시스템에서 분리시킬 수 있도록 만들었다. 도커 컨테이너는 이 개념을 몇 단계 더 발전시켰다. 가상 머신 보다 더 가볍고, 이동성이 높고, 더 빠른 '스핀 업'을 제공한다. 또 가상 머신에서는 불가능한 스케일링, 결합, 관리 기능을 제공한다.
짧게 말하면 Docker는 컨테이너를 위한 OS라고 생각할 수 있다.
도커를 통해 어플리케이션을 실행하면 독립적인 환경에서 실행하는 것과 마찬가지로 일관된 결과를 보장한다.
도커의 핵심은 이미지와 컨테이너다.
일반적으로 서버 상에서 도커를 사용하는데
VM이 서버 하드웨어를 가상화하는 방식과 비슷하게
컨테이너는 서버 운영체제를 가상화시킨다.
도커의 구조를 보자
Docker는 클라이언트-서버 아키텍처이다.
도커 클라이언트와 도커 데몬이 Rest-API를 사용하여 통신한다.
Docker 데몬
•Docker API 요청 수신, 이미지, 컨테이너, 네트워크와 같은 도커 객체 및 도커 서비스 관리
Docker 클라이언트
- Docker 사용자가 Docker와 상호작용하기 위한 방법. 기본적인 도커 커맨드를 통해서 Docker 데몬과 통신
Docker 레지스트리
- Docker 이미지를 저장, Docker hub이라는 공용 레지스트리와 개인private한 레지스트리가 있다. 일반적으로 공용 레지스트리에서 실행
Docker 객체
• 도커 이미지: 도커 이미지는 컨테이너 실행에 필요한 파일과 설정 값 등을 포함하고 있다.
• 컨테이너 : 컨테이너는 도커 이미지의 실행 가능한 인스턴스입니다.
VM의 장점
1개의 VM내에 다수의 어플리케이션을 설치해서 연동하여 사용하거나 유기적으로 구동하여 사용하거나, 일반적인 서버 자체가 필요한 경우도 다수 상황에서 존재한다.
컨테이너는 경량화를 위해 해당 어플리케이션을 위한 구동을 위해 필요한 파일과 라이브러리를 담고 있다. 그런 컨테이너 이미지에 여러 라이브러리 , 패키지, 데몬, 유틸리티 등의 사용 필요성이 있을 수 있다.
다중의 목적의 다수의 라이브러리나 패키지가 설치해야 하거나 여러 데몬과 유틸리티가 필요할 경우 컨테이너 경량화 맞지 않으며 이러한 상황의 경우도 컨테이너 보다는 VM 이 더 맞을 것 같다.
또한 리눅스 도커(컨테이너) 환경에서는 윈도우 환경의 컨테이너를 구동할 수 없다.
컨테이너는 호스트OS 를 기반으로 하여 리소스와 드라이버를 공유해서 사용하기 때문에 윈도우 컨테이너는 윈도우 호스트 OS 환경에서만 가능하다.
요약
아래 워터마크와 같이 링크드인에 유용한 그림이 많다.
'클라우드 > Docker & K8s' 카테고리의 다른 글
구글 스터디잼 (0) | 2022.10.21 |
---|---|
K8s, Kubernetes - 기본 개념 (추가 중) (0) | 2022.10.06 |
쿠버네티스 - Probe (1) | 2022.07.30 |
쿠버네티스 - 디플로이먼트 yaml 파일 예시, Kubernetes - Deployment.yaml sample (0) | 2022.07.30 |
쿠버네티스 기본 개념 (3) | 2022.07.09 |