정리 예정/🐳 Docker

[도커 교과서] 2장

전호영 2024. 6. 27. 13:10

본 글은 도커 교과서를 읽고 정리한 내용입니다.


(본 장에선 컨테이너를 실행하는 다양한 방법을 알아볼 예정이며, 컨테이너그 정확히 무엇인지 살펴보고, 컨테이너가 애플리케이션을 경량으로 실행할 수 있는 이유를 알아볼 예정)

 

docker container run diamol/ch02-hello-diamol

 

docker container run 명령은 컨테이너로 애플리케이션을 실행하라는 도커 명령.

여기서 애플리케이션은 미리 도커로 실행하도록 패키징돼 누구나 내려받을 수 있도록 공유된 것.

-> 이 컨테이너 패키지(도커에선 '이미지'라 부름)의 이름은 diamol/ch02-hello-diamol

 

= docker container run 명령어는 이미지를 이용해 컨테이너를 실행하는 명령.

 

docker container run을 사용하면 실행되는 순서

  1. 이미지를 이용해 컨테이너를 실행하려면 먼저 이미지가 있어야 함. 
  2. 만약 이미지가 없다면, 도커가 이미지를 내려받음(pull)
  3. 이미지를 내려받고 나면 내려받은 이미지를 사용해 컨테이너를 실행함. (이미지엔 애플리케이션을 실행하는 데 필요한 모든 내용과 함께 애플리케이션을 실행하는 방법이 정의돼 있음.)

도커 사용 워크플로우

  1. 애플리케이션을 컨테이너에서 실행할 수 있도록 패키징
  2. 다른 사람이 패키지를 사용할 수 있도록 공유
  3. 패키지를 내려받은 사람이 컨테이너를 통해 애플리케이션 실행

위 과정을

빌드 , 공유 , 실행이라고 부름!

 

다시 명령어를 실행하면

 docker container run diamol/ch02-hello-diamol

 

 

처음과 다른 결과가 나옴.

도커가 전에 이미지를 다운받았으므로 이미지를 내려받는 부분이 사라지고 바로 컨테이너를 실행하는 메시지가 출력됨.

또 컴퓨터 이름(My name is: 아래부분)이 달라지는 것을 볼 수 있다.(IP주소도 달라질 수 있음)

 

모든 컨테이너는 같은 컴퓨터에서 실행되는데 왜 컴퓨터 이름과 IP 주소가 달라질까?

 

컨테이너란 무엇일까?

도커에서 컨테이너란 물건을 담는 컨테이너!

만약 애플리케이션이 어떤 상자안에 있다고 상상해볼 때, 이 상자 안엔 애플리케이션과 애플리케이션을 실행할 컴퓨터(IP 주소, 컴퓨터 이름, 디스크 드라이브 등)이 들어있다. 

호스트명, IP 주소, 파일 시스테마지 모두 도커가 만들어낸 가상 리소스가 되고,

이들이 엮여 애플리케이션이 동작할 수 있는 환경이 만들어지고, 이 환경이 위 그림의 '상자'가 됨.

 

상자 안에선 상자 밖의 환경을 볼 수 없다. 그러나 상자는 어떤 컴퓨터에서 동작하는 것이며, 이 컴퓨터는 이 상자 말고도 다른 여러 상자를 실행할 수 있다.

이 상자들은 (도커가 관리하는)서로 독립적인 환경을 갖지만, 상자가 실행되는 컴퓨터의 CPU와 메모리, OS를 공유함

 

여러 상자가 실행되는 환경은 아래와 같다.

같은 컴퓨터에서 운영체제와 CPU, 메모리를 공유하는 여러개의 컨테이너

위 구도는 격리(isolation)밀집(density)을 만족함.

밀집이란 컴퓨터에 CPU와 메모리가 허용하는 한 되도록 많은 수의 애플리케이션을 실행하는 것을 의미함.

그러나 여러 애플리케이션이 동시에 실행할 땐 여러 문제가 있을 수 있다.(런타임 버전, 호환되지않는 라이브러리 등)

그러므로 애플리케이션은 서로 독립된 환경에서 실행되어야 함.

도커는 위 그림처럼 밀집과 격리를 동시에 달성한다. 매우 효율적!

 

컨테이너를 원격 컴퓨터처럼 사용하기

아래 명령어를 실행해보자.

docker container run --interactive --tty diamol/base

 

 

--interactive : 컨테이너에 접속한 상태로 만듬

--tty : 터미널 세션을 통해 컨테이너를 조작하겠다는 의미

 

도커 컨테이너는 호스트 컴퓨터의 운영체제를 공유하기에 호스트 컴퓨터가 리눅스 머신이면 리눅스 셸이 뜨고, 윈도우 머신이라면 윈도우 명령 프롬프트가 뜨게 될 것.

 

docker container ls

위 명령어를 통해 현재 호스트 컴퓨터에서 돌아가는 컨테이너를 볼 수 있다.

 

 

CONTAINER ID가 다른 것을 볼 수 있다.

서로 다른 컨테이너에서 돌아가고 있다는 뜻!

 

컨테이너를 사용해 웹 사이트 호스팅하기

앞에서 했던 내용들(컨테이너 실행하기)은 터미널 창에서 세션을 끝내면 모든 컨테이너가 종료됨.

 

컨테이너의 상태가 Existed임을 볼 수 있음.

여기서 알아둬야 하는 내용은 2가지

 

