도커 이미지
도커 이미지는 컨테이너를 생성할 때 필요한 요소이다.(VM에서 쓰는 iso 파일과 비슷)
쉽게 얘기하면 이미지는 컨테이너를 찍어내는 틀이고, 컨테이너는 틀로부터 생성된 애플리케이션이다!
도커 이미지 이름
imsongkk/ubuntu:14.04
- imsongkk : 저장소 이름, Docker Hub나 AWS ECR 같이 docker image를 저장할 수 있는 repository의 이름이다. local에서만 이미지를 빌드할것이라면 저장소 이름은 필수가 아닐 수 있다.
- ubuntu : 이미지 이름, 해당 이미지의 이름으로 어떤 애플리케이션인지를 나타낸다.
- 14.04 : 태그, 1편에서 다뤘듯이 도커의 장점은 버전 관리가 된다는 것이다. 애플리케이션의 버전 정보를 나타내는 리비전으로 태그를 사용할 수 있다.
도커 이미지 구조
도커 이미지는 여러 개의 Layer로 구성되어있다. 태그는 도커 이미지 구조를 보여주는 좋은 예시이다
docker inspect ubuntu
ubuntu 이미지를 inspect 해보면 다음과 같이 Layer 정보가 나온다.
sha256~은 하나의 commit ID로, 어떤 Layer가 적재 되었는지를 알려준다.
이번에는 태그 별로 이미지를 파헤쳐보자
같은 이미지 이름을 갖는 3가지 버전의 태그가 다른 ubuntu 이미지가 있다.
0.1 태그를 갖는 버전의 이미지는 abcd라는 Layer만을 가지고 있고, 0.2 친구는 abcd 위에 efgh를 가지고 있다.
여기서 중요한 점은, 화살표의 방향대로 Layer들은 쌓이게 되며, 이전 버전(사실 정확히는 이전 버전은 아니고 다른 태그를 갖는 이미지) 의 Layer들은 그대로 있다는 점이다.
아니 commit이 뭐야
commit은 git을 써봤다면 아마 대부분 써보았을텐데, Docker Image에서도 그 의미는 비슷하다.
git에서 여러 commit들이 쌓여 시점을 완성하듯이, Docker Image에서는 변경 사항을 commit하여 Layer를 남긴다.
해당 이미지에 대한 수정이 끝난 이후에 commit을 통해 변경 사항을 저장한다고 이해하면 된다.
도커 이미지 생성
이미지는 컨테이너를 생성할 수 있고, 컨테이너도 이미지를 생성할 수 있다.
도커 이미지로 컨테이너 생성
docker pull ubuntu
docker pull ubuntu:14.04
docker pull은 이미지 레지스트리 저장소(Docker Hub, ECR)로 부터 도커 이미지를 내려받는 명령어이다.
태그를 지정해줄수도, 안할수도 있는데 지정하지 않는다면 자동으로 latest 버전을 가져오게 된다.
docker images
docker images는 현재 내 local에 있는 이미지의 목록을 나타낸다.
ubuntu:latest 이미지가 있는것을 확인할 수 있다.
이제 이미지로 컨테이너를 실행시켜 보자.
docker run -i -t ubuntu
docker run은 이미지로 컨테이너를 실행시키는 명령어로, 사용법과 옵션은 아래에서 더 자세하게 다룬다.
컨테이너를 실행시키고, 컨테이너 내부로 들어왔다!
bash 쉘의 이름이 16진수 hash 값으로 바뀌었다.
CTRL+P+Q를 눌러 다시 호스트로 돌아오자.
docker ps -a
docker ps 명령어는 현재 실행중인 컨테이너 목록을 보여준다.
- a 옵션을 통해 종료된 컨테이너도 보이게 했더니 b65a021d29d5라는 ID를 갖는 내가 만든 컨테이너가 보인다.
이렇게 이미지로 컨테이너를 생성할 수 있다!
도커 컨테이너로 이미지 생성
이번엔 반대로 이미지를 만들어보자
docker exec -it [container] bash
실행중인 도커 컨테이너에 접속하는 명령어이다.
실제 명령어를 보면 hash 값을 굳이 다 적지 않고 앞 3글자만 적었다. 이래도 알아서 접속이 된다!
echo 명령어를 통해 first라는 파일을 만들었다.
exit를 통해 컨테이너 밖으로 빠져나온 다음에 실행중인 컨테이너를 확인해본다.
나는 무엇을 한걸까?
ubuntu image로 컨테이너를 띄운 후, first라는 파일을 만들어 기존 image와 다른 변경사항을 만들어 냈다.
변경사항은 곧 Layer로 남길 수 있으며 commit을 통해 새로운 버전의 이미지를 생성할 수 있다.
docker commit -m "first commit" b65 ubuntu:0.1
commit을 했더니 commit ID를 알려주면서 끝난다.
이후 image 목록을 조회하니 ubuntu라는 이름을 갖는 image가 2개가 보인다.
TAG를 보면 하나는 latest, 그리고 내가 만든 0.1이 보인다. 둘 간의 Image ID는 다르며 만든 시각도 다르다.
ubuntu:latest에서 업데이트 된 ubuntu:0.1 이미지를 생성한것이다!
도커 이미지 특징
이미지로 컨테이너, 컨테이너로 이미지 생성을 둘다 해보았는데 꼭 알아야 하는점이 있다.
- 이미지는 불변(Immutable)이다. 이미지로 컨테이너를 생성하게 되면, 이미지는 그 즉시 읽기 전용이 되며 컨테이너에서 어떠한 작업을 수행해도 원래의 이미지는 변하지 않는다.
- 이미지는 Layer 구조다. 위의 예시에서 호스트 로컬 볼륨에 ubuntu:latest, ubuntu:0.1 두 개의 이미지가 있고 둘의 SIZE는 77.8MB로 똑같다. 하지만 1개의 Layer를 제외하곤 둘의 Layer가 전부 같으므로 ubuntu:0.1 이미지는 77.8MB의 SIZE를 차지하지 않고 1개의 Layer에 해당하는 볼륨만 차지한다.
즉, 여러 개의 태그를 갖는 이미지를 많이 가지고 있어도 공간 낭비를 하지 않을 수 있다. - 해당 이미지를 사용 중인 컨테이너가 존재하면 이미지를 삭제할 수 없다.
도커 컨테이너
위에서 도커 이미지와 컨테이너의 관계에 대해 알아보았다.
이번에는 컨테이너에 좀 더 집중해보자
컨테이너의 생성과 실행, 삭제
도커 컨테이너는 사실 생성과 실행 두 단계로 나뉘어져 있다.
docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker start [OPTIONS] CONTAINER [CONTAINER...]
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
docker rm [OPTIONS] CONTAINER [CONTAINER...]
create는 말 그대로 컨테이너 생성만 담당할뿐, 실행은 하지 않는다.
start는 생성된 컨테이너를 실행하는 명령어이다.
run은 create+start를 합친 느낌으로, 생성과 실행을 동시에 해준다. 보통 run을 많이 쓴다.
rm은 생성된 컨테이너를 삭제하는 명령어이다.
docker run
docker run -it my_image bash
docker run -it --name my_container my_image bash
docker run -it --name my_container -p 127.0.0.1:80/8080 -v ./:/etc/usr my_image bash
주요 옵션은 다음과 같다.
-i : 컨테이너의 표준 입력(stdin)을 활성화
-t : 컨테이너에 가상 터미널을 할당해 stdin을 전달할 수 있게 해준다.
-d : 컨테이너를 백그라운드로 실행(detach)
-p : 컨테이너에 포트 지정
-v : 컨테이너에 볼륨 지정
--name : 컨테이너에 이름을 지정
-it 옵션을 주지 않으면, 컨테이너는 stdin을 기다리지 않기 때문에 실행과 동시에 종료된다.
포트와 볼륨은 새로 나오는 개념인데, 뒤이어서 다룰 예정이다.
ARG로 전달된 bash는 컨테이너가 실행됐을 때 실행될 명령어를 의미한다.
docker rm
docke rm my_container
docke rm -f my_container
기본적으로 컨테이너 삭제는 종료된 컨테이너에만 유효하다.
만약 실행중인 컨테이너를 삭제하고 싶다면 -f 옵션을 주면 된다.
컨테이너 접속
정상적으로 실행한 컨테이너 내부에 접속하고 싶다면 어떻게 해야할까?
사실 접속이란건 컨테이너 내부에 있는 shell에게 명령어를 전달하는것과 같다.
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
docker exec
docker exec -it my_container bash
-it 옵션을 주어 stdin을 활성화 시키고, bash라는 shell과 통신하고 싶다는 뜻이다.
컨테이너 내부에 있는 shell에게 명령어 전달이 가능해진다.
주요 명령어들
docker logs
docker logs [OPTIONS] CONTAINER
컨테이너에서 실행되는 command들의 log를 볼 수 있다.
이때 -f 옵션을 주게 되면 실시간으로 볼 수 있다.
docker inspect
도커 Object들에 대한 정보를 볼 수 있다.
docker inspect [OPTIONS] NAME|ID [NAME|ID...]
docker rmi
docker rmi [OPTIONS] IMAGE [IMAGE...]
로컬에 있는 이미지를 삭제하는 명령어
Docker 명령어 레퍼런스
docker 명령어에 대한 더 자세한 정보는 아래 documentation을 참고하면 된다.
https://docs.docker.com/engine/reference/run/
Docker run reference
docs.docker.com
'Infra > Docker' 카테고리의 다른 글
[Docker] Docker Daemon (0) | 2023.06.27 |
---|---|
[Docker] Dockerfile (1) | 2023.05.20 |
[Docker] 도커 볼륨과 네트워크 (0) | 2023.05.19 |
[Docker] Docker란 무엇인가 (0) | 2023.05.18 |
[Docker] 도커 시작하기 (2) | 2023.04.05 |