[따라하며 배우는 도커와 CI환경] 1. 도커 기본
✔️ 도커(Docker) 란 무엇인가?
도커는 컨테이너를 사용하여 응용프로그램을 더 쉽게 만들고 배포하고 실행할 수 있도록 설계된 도구 이며 컨테이너 기반의 오픈소스 가상화 플랫폼이자 생태계 이다.
도커를 이해하기 위해서는 먼저 컨테이너의 개념을 알고 있어야 한다.
컨테이너의 개념을 먼저 알아보고, 도커 이미지에 대하여 알아보자.
컨테이너
컨테이너는 코드와 모든 종속성을 패키지화하여 응용 프로그램이 한 컴퓨팅 환경에서 다른 컴퓨팅 환경으로 빠르고 안정적으로 실행되도록 하는 소프트웨어의 표준 단위 이다.
즉 컨테이너는 도커에서의 실행 단위로써, 격리된 공간에서 프로세스가 동작하는 기술을 의미한다.
도커 이미지
도커 이미지는 코드, 런타임, 시스템 도구, 시스템 라이브러리 및 설정과 같은 응용 프로그램을 실행하는 데 필요한 모든 것을 포함하는 가볍고 독립적이며 실행 가능한 소프트웨어 패키지 이다.
도커 이미지는 상태값을 가지지 않고 변하지 않는다.
반면 컨테이너는 이미지를 실행한 상태로써, 추가되거나 변하는 값이 컨테이너에 저장된다.
하나의 도커 이미지에서 여러 개의 컨테이너를 만들 수 있고, 컨테이너의 상태가 바뀌거나 삭제되어도 이미지는 변하지 않는다.
위에서 도커 이미지는 '응용 프로그램을 실행하는 데 필요한 모든 것'을 포함하고 있다고 했다.
그렇다면 그 필요한 것들은 무엇일까?
1. 컨테이너가 시작될 때 실행되는 명령어
ex) run kakaotalk
2. 파일 스냅샷
* 파일 스냅샷: 디렉토리나 파일을 copy 한 것
도커를 쓰는 이유
아주 간단하게 도커와 컨테이너, 도커 이미지에 대해 알아보았다.
그렇다면 Docker를 사용하는 이유는 무엇일까?
간단하게 말하자면, 보다 간편하게 프로그램을 설치하고 실행하기 위해서다.
프로그램을 설치하다보면 서버, 패키지 버전, 운영체제 등등에 따라 많은 에러들이 발생할 수 있다. 그래서 개발 초기에 환경 구축이 꽤 힘든 작업이 될 수 있는데, 이럴 때 도커를 사용하면 매우 유용하다. 도커를 사용하면 설치 과정 중 에러가 적게 발생하고, 과정도 간단해진다.
✔️ 도커 설치하기 (MacOS)
MacOS 환경에서 도커를 설치하는 과정은 다음과 같다.
1. 도커 사이트에서 docker desktop 다운로드
https://www.docker.com/products/docker-desktop/ 에 들어가서 자신의 환경에 맞는 파일을 다운로드한다.
2. 도커 실행
설치된 도커 아이콘을 클릭하여 실행하면 다음과 같은 창이 뜬다.
체크박스를 클릭 후 accept 버튼을 누르면 다음 창이 뜬다.
여기서 오른쪽 상단의 Sign in을 통해 로그인을 진행한다.
3. 도커 회원가입 및 로그인
도커 계정이 있다면 바로 로그인하고, 없다면 오른쪽 상단의 Sign Up을 통해 회원가입 후 로그인한다.
4. 설치 확인
docker version 명령어를 이용해 도커가 잘 설치되었는지 확인하자.
$ docker version
터미널에서 다음과 같은 출력문이 보인다면 잘 설치된 것이다.
✔️ 도커를 사용할 때의 흐름
'hello-world'라는 도커의 official image를 이용하여 도커의 흐름을 간단하게 알아보자.
1. 도커 Client (CLI)에 커맨드를 입력하면, Client에서 도커 Server (Demon)으로 요청을 보낸다
2. Server 에서 해당 이미지가 로컬에 cache 되어 있는지 확인한다.
3. 현재 'hello-world'라는 이미지가 로컬에 없기 때문에, Unable to find image 'hello-world:latest' locally 라는 문구가 표시된다.
4. Docker Hub에서 해당 이미지를 가져오고(pull) 로컬에 Cache로 보관한다.
(Docker Hub는 무료 public image repository로써, 여러 docker 유저가 올려놓은 image를 다운로드할 수 있다.)
5. 가져온 이미지를 이용해서 컨테이너를 생성하고, "run" 명령어를 실행한다.
✔️ 도커와 기존의 가상화 기술과의 차이
다음은 도커와 기존 가상화 기술의 구조를 나타낸 것이다.
* 하이퍼 바이저: 호스트 시스템에서 다수의 게스트 OS를 구동할 수 있게 하는 소프트웨어
위의 그림에서도 알 수 있듯이, 기존 가상화 기술에는 하이퍼바이저와 게스트(Guest) OS가 있지만, 도커에는 없다.
도커는 하이퍼바이저와 게스트 OS가 필요하지 않기 때문에 오버헤드가 적고 더 가볍다는 특징이 있다.
애플리케이션을 실행할 때 도커와 VM은 어떻게 동작할까?
기존 가상화 기술의 경우, VM을 띄우고 자원을 할당한 다음에 Guest OS를 부팅하여 애플리케이션을 실행한다.
도커의 경우, 호스트 OS 위에 애플리케이션 실행 패키지인 이미지를 배포하여 애플리케이션을 실행한다.
VM을 통해 애플리케이션을 실행하는 것이 훨씬 복잡하고 무겁다는 것을 알 수 있다.
공통점
도커 컨테이너와 가상 머신 모두 기본 하드웨어에서 격리된 환경 내에 애플리케이션을 배치하는 방법이다.
차이점
도커 컨테이너에서 돌아가는 애플리케이션은 컨테이너가 제공하는 격리 기능 내부에 샌드박스가 있지만, 여전히 같은 호스트의 다른 컨테이너와 동일한 커널을 공유한다.
결과적으로, 컨테이너 내부에서 실행되는 프로세스는 호스트 시스템(모든 프로세스를 나열할 수 있는 충분한 권한있음)에서 볼 수 있다.
예를 들어, 도커와 함께 몽고DB 컨테이너를 시작하면 호스트(도커가 아님)의 일반 쉘에 ps-e grep 몽고를 실행하면 프로세스가 표시된다.
또한, 컨테이너가 전체 OS를 내장할 필요가 없기 때문에 매우 가볍다. 일반적으로 약 5-100 MB의 용량을 차지한다.
가상 머신과 함께 VM 내부에서 실행되는 모든 것은 호스트 운영체제 또는 하이퍼바이저와 독립되어 있다.
가상 머신 플랫폼은 특정 VM에 대한 가상화 프로세스를 관리하기 위해 프로세스를 시작하고, 호스트 시스템은 그것의 하드웨어 자원의 일부를 VM에 할당한다.
그러나 VM과 근본적으로 다른 것은 시작 시간에 이 VM 환경을 위해 특정 VM만을 위한 커널을 부팅하고 운영체제 프로세스 세트를 시작한다는 것이다. 이것은 응용 프로그램만 포함하는 일반적인 컨테이너보다 VM의 크기를 훨씬 크게 만든다.
이러한 방법은 비교적 사용법이 간단할 수 있지만 굉장히 느리다.
✔️ 이미지로 컨테이너 만들기
이미지로 컨테이너 만드는 순서
1. Docker 클라이언트에 docker run <이미지> 를 입력한다.
*여기서는 docker run hello-world를 입력했다고 가정한다.
2. 도커 이미지에 있는 파일 스냅샷을 컨테이너 하드 디스크에 옮겨준다.
3. 이미지에서 가지고 있는 명령어를 이용해 hello-world를 실행시켜준다.
run hello-world 명령어를 실행하면, 커널을 통해 hello world 실행 파일을 실행시킨다.
✔️ Namespaces 와 Cgroup
도커는 어떻게 컨테이너를 격리시킬까?
도커는 완벽한 격리 환경을 만들기 위해, 리눅스 커널의 2가지 기능을 이용한다.
그 2가지 기능은 바로 C Groups(Control Groups)와 namespaces 이다.
Namespaces
하나의 시스템에서 프로세스를 격리시킬 수 있는 가상화 기술
별개의 독립된 공간을 사용하는 것처럼 격리된 환경을 제공하는 경량 프로세스 가상화 기술
리눅스 커널에서는 다음 6가지 namespace를 지원한다.
- mnt (파일시스템 마운트): 호스트 파일시스템에 구애받지 않고 독립적으로 파일시스템을 마운트하거나 언마운트 가능
- pid (프로세스): 독립적인 프로세스 공간을 할당
- net (네트워크): namespace간에 network 충돌 방지 (중복 포트 바인딩 등)
- ipc (SystemV IPC): 프로세스간의 독립적인 통신통로 할당
- uts (hostname): 독립적인 hostname 할당
- user (UID): 독립적인 사용자 할당
Cgroup
Control Groups의 약자로, 프로세스들이 사용할 수 있는 컴퓨팅 자원들을 제한하고 격리시킬 수 있는 리눅스 커널의 기능이다.
cgroup을 이용하면 프로세스의 시스템 리소스 사용량을 관리할 수 있다.
제한할 수 있는 리소스 종류
- CPU
- 메모리
- Network
- Device
- I/O
참고 자료