도커 이미지 구조
이전에도 봤지만 도커 이미지 구조는 위와 같습니다. 여기서 우리는 ubuntu이미지가 있고, nginx이미지는 ubuntu에 nginx 이미지 레이어를 하나 쌓아서 만들었다고 하고, web app이미지는 seb app source 이미지 레이어 하나를 더 추가해서 만들었다고 해 봅시다. 그리고 이 web app 도커 이미지를 활용하여 도커 컨테이너를 만듭니다. 이는 R/W 레이어고 도커 컨테이너가 삭제되면 이도 삭제된다는 특징이 있습니다.
실습
우리는 실습 전에 docker image inspect명령어를 통해 ub
untu:latest이미지에 어떤 레이어가 쌓여있는지 확인해 보겠습니다. 보니까 sha256해시로 6개의 레이어가 쌓여있는 것을 보실 수 있습니다.
Dockerfile 없이 이미지 생성
우선 먼저 Dockerfile없이 이미지를 생성하는 방법에 대해 알아보겠습니다. 기존 컨테이너를 기반으로 새 이미지를 생성할 수 있습니다.
이를 하기 위해 우선 ubuntu:focal로 도커 컨테이너를 만들고 루트 디렉토리에 hello라는 파일을 만들고 그 안에 아무 내용이나 집어 넣었습니다.
여기서 exit을 하게되면 컨테이너가 종료되기 때문에 ctr + p + q를 눌러 빠져나오도록 하겠습니다.
빠져나와도 컨테이너가 삭제되지 않았습니다.
그 다음에 docker commit을 통해서 위에서 루트 디렉토리에 hello파일을 추가한 my_ubuntu도커 컨테이너를 커밌했습니다. -a옵션을 주어 누가 했는지, 그리고 -m을 통해서 메세지와, 마지막에 만들 이미지 이름과 버전을 명시해줍니다.
그리고 docker images를 쳐서 도커 이미지의 목록을 확인하게 되면 우리가 만든 my-ubuntu이미지가 잘 있는 것을 보실 수 있습니다.
그리고 docker image inspect my-ubuntu:v1을 통해 정보를 보면, 두개의 레이어가 쌓여있는 것을 보실 수 있습니다.
우리는 my-ubuntu:v1이미지를 ubuntu:focal이미즐 통해서 만들었으므로 my-ubuntu:v1에 존재하는 Layer의 2개의 해시값중 하나는 무조건 ubuntu:focal껴여야 합니다. 확인해보면 b40e로 시작하는 레이어가 있습니다.
다음과 같이 my-ubuntu:v1을 통해서 도커 컨테이너를 만들었고 루트 디렉터리에 이전에 작성한 hello라는 파일이 있는 것을 확인할 수 있습니다.
Dockerfile 이용하여 이미지 생성
Dockerfile을 기반으로 시 이미지를 생성할 수 있는 명령어들입니다. -t옵션은 빌드된 이미지의 태그를 지정할 수 있습니다. 또한 -f옵션은 Dockerfile이 아닌 다른 Dockerfile을 통해서 빌드하고 싶을 때 씁니다.
우선 실습을 하기 위해 기존에 작성된 node 서버를 기반으로 진행해 보도록 하겠습니다. 파일 구조를 보게되면 루트에 Dockerfile이 있게 되고 spec안에 서버 스펙이 적혀있고 src안에 서버를 생성할 수 있는 코드가 있습니다.
Dockerfile을 보게되면 6줄로 명령어가 적혀있는 것을 보실 수 있습니다. 일단 이를 기반으로 docker build를 해보도록 하겠습니다.
build를 하고 image의 목록을 보게되면 my-app:v1이 잘 생성된 것을 보실 수 있습니다. 그리고 build직후의 콘솔을 보게되면 Sending build context to Docker daemon 4.61MB로 도커 데몬에게 파일을 일단 넘긴것을 보실 수 있고 Dockerfile의 6줄이 각 줄을 1 step으로 쳐서 명령어가 실행되는 것을 보실 수 있습니다.
또한 우리가 주목해야 할 점은 이 명령어가 쳐지고 하나의 이미지 레이어가 생성된다는 것인데, 이는 다음번에 빌드될 때, 만약 같다면 캐시된다는 점입니다. 이를 my-app:v2이미즐 빌드할 때, 어떻게 캐시되는지 살펴보도록 하겠습니다.
다음과 같이 캐시가 됩니다.
빌드 컨텍스트
도커 빌드 명령 수행 시 현재 디렉토리(Current Working Directory)를 빌드 컨텍스트(Build Context)라고 합니다. Dockerfile로부터 이미지 빌드에 필요한 정보를 도커 데몬에게 전달하기 위한 목적입니다.
예를 들면 Dockerfile의 COPY . .에서 CWD의 현재 디렉토리를 알아야 도커 컨테이너에 복사할 수 있는데, 이를 위해서는 무조건 빌드 컨텍스트가 필요함을 느끼실 수 있을겁니다. 즉 빌드가 시작될 때, 해당 디렉토리의 모든 정보가 도커 데몬에게 넘어간다라고 이해하면 좋을거 같습니다. 그러므로 해당 디렉토리의 정보가 너무 많게 되면 빌드가 되는 시간이 길어지게 되고, 매우 비효율적이게 됩니다.
이러한 문제를 해결하기 위해 .dockerignore를 도커가 제공합니다.
도커가 이미지를 빌드할 때, 특정 디렉토리 혹은 파일 목록을 빌드 컨텍스트에서 지외하기 위한 목적입니다.
'DevOps > AWS Architecture' 카테고리의 다른 글
[ Docker && Kubernetes ] - 도커 컨테이너 다루기:이미지 압축파일로 저장 및 불러오기 (0) | 2022.09.03 |
---|---|
[ Docker && Kubernetes ] - 도커 컨테이너 다루기: Dockerfile (0) | 2022.09.03 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기: 로그 (0) | 2022.09.03 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기: 볼륨 (0) | 2022.09.02 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기: 네트워크 (0) | 2022.09.02 |