본문 바로가기
IT & 데이터 사이언스/Data Engineering

[Docker] Docker 엔진의 기본 단위와 컨테이너 생성, 삭제

by 바른 호랑이 2024. 7. 25.
728x90
반응형

안녕하세요. 바른호랑이입니다.

이번 게시글에서는 Docker 엔진의 기본단위와 컨테이너를 조작하는 방법에 대해서 알아볼 예정입니다.

게시글은 '시작하세요! 도커/쿠버네티스 친절한 설명으로 쉽게 이해하는 컨테이너 관리'를 기반으로 작성하였으니 참고 바랍니다.

Docker 엔진에서 사용하는 기본 단위는 이미지와 컨테이너입니다.

Docker 이미지는 컨테이너를 생성하는 데 필요한 요소로 가상머신 생성 시 사용하는 iso 파일과 비슷한 개념으로 여러 개의 계층으로 된 바이너리 파일이 존재하고, 컨테이너의 생성, 실행 시에 읽기 전용으로 사용됩니다. Docker 명령어로 다운로드가 가능하기에 별도로 설치할 필요는 없는 것이 특징이며, 기본적으로 '[저장소 이름]/[이미지 이름]:[태그]'의 형태로 구성되어 있습니다.

- 저장소(Repository) 이름은 이미지가 저장된 장소를 의미합니다. 이름이 명시되지 않은 이미지는 Docker에서 기본적으로 제공하는 이미지 저장소인 Docker Hub의 공식 이미지를 의미하며, 저장소 이름은 입력 필수 요건은 아니므로 생략하는 경우도 있습니다.

- 이미지 이름은 해당 이미지의 역할을 나타내며, 입력 필수 요건이기에 반드시 입력해주어야 합니다.

- 태그는 이미지의 버전 관리, 혹은 Revision 관리에 사용하며, 일반적으로 버전을 명시하지만 생략 시에는 default값으로 태그를 latest로 인식합니다.

 

Docker 이미지는 Ubuntu, CentOS 등과 같은 기본적인 리눅스 운영체제부터 Apache Web Server, MySQL과 같은 DB, Hadoop, Spark와 같은 빅데이터 분석 도구까지 다양한 종류가 있습니다. 이와 같은 이미지로 컨테이너를 생성하게 되면 해당 이미지의 목적에 맞는 파일이 들어 있는 파일시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간인 Docker 컨테이너가 생성됩니다. 

대부분의 Docker 컨테이너는 생성 시에 사용된 Docker 이미지 종류에 따라 각각의 설정과 파일을 가지고 있기에 Docker 이미지의 목적에 맞게 사용되는 것이 일반적입니다. 컨테이너는 이미지를 읽기 전용으로 사용하며, 이미지에서 변경된 사항만 컨테이너 계층에 저장하므로 컨테이너에서 수정을 해도 원본 이미지는 변경되지 않습니다. 각 컨테이너는 독립된 파일시스템을 제공받으며 호스트와 분리되어 있으므로 특정 컨테이너에서 애플리케이션을 설치 및 삭제해도 다른 컨테이너와 호스트는 변화가 없는 것이 특징입니다.

 

아래의 모든 과정은 VMware로 Ubuntu Server를 설치하고 VS Code로 ssh를 활용하여 접속 후 진행한 내용이니 참고 바라며, VMware를 활용하여 Ubuntu Server에 Docker를 설치하는 방법과 VS Code로 ssh를 활용하여 접속하는 방법은 아래의 게시글을 참고하기 바랍니다.

 

※ Ubuntu에 Docker 설치하기

 

[환경설정] Ubuntu에 Docker 설치하기

안녕하세요. 바른 호랑이입니다.이번 게시글에서는 Ubuntu OS에서 Docker를 설치하는 방법에 대해서 알아볼 예정입니다.일반적으로 도커의 기능을 완전하게 사용하려면 리눅스 OS에서 사용하는 것

data-is-power.tistory.com

※ VSCode Remote SSH 사용법

 

[환경설정] VSCode Remote SSH 사용법

안녕하세요. 바른호랑이입니다.이번 게시글에서는 VS Code를 기반으로 SSH를 사용하여 Linux 서버에 접근하는 방법에 대해서 알아볼 예정입니다.Linux가 설치된 가상머신(VM)이나 외부 컴퓨터를 접속

data-is-power.tistory.com

 

우선 도커에 사용하기에 앞서 설치한 도커 엔진 버전을 아래의 코드를 통해 확인합니다.

sudo docker -v

도커는 다양한 기능들이 빠르게 업데이트되고, 새로운 버전이 배포되므로 설치된 도커 버전을 확인하는 것은 매우 중요하며, 이는 호환성 문제와 이어지기에 새로운 PC나 서버에 도커를 설치해야 하는 상황이라면 버전을 반드시 확인하고 알맞게 설치하는 것이 필요합니다. 버전을 확인한 후에는 아래의 명령어를 활용하여 컨테이너 생성 테스트를 진행해 봅니다.

sudo docker run -i -t ubuntu:24.04

docker run 명령어는 컨테이너를 생성하고 실행하는 역할을 하며, '-i', '-t' 옵션은 컨테이너와의 상호 입출력이 가능하게끔 설정해줍니다. 만약 사용하고자 하는 이미지가 로컬 도커 엔진에 존재하지 않으면 도커 중앙 이미지 저장소인 도커 허브에서 자동으로 이미지를 다운로드하여 설치를 진행하며, 이는 네트워크 환경에 따라 시간이 소요될 수도 있습니다.

docker run 명령어를 사용했기에 위와 같이 별다른 추가 명령어 없이도 컨테이너 내부로 들어가게 되며, 별도로 유저와 hostname을 설정해주지 않았기에 기본 사용자인 root와 무작위 16진수 해시값이 hostname으로 사용됩니다.

생성 시 사용한 옵션 중 '-i' 옵션은 상호 입출력 활성화를, '-t' 옵션은 tty를 활성화하여 bash shell을 사용할 수 있게 해주는 옵션으로 둘 중 하나라도 사용하지 않으면 shell을 정상적으로 사용할 수 없습니다. 생성 후에 ls 명령어를 실행시켜 파일시스템을 확인해 보면 아무것도 설치되지 않은 상태임을 알 수 있습니다.

컨테이너의 생성과 동작이 정상적으로 되는 것을 확인했다면 이제 컨테이너를 빠져나와야 하는데 'ctrl+d'를 입력하여 컨테이너를 빠져나오면서 종료까지 하는 방법과 'ctrl+p+q' 또는 'ctrl+p', 'ctrl+q'를 차례로 입력하여 종료는 하지 않고 빠져나오기만 하는 방법 중 필요한 방법을 사용하면 됩니다. 다만 VS Code의 경우 'ctrl+p+q' 또는 'ctrl+p', 'ctrl+q'를 차례로 입력하는 방법의 경우 이미 시스템에서 설정한 단축키가 존재하여 작동하지 않을 수 있으며, 이 경우에는 'run' 또는 'attach' 명령어로 컨테이너에 진입 시에 '--detach-keys="{키 조합}"' 옵션을 사용하여 별도로 escape sequence를 실행시킬 수 있게 설정하면 됩니다.

단, --detach-keys를 사용 시에는 기존의 default 설정인 'ctrl+p+q' 또는 'ctrl+p', 'ctrl+q'를 차례로 입력하는 방법으로는 escape sequence를 실행할 수 없고 설정한 key로만 사용 가능하니 필수적인 단축키들이 아닌 키 조합으로 단축키를 설정해야 하며, 별도의 추가 설정을 진행하지 않으면 일회성인 것을 유의해야 합니다.

# detach-keys 옵션 사용 예시(run)
sudo docker run -i -t --detach-keys="ctrl-x" ubuntu:24.04

# detach-keys 옵션 사용 예시(attach) 
sudo docker attach {container name} --detach-keys="ctrl-x"

ubuntu 서버 직접 접속 후 ctrl+p+q로 컨테이너에서 빠져나오는 예시
직접 detach-keys를 설정후 해당 단축키로 빠져나오는 예시(1)
직접 detach-keys를 설정후 해당 단축키로 빠져나오는 예시(2)

만약 도커에서 로컬 환경에 설치된 이미지의 종류들을 확인하거나 삭제하고 싶다면 아래의 명령어를 활용할 수 있습니다. 단, 이미지를 삭제하기 위해서는 해당 이미지를 사용하는 컨테이너가 없어야 합니다.

# 설치된 이미지 확인
sudo docker images

# 설치된 이미지 삭제
sudo docker rmi {REPOSITORY}:{TAG}

설치된 이미지 확인 및 삭제

위에서는 컨테이너 생성을 위해 run 명령어를 사용하여 생성과 동시에 컨테이너에 진입하였습니다. 만약 진입은 안 하고 컨테이너 생성만 해야 하는 상황이면 run 명령어를 사용해서는 안되며, 이 경우 create 명령어를 사용하여 컨테이너 생성만 진행하는 것도 가능합니다. 생성 시에 출력되는 16진수 해시값은 컨테이너의 고유 ID이며, 값 자체가 너무 길기에 해당 값을 사용할 경우 일반적으로는 앞의 12자리만 사용합니다. 만약 컨테이너의 전체 ID를 확인해야한다면 docker inspect 명령어를 사용하면 되며, '--name' 옵션을 통해 해당 컨테이너의  이름을 설정할 수도 있습니다. 

# create container
sudo docker create -i -t --name ubuntu00 ubuntu:24.04

# check full container ID
sudo docker inspect ubuntu00

 

Create 명령어를 활용하여 생성된 컨테이너는 바로 실행되지 않으며 해당 컨테이너를 사용하기 위해서는 start명령어로 컨테이너를 실행시키고 attach 명령어를 통해 컨테이너에 접속해야 합니다. 컨테이너를 대상으로 하는 명령어는 일반적으로 컨테이너 이름 또는 ID를 활용하며, ID의 경우 모든 ID값을 입력할 필요 없이 앞자리 3~4자만 입력해도 접속이 가능합니다. 다만 앞자리가 동일한 다른 컨테이너가 여러 개 존재하면 에러가 발생하므로 해당 사항은 유의해야 합니다.

run과 create 명령어의 차이

컨테이너에 명령을 하기 위해 필요한 컨테이너 이름을 외우고 있으면 좋겠지만, 컨테이너의 수와 종류가 다양해지면 해당 사항은 불가능할 수밖에 없습니다. 이 경우에는 컨테이너 목록을 확인하여 각 컨테이너마다 가지고 있는 정보를 확인하는 것이 필요하며 목록 확인을 위해서는 ps 명령어를 사용하면 됩니다. 다만 ps 명령어는 현재 실행 중인 컨테이너만 보여주는 것이 기준이기에 종료된 컨테이너까지 전부 보기 위해서는 '-a' 옵션을 추가해주어야 합니다.

# print container list(default)
sudo docker ps

# print container list(all)
sudo docker ps -a

- CONTAINER ID

: 컨테이너에게 자동으로 할당되는 고유한 ID로 ps 명령어로는 일부분만 확인이 가능하며 전체 값을 확인하기 위해서는 inspect 명령어를 사용해야 합니다.

- IMAGE

: 컨테이너를 생성할 때 사용한 이미지의 이름입니다.

- COMMAND

: 컨테이너가 시작될 때 실행될 명령어로 커맨드는 대부분의 이미지에 미리 내장되어 있기에 별도로 설정할 필요가 없습니다. 위의 예시에서는 별도로 설정하지 않아 "bin/bash" 명령어가 들어간 모습이며, 명령어 맨 끝에 별도로 입력하여 실행 시 명령어를 변경할 수 있습니다.

# 예시: 컨테이너 실행시에 echo hello world!를 실행하도록 설정
# 아래와 같이 설정하면 상호 입출력 가능한 쉘이 실행되지 않고, hello world!만 출력하고 컨테이너가 종료됨.
sudo docker run -i -t ubuntu:24.04 echo hello world!

- CREATED

: 컨테이너가 생성되고 난 뒤 흐른 시간을 나타냅니다.

- STATUS

: 컨테이너의 상태를 나타내며, 실행중일 때는 'Up', 종료되었을 때는 'Exited', 일시 중지된 상태일 때는 'Pause'로 나타내는 것이 대표적입니다.

- PORTS

: 컨테이너가 개방한 포트와 호스트에 연결된 포트를 나열합니다. 

- NAMES

: 컨테이너의 고유한 이름으로, '--name' 옵션으로 이름을 설정하지 않으면 도커 엔진이 임의로 형용사와 명사를 무작위로 조합해 이름을 설정합니다. 컨테이너 이름은 ID와 마찬가지로 중복될 수는 없지만 docker rename 명령어를 사용하면 컨테이너의 이름을 변경할 수 있습니다. 추가적으로 ps 명령어는 '--format' 옵션을 사용하여 원하는 것들만 출력할 수도 있습니다.

# sudo docker rename {기존 이름} {변경할 이름}
sudo docker rename ubuntu01 ubuntu02

# format 사용예시
sudo docker ps -a --format "table {{.ID}}\t{{.Status}}\t{{.Image}}"

format 사용 예시

컨테이너 삭제는 rm 명령어를 사용하며, 한 번 삭제한 컨테이너는 복구할 수 없으므로 삭제 시에는 반드시 삭제해야 하는 것인지를 꼭 확인해야 합니다. 단, 실행 중인 컨테이너는 '-f' 옵션을 주어야하며, 만약 해당 조건 없이 실행 중인 컨테이너를 삭제하는 명령어를 사용하면 에러가 발생합니다.

# 컨테이너 삭제
sudo docker rm ubuntu02

# 사용중인 컨테이너 강제 삭제
sudo docker rm -f ubuntu00

만약 생성되어 있는 컨테이너 중 종료된 컨테이너를 하나하나 지우는 것이 아니라 한꺼번에 지우고 싶다면 prune 명령어를 사용하면 됩니다. 다만 prune 명령어의 경우 실행중인 컨테이너들은 삭제를 하지 않으므로, 실행중인 것까지 전부 삭제하고 싶은 경우에는 ps 명령어와 옵션으로 전체 컨테이너의 ID값을 불러온 후 변수화하여 rm -f 명령어로 삭제하면 됩니다.

# 정지된 컨테이너 전체 삭제
sudo docker container prune

# 컨테이너 ID 변수화 후 전체 삭제
sudo docker rm -f $(sudo docker ps -a -q)

prune명령어로 정지된 컨테이너 전체 삭제
컨테이너 ID 변수화 후 전체 컨테이너 삭제

 

728x90
반응형

댓글