1. 컨테이너 내부의 애플리케이션이 실행중이어야 컨테이너의 상태도 실행 중이 된다.

  • 애플리케이션 프로세스가 종료되면 컨테이너의 상태도 Existed가 된다.
  • 종료된 컨테이너는 CPU 자원이나 메모리를 사용하지 않는다.
  • 단순히 텍스트를 출력하는 컨테이너도 스크립트 실행이 끝나면 종료되고, 대화식 컨테이너도 터미널 세션을 종료하는 시점에 종료된다.

2. 컨테이너가 종료돼도 컨테이너는 사라지지 않는다.

  • 종료된 컨테이너는 명시적으로 삭제하지 않는 한 그대로 남아있다.
    • 컨테이너의 파일 시스템이 그대로 남아있으므로 호스트 컴퓨터의 디스크 공간을 계속 차지한다.
    • 나중에 컨테이너를 다시 실행하거나 , 로그를 확인하거나, 컨테이너의 파일 시스템에 새로운 파일을 복사하거나 외부로 복사해올 수 있다.

 

그렇다면 컨테이너를 실행하고 백그라운드에서 계속 동작하게 하려면 어떻게 해야할까?

아래 명령어를 실행하면

docker container run --detach --publish 8888:80 diamol/ch02-hello-diamol-web

 

 

 

아래 명령어를 통해 상태를 확인해보자

docker container ls

 

 

상태가 Up임을 볼 수 있음.

 

아래 명령어에 대해 자세히 알아보자.

docker container run --detach --publish 8888:80 diamol/ch02-hello-diamol-web
  • --detach : 컨테이너를 백그라운드에서 실행하며 컨테이너 ID를 출력함.
  • --publish : 컨테이너의 포트를 호스트 컴퓨터에 공개함.

--detach 플래그를 적용해 실행한 컨테이너는 백그라운드에서 동작함.

 

컨테이너의 포트를 호스트 컴퓨터에 공개하는 원리는 다음과 같다.

  • 도커를 설치하면 호스트 컴퓨터의 네트워크 계층에 도커가 끼어들게 되는데, 그러면 호스트 컴퓨터에서 들어가고 나오는 네트워크 트래픽을 모두 도커가 가로채 그중 필요한 것을 컨테이너에 전달할 수 있음!
  • 컨테이너는 기본적으로 외부 환경에 노출되지 않으므로, 각 컨테이너는 고유의 IP 주소를 갖지만, 이 IP 주소는 도커가 관리하는 내부 가상 네트워크의 주소지 호스트 컴퓨터가 연결된 물리 네트워크에 연결된 것이 아님.
  • 컨테이너의 포트를 공개한다는 것은 도커가 호스트 컴퓨터의 포트를 주시하다가 해당 포트로 들어오는 트래픽을 컨테이너에게 전달해주는 것!
    • --publish 8888:80 은 호스트 컴퓨터의 8888번 포트로 들어온 트래픽이 컨테이너의 80번 포트로 전달된다는 뜻

호스트 컴퓨터의 포트를 8088이 아닌 8888로 생각하기

즉, 192.168.2.150은 내가 사용하는 물리 네트워크의 주소이며 내 집 공유기가 부여한 IP.

172.0.5.1은 도커가 부여한 도커 가상 네트워크의 주소임!

호스트 컴퓨터가 연결된 물리 네트워크의 컴퓨터는 컨테이너의 IP 주소에 접근할 수 없다. 왜냐하면 이 주소는 도커 내부에만 존재하는 주소이기 때문! 그러나 컨테이너의 포트가 외부로 공개됐으므로 컨테이너로 트래픽을 전달할 수 있다!

 

제대로 호스팅이 되고 있다!

이 웹페이지는 웹 서버와 함께 이미지로 패키징 됨.

실행중인 컨테이너를 삭제하려면 아래 명령어를 사용하면 됨.

docker container rm 컨테이너ID
docekr container rm --force 컨테이너ID

(--force 명령어는 실행중인 컨테이너도 바로 삭제해준다.)

docker container rm --force $(docker container ls --all --quiet)

(위 명령어는 모든 컨터이너를 삭제하는 명령!)

 

도커가 컨테이너를 실행하는 원리

 

도커를 구성하는 컴포넌트

  • 도커 엔진 : 도커의 관리 기능을 맡는 컴포넌트.
    • 로컬 이미지 캐시를 담당하기에 새로운 이미지가 필요하면 이미지를 내려받으며, 기존 이미지가 있다면 전에 내려받은 이미지를 사용.
    • 호스트 운영체제와 함께 컨테이너와 가상 네트워크 등 도커 리소스를 만드는 일도 담당.
    • 도커 엔진은 항시 동작하는 백그라운드 프로세스(리눅스 데몬같은 느낌)
    • 도커 엔진은 도커 API를 통해 맡은 기능을 수행
  • 도커 API : 표준 HTTP 기반 REST API.
    • 도커 엔진의 설정을 수정하면 이 API 네트워크를 경유해 외부 컴퓨터로부터 호출할 수 없도록 차단(기본 설정)하거나 허용할 수 있음.
    • 도커 엔진과 상호작용할 수 있는 유일한 방법
  • 도커 명령행 인터페이스(도커 CLI) : 도커 API의 클라이언트
    • 우리가 docker 명령을 사용할 때 실제로 도커 API를 호출하는 것이 바로 도커 CLI

도커 엔진은 containerd라는 컴포넌트를 통해 컨테이너를 실제로 관리하는데, containered는 호스트 운영체제가 제공하는 기능을 통해 컨테이너, 즉 가상 환경을 만든다.

 

 

연습문제 힌트(아래 드래그하기)

exec

-it