이번엔 Virtualization(가상화), Container 개념과 Docker에 대하여 한번 알아보겠습니다.
What is Virtualization? (가상화)
클라우드 컴퓨팅에서 Virtualization(가상화)는 H/W (하드웨어) 기능을 시뮬레이션 하여 App Server, Storage, Network와 같은 유용한 IT Service를 생성하는 SW Architecture 기술입니다.
모든 규모의 비즈니스에서 IT 비용을 절감하면서 효율성, 대응력(민첩, 탄력성), 가용성 향상과 운영 자동화를 통해 IT 관리를 간소화 & 소유, 운영비용을 낮출수 있습니다. 이처럼 클라우드는 기업이 추가하는 비용 효율적인 부분을 만족시킨다는 특징이 있습니다.
최근 사용하고 있는 가상화는 하이퍼바이저를 이용한 Virtual Machine(가상 머신)과 Container(컨테이너)를 이용한 Docker 방식입니다. Virtual Machine(가상 머신)은 Host OS(운영체제) 위에 가상화 SW를 이용하여 여러개의 Guest OS(Ubuntu, CentOS)등을 구동화는 방식입니다.
하이퍼바이저(hypervisor)는 가상머신(Virtual Machine, VM)을 생성하고 실행하는 역할과 가상화된 하드웨어와 각각의 가상머신을 모니터링하는 중간 관리자의 역할을 수행합니다.
대표적인 가상화 프로그램인 VMware의 VMware 제품과 오라클의 VirtualBox를 이용하여 게스트 OS가 사용할 수 있는 물리적 공간을 격리하는 기술입니다.
각각의 게스트 OS는 호스트 운영체제로부터 독립된 자원을 할당받아 가상화된 서비스를 제공하기 때문에 수 기가바이트(GB)의 용량을 차지하는 이미지를 만들어 사용합니다. 이러한 타입을 호스트형(hosted) 하이퍼바이저(또는 호스트형 서버 가상화)라고 합니다. 따라서 가상머신은 하드웨어 가상화입니다.
컨테이너를 이용한 가상화는 리눅스 기반의 물리적 공간 격리가 아닌 프로세스 격리를 통해 경량의 이미지를 실행하고 서비스할 수 있는 컨테이너(Container)기술 입니다. 사전적 의미로 보면, 컨테이너는 특정 대상을 격리하는 공간을 의미합니다. 따라서 클라우드 서비스의 컨테이너는 애플리케이션을 구동하는 환경을 격리한 공간을 의미합니다.
Docker 엔진이 차용하고 있는 컨테이너 기술은 본래 리눅스 자체 기술인 chroot, 네임스페이스(namespace), cgroup을 조합한 리눅스 컨테이너(Linux Container, LXC)에서 출발합니다.
- chroot: 특정 디렉터리를 최상위 디렉터리 root로 인식하게끔 설정하는 리눅스 명령
- 네임스페이스 (namespace): 프로세스 자원을 관리하는 기능으로, mnt, pid, net, ipc, user 등의 자원을 그룹화하여 할당하는 기능
- cgroup (control group): CPU, 메모리, 디스크 I/O, 네트워크 등의 자원 사용량 제어를 통해 특정 애플리케이션의 과도한 자원 사용을 제한하는 기능
물리적 요소에 대한 가상화인 가상머신과 다르게 컨테이너 가상화는 프로세스 가상화입니다. 컨테이너 엔진 도커와 오케스트레이션(orchestration) 도구인 쿠버네티스(Kubernetes)는 호스트 운영체제의 커널을 공유하고 그 위에 실행 파일 및 라이브러리(Bins/Libs), 기타 구성 파일 등을 이미지로 빌드(image build)하여 패키지로 배포(image run)하는 방식입니다.
컨테이너 기술의 장점
- 하이퍼바이저와 게스트 OS가 없기 때문에 가볍다(수십 메가바이트).
- 경량이기 때문에 만들어진 이미지 복제, 이관, 배포가 쉽다.
- 게스트 OS를 부팅하지 않기 때문에 애플리케이션(App)등 시작 시간이 빠르다.
- 가상머신보다 경량이므로 더 많은 애플리케이션을 실행할 수 있다.
Server Virtualization(가상화) 하는법
서버 가상화하는 방법 1 (호스트 가상화)
- 가장 쉬운 방법으로 Windows나 MacOS에서 가상화 소프트웨어를 이용하여 서버를 만들 수 있습니다.
- (예: Virtual Box, VMware Fusion 등등)
서버 가상화하는 방법 2 (하이퍼바이저 가상화)
- 하드웨어에 "하이퍼바이저"를 설치하여 가상 자원을 만드는 방법입니다. (예: Xen, KVM 등등)
- OS의 명령어를 하이퍼바이저가 모두 받아들이거나(Para-Virtualization, PV) 하드웨어에서 OS 명령어를 이해하는 경우(Hardware Virtual Machine, HVM / Bare-Metal Hypervisor)가 있습니다.
서버 가상화하는 방법 3 (컨테이너 가상화)
- 컨테이너 관리 소프트웨어를 설치하여, 논리적으로 컨테이너를 나누어 사용 (예: Linux Container, Docker 등등)
부록. AWS에서는 어떠한 가상화 개념을 사용..?
- AWS EC2에서는 초반에는 PV 방식을 사용하다가 주로 HVM 방식을 사용하고 있으며, 최근에는 Nitro System을 사용하고 있다고 합니다.
- AWS ECS에서는 컨테이너 가상화를 활용하고 있습니다.
Virtualization(가상화)의 종류
서버 가상화
- 설명: 하나의 물리적 서버를 여러 개의 가상 서버로 분할하여, 마치 각 가상 서버가 독립된 서버인 것처럼 운영할 수 있게 합니다. 물리적인 자원을 가상화 소프트웨어(VMware, Hyper-V 등)를 통해 분할함으로써, 하나의 서버에서 여러 운영 체제를 동시에 실행할 수 있습니다.
- 장점: 서버 자원의 활용도를 극대화하고, 하드웨어 비용을 절감하며, 서버 유지 관리 시간을 줄일 수 있습니다. 예를 들어, 물리적 서버 한 대를 여러 부서에서 각각의 가상 서버로 나누어 사용할 수 있습니다.
데스크탑 가상화
- 설명: 사용자의 데스크탑 환경을 가상화하여, 원격 서버에서 데스크탑 운영체제를 실행하고, 사용자는 네트워크를 통해 해당 환경에 접속해 사용하는 방식입니다. 대표적으로 VDI(Virtual Desktop Infrastructure) 기술이 사용됩니다.
- 장점: 중앙에서 데스크탑 환경을 관리할 수 있어 보안 및 업데이트가 용이하며, 사용자는 어느 기기에서나 동일한 데스크탑 환경에 접속할 수 있습니다. 특히, 재택근무와 같은 원격 환경에서 많이 사용됩니다.
애플리케이션 가상화
- 설명: 애플리케이션을 가상 환경에서 실행하여, 애플리케이션과 운영 체제를 분리하는 방식입니다. 가상화된 애플리케이션은 중앙 서버에서 실행되고, 사용자는 이를 네트워크를 통해 접근합니다.
- 장점: 애플리케이션 설치 문제를 줄이고, 특정 운영 체제에 종속되지 않으며, 애플리케이션 충돌 문제를 방지할 수 있습니다. 또한, 사용자는 애플리케이션 설치 없이도 실행할 수 있습니다.
네트워크 가상화
- 설명: 물리적 네트워크 자원을 가상화하여, 여러 가상 네트워크를 생성하고 관리할 수 있는 방식입니다. 예를 들어, 하나의 물리적 네트워크를 여러 개의 논리적 네트워크로 분할하거나, 네트워크 기능(라우터, 스위치 등)을 소프트웨어로 구현하는 방식입니다.
- 장점: 네트워크 자원을 더 유연하게 관리하고, 네트워크 구성 변경이 쉬워지며, 효율적으로 네트워크 자원을 사용할 수 있습니다. SDN(Software Defined Networking)이 대표적인 예시입니다.
스토리지 가상화
- 설명: 물리적인 스토리지를 추상화하여, 여러 물리적 스토리지를 하나의 논리적 스토리지 풀로 통합하거나, 반대로 하나의 물리적 스토리지를 여러 개의 논리적 스토리지로 나누는 방식입니다. 이는 물리적 장치의 위치와 무관하게 스토리지를 유연하게 사용할 수 있게 합니다.
- 장점: 스토리지 용량을 더 효율적으로 관리하고, 중앙 집중식 스토리지 관리가 가능해집니다. 다양한 스토리지 장치를 논리적으로 통합해 사용자가 원하는 대로 용량을 할당할 수 있습니다.
Docker (도커)
컨테이너는 최신 기술이 아닙니다. 오랜 시간 동안의 변화를 통해 리눅스 컨테이너(Linux Container, LXC) 기술로 완벽해졌고, LXC 기술을 차용한 도커를 통해 컨테이너의 생성과 배포를 위한 완벽한 가상화 솔루션, 컨테이너 표준화로 자리 잡았습니다.
컨테이너는 코드와 모든 종속성, 패키지화하는 표준 소프트웨어 단위로, 애플리케이션이 다른 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 합니다. 도커 컨테이너 이미지는 애플리케이션을 실행하는 데 필요한 모든 것(코드, 런타임, 라이브러리 등)을 포함하는 경량의 독립 실행 기능 소프트웨어 패키지라고 정의할 수 있습니다.
도커 컨테이너 이미지는 도커 허브(docker hub)로부터 내려받거나 Dockerfile을 통해 생성하여 도커 엔진을 이용해 실행하면 컨테이너 서비스가 됩니다.
도커의 주요 기능.
- LXC를 이용한 컨테이너 구동: containerd는 리눅스 및 윈도우용 데몬(daemon)으로, 이미지 전송 및 스토리지에서 컨테이너 실행 및 감독, 네트워크 연결까지 호스트 시스템 전체 컨테이너의 라이프사이클을 관리한다.
- 통합 Buildkit: Buildkit은 도커 파일의 설정 정보를 이용하여 도커 이미지를 빌드하는 오픈 소스 도구이며, 빠르고 정확하게 여러 가지 아키텍처 향상 기능을 제공한다.
- 도커 CLI 기반: 도커 명령을 수행하는 기본적인 방법은 CLI(Command Line Interface)로 제공한다.
도커를 사용하기 위해서는 두가지 구성 요소를 다룰 수 있어야 합니다. 우선은 컨테이너, 이미지를 다룰 수 있는 도커 엔진이 필요하고, 다음으로 이미지를 업로드(push)하거나 다운로드(pull)할 수 있는 도커 허브에서 서비스를 제공받아야 합니다.
user@docker-host:~$ docker pull ubuntu:18.04
# push를 하려면 사전의 Docker Hub에 가입이 되어 있어야 하고, docker login을 통해 접속한 후 수행할 수 있습니다.
user@docker-host:~$ docker push dbgurum/test_image:1.0
위의 예시는 도커 허브로부터 Ubuntu(우분투) 18.04 버전을 호스트로 다운로드를 수행하고, test_image라는 새로운 이미지를 생성한 경우, 이 이미지를 dbgurum(필자의 도커 hub 저장소명)에 test_image:1.0이라는 태그(tag)로 업로드를 수행할 것 입니다.
별도의 도커 컨테이너 이미지 서버를 지정하지 않으면 자동으로 도커 허브로 지정됩니다.
큰 개념의 클라우드 서비스와 연결해서 생각해 본다면, 도커 컨테이너 기술은 PaaS 서비스를 가능하게 하는 소프트웨어 개발 환경을 제공하는 것입니다. 다만, 컨테이너 서비스에 대한 자동화된 관리, 트래픽 라우팅, 로드 밸런싱 등을 쉽게 하려면 오케스트레이션 기능이 추가로 요구됩니다.
애플리케이션 테스트를 해야 하는 상황을 예로 들어보겠습니다. Node.js로 만든 샘플 코드를 테스트하고자 한다면? 하지만 현재 로컬에 node.js 소스 코드를 실행하기 위한 npm이라는 모듈이 필요합니다.
"그냥 설치하면 되겠지"라고 생각하겠지만, 하나의 애플리케이션이 아닌 여러 가지 의존성 있는 애플리케이션이나 데이터베이스까지 필요한 상황이라면 어떨까요? 환경 설정과 함께 각 애플리케이션을 설치하는 데 많은 시간을 투자해야 하는 상황이 벌어질 수도 있습니다. 하지만 도커 환경에서는 다음과 같이 간단하게 만들어진 샘플 소스 코드를 테스트할 수 있습니다.
# docker hub으로부터 node 도커 이미지를 다운로드함.
# 이미지를 뒤에 버전을 지정하지 않으면 자동으로 latest(최신) 버전으로 지정.
user@docker-host:~$ docker pull node
# 다운로드한 이미지를 실행하여 컨테이너화(containerized)함.
user@docker-host:~$ docker run -d -it --name=nodejs_test node:latest
# 컨테이너 실행 확인.
user@docker-host:~$ docker ps
# 미리 작성해 둔 소스 코드를 컨테이너 내부로 복사. (nodejs_test.js)
# 내부에서 작성해도 되지만 별도 편집 프로그램(vi 등) 설치가 필요하여 복사함.
user@docker-host:~$ docker cp nodejs_test.js nodejs_test:/nodejs_test.js
# 실행 중인 npm이 설치된 nodejs_test 컨테이너에서 bash 셸(shell)로 접속.
user@docker-host:~$ docker exec -it nodejs_test /bin/bash
# 전달된 소스 코드 확인.
root@579bcaa04d40:/# ls
bin boot dev etc home lib lib64 media mnt nodejs_test.js
# 설치된 npm 모듈 버전 확인.
root@579bcaa04d40:/# node -v
v13.5.0
# node 프로그램을 이용하여 샘플 소스 코드 테스트 수행.
root@579bcaa04d40:/# node nodejs_test.js
도커를 처음 사용해 본 사용자에게는 어쩌면 더 부담스러워 보일 수도 있지만, 도커에 어느 정도 익숙한 사용자에게는 눈에 띄게 끝낼 수 있는 간단한 테스트일 수도 있습니다. 도커가 가지고 있는 구조적 특징으로 사전에 만들어진 이미지를 이용하여 애플리케이션 테스트가 가능합니다.
Docker(도커)는 위에서 언급한 기본적인 도커 엔진, 도커 허브 외에 활용도가 높은 많은 구성 요소가 있습니다.
- Docker Engine: 도커를 이용한 애플리케이션 실행 환경 제공을 위한 핵심 요소
- Docker Hub: 전 세계 도커 사용자들과 함께 도커 컨테이너 이미지를 공유하는 클라우드 서비스
- Docker-compose: 의존성 있는 독립된 컨테이너에 대한 구성 정보를 YAML 코드로 작성하여 애플리케이션의 관리를 가능하게 하는 도구
- Docker Kitematic: 컨테이너를 이용한 작업을 수행할 수 있는 GUI(Graphic User Interface) 제공
- Docker Registry: 도커 허브 사이트를 공개된 레지스트리로 보면 됨. 사내에 도커 컨테이너 이미지를 push/pull 할 수 있는 독립된 레지스트리 구축 시 사용
- Docker Machine: 가상머신 프로그램(VMware, Virtualbox) 및 AWS EC2, MS Azure 환경에 도커 실행 환경을 생성하기 위한 도구
- Docker Swarm: 여러 도커 호스트를 클러스터로 구축하여 관리할 수 있는 도커 오케스트레이션 도구
Docker 맛보기: PWD
이 사이트로 들어가서 play with Docker 아래 있는 링크를 누르고 시작하면 됩니다.
- Log into https://labs.play-with-docker.com/ to access your PWD terminal
- Type the following command in your PWD terminal
docker run -dp 80:80 docker/getting-started:pwd
- Wait for it to start the container and click the port 80 badge
- Have fun!
Docker 환경 살펴보기
한번, Docker 환경을 살펴보겠습니다.
- 가상 IP 주소와 함께 자원(메모리, CPU)에 대한 리소스 현황을 볼 수 있다.
- SSH(Secure Shell)로 접속할 수 있는 주소를 지원한다.
- [OPEN PORT]는 도커 컨테이너를 외부로 노출 시 바인드되는 포트 번호를 보여준다.
추가적인 환경 구성은 직접 살펴보시는것을 권장합니다.
도커는 리눅스를 기반으로 하는 컨테이너 서비스이므로 기본 리눅스 환경에 익숙해야 컨테이너를 다루기가 쉽다는점이 있습니다.
특정 테스트를 하기 위해 CentOS 7 버전이 필요한 상황을 가정해 보겠습니다.
다음과 같이 제공된 터미널 환경에서 따라 해보겠습니다. 자세한 명령어에 대한 의미는 추후 설명하겠습니다.
# 제공된 환경에 이미지와 컨테이너가 있는지 조회해 본다. 아무것도 없을 것이다.
$ docker image ls
$ docker ps
# 도커 허브 사이트로부터 CentOS 7 버전의 도커 컨테이너 이미지를 다운로드한다.
$ docker pull centos:7
7: Pulling from library/centos
ab5ef0e58194: Pull complete
Digest: sha256:46a7017360d3f6b39bc8a2af84a8e499441bd567f9a9db58e4991de4472fb813c
Status: Downloaded newer image for centos:7
docker.io/library/centos:7
# 다운로드한 이미지를 확인해 본다.
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7 5e35e350aded 4 months ago 203MB
# 이미지만 가지고 있는 CentOS 7 능력을 구경해 볼까? 컨테이너를 시작한다.
$ docker run -it --name=centos7_test centos:7 /bin/bash
# 프롬프트(prompt)가 변경, CentOS 7 컨테이너 환경으로 들어온 것을 확인해 본다.
root@9b06b91cfbc397:/# cat /etc/os-release
- 실행결과
[node1] (local) root@192.168.0.8 ~
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
centos 7 eeb6ee3f44bd 3 years ago 204MB
[node1] (local) root@192.168.0.8 ~
$ docker run -it --name=centos7_test centos:7 /bin/bash
[root@c688259f528d /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="7 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="7"
PRETTY_NAME="CentOS Linux 7 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:7"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"
CENTOS_MANTISBT_PROJECT="CentOS-7"
CENTOS_MANTISBT_PROJECT_VERSION="7"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="7"
다운로드한 CentOS 7 이미지 용량을 살펴보겠습니다. 204MB에 지나지 않습니다.
만약 실제 환경 또는 가상머신(VM)에서 설치했다면 아마도 3~5GB 정도의 물리적 공간을 차지했을 것입니다.
# PWD Terminal에서 다음 명령어 입력
docker run -dp 80:80 docker/getting-started:pwd
[node1] (local) root@192.168.0.8 ~
$ docker run -dp 80:80 docker/getting-started:pwd
Unable to find image 'docker/getting-started:pwd' locally
pwd: Pulling from docker/getting-started
89d9c30c1d48: Pull complete
24f1c4f0b2f4: Pull complete
16542569a10d: Pull complete
08396939143d: Pull complete
Digest: sha256:9156d395e7e41498d5348e95513d61fc7929db720393448306c5d7263d7f2696
Status: Downloaded newer image for docker/getting-started:pwd
d0c837c344a3a4d9bd94635ab885ac7fa1ea7f438ca9385472f1a12505ff2897
보시면, 제공된 SSH 주소에 해당 컨테이너 내부에 저장된 웹 화면을 80번 포트로 연결해서 웹 페이지에서 보여주는 것을 확인할 수 있습니다.
호기심이 든다면 호스트 포트 번호를 변경해 보는 것도 한번 해보시길 바랍니다.
80:80(호스트 포트:컨테이너 포트) 값을 8888:80으로 변경
상단에 [OPEN PORT] (8888)(80) 포트가 추가로 생기고, (8888)을 클릭해 보면 처음에 봤던 같은 페이지를 볼 수 있습니다.
'☁️ Cloud' 카테고리의 다른 글
[Cloud] Docker Installation Check (도커 설치 확인) (0) | 2024.10.11 |
---|---|
[Cloud] Ubuntu에 Docker Community Edition (CE) 설치 (0) | 2024.10.08 |
[Cloud] Docker Install (도커 설치 with UTM, Ubuntu install) (0) | 2024.10.07 |
[Cloud] Kubernetes(쿠버네티스) & DevOps(데브옵스) Intro (0) | 2024.10.05 |
[Cloud] Cloud Computing (클라우드 컴퓨팅) (0) | 2024.10.03 |