도커 이미지와 컨테이너
도커 엔진에서 사용하는 기본 단위는 이미지와 컨테이너이며, 이 두 가지가 도커 엔진의 핵심입니다.
- 이미지에는 코드, 설정, 여러 것들이 포함되며 컨테이너는 그 이미지의 실행 인스턴스입니다.
- 이미지를 기반으로 컨테이너를 실행합니다.
도커 이미지
- 이미지는 실제로 코드와 코드를 실행하는데 필요한 도구를 포함한 것으로 컨테이너를 생성할 때 필요한 요소입니다.
- 여러 개의 계층으로 된 바이너리 파일이 존재하고, 컨테이너를 생성하고 실행할 때 읽기 전용으로 사용됩니다.
- 도커에서 사용하는 이미지의 이름은 기본적으로 [저장소 이름]/[이미지 이름]:[태그]로 구성됩니다.
- 저장소: 이미지가 저장된 장소를 의미(생략 가능)
- 이미지 이름: 이미지가 어떤 역할을 하는지 나타냅니다. 이미지는 생략할 수 없으며 반드시 설정해야 함
- 태그: 이미지 버전 관리에 사용(생략 가능)
- 태그를 입력하지 않으면 자동으로 lastest로 설정됩니다.
- 이미지는 컨테이너의 템플릿, 청사진이 됩니다.
- 이미지를 기반으로 하는 여러 컨테이너를 만들 수 있습니다.
- 이미지는 모든 설정과 명령 모든 코드가 포함된(템플린 코드와 애플리케이션 포함) 공유 가능한 패키지입니다.
도커 이미지 생성
공유된 이미지 사용하기
- 이미 구축되어 있는 공식 이미지나 커뮤니티에서 공유한 이미지를 사용할 수 있습니다.
아래와 같은 명령어를 사용했을 때 로컬에 해당 이미지가 없다면 도커 허브에서 이미지를 가져옵니다.
docker run node
commit을 이용한 이미지 생성
docker commit [options] <컨테이너> <이미지:태그>
ex) docker commit -a "raeyoung" -m "commet message" mycontainer mycontainer_image:1.1.1
- 저장소 이름은 입력하지 않아도 상관없지만 이미지 태그를 입력하지 않으면 자동으로 lastest로 설정됩니다.
-a
옵션은 author를 뜻하며 -m
옵션은 커밋 메시지를 뜻합니다.
Dockerfile을 이용한 이미지 생성
- 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 셸 스크립트 등을 하나의 파일에 기록한 파일을 Dockerfile이라고 합니다.
- Dockerfile을 사용하면 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거로움을 덜 수 있고, 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화할 수 있습니다.
- 생성한 이미지를 도커 허브 등을 통해 배포할 때 이미지 자체를 배포하는 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile을 배포할 수 있습니다.
애플리케이션을 컨테이너화 하기 위한 장기적인 시점에서 본다면 Dockerfile을 작성하는 것은 이미지를 생성하는 방법을 기록하는 것뿐만 아니랄 이미지 빌드, 배포 측면에서도 매우 유리합니다. 애플리케이션에 필요한 패키지 설치 등을 명확히 할 수 있고 이미지 생성을 자동화할 수 있으며, 쉽게 배포할 수 있기 때문입니다.
ex) Dockerfile
아래 소스는 자체 이미지를 빌드할 때 실행하려는 도커에 대한 명령이 포함됩니다.
FROM node
WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app/
EXPOSE 80
CMD ["node", "server.js"]
- FROM
- 생성할 이미지의 베이스가 될 이미지를 뜻합니다.
- Dockerfile을 작성할 때 반드시 한 번 이상은 입력해야 하며, 로컬에 사용하려는 이미지가 없다면 자동으로 pull 합니다.
- 다른 베이스 이미지에 이미지를 구축할 수 있습니다.
- WORKDIR
- 도커 컨테이너의 작업 디렉터리를 설정하는 것을 뜻합니다.
- COPY
- 로컬 머신에 있는 파일이 이미지에 들어가 있는지 알려야 합니다.
COPY <Host file sysyem> <Image/container file system>
COPY <도커파일이 포함된 동일한 폴더 경로> <파일을 저장해야 하는 이미지 내부의 경로> (ex: COPY . .)
- 기본적으로 두 개의 경로를 지정합니다.
- <도커 파일이 포함된 동일한 폴더 경로> 프로젝트의 모든 폴더 및 하위 폴더 파일을 복사한다는 의미입니다.
- <파일을 저장해야 하는 이미지 내부의 경로> 복사한 파일을 컨테이너 내부에 저장하는 경로를 의미하고 WORKDIR이 설정되어 있다면 WORKDIRD의 상대경로를 지정할 수 있습니다.
- RUN
- 이미지가 빌드될 때마다 실행됩니다.
- 명령을 실행합니다 ex) npm install
- WORKDIR가 설정되어 있지 않다면 기본적으로 컨테이너 루트 폴더를 실행합니다.
- CMD
- 이미지가 생성될 때 실행되는 것이 아니라 이미지를 기반으로 컨테이너가 실행될 때 실행됩니다.
- EXPOSE (사용 권장)
- 도큐먼테이션 목적으로만 추가되었기 때문에 컨테이너를 실행할 때 플래그를 추가해야 합니다.
docker run -p 3000:80 <이미지 ID>
docker run -p 3000:80 -d <이미지 ID>
옵션 d는 detached 모드로 실행합니다.
모든 이미지와 이미지를 기반으로 생성된 모든 컨테이너에는 로컬 머신의 파일 시스템에서 완전히 분리된 자체 내부 파일 시스템이 있습니다.
이미지 생성
docker build <도커파일이 있는 경로>
docker build -t <이미지 name:tag> <도커파일이 있는 경로>
이미지 목록 확인
docker images
이미지 레이어
이미지를 생성할 때 이미지는 캐시 되고 새로운 이미지를 사용할 때 캐시된 이미지를 사용합니다.
컨테이너에서 변경된 사항만 새로운 레이어로 저장하고, 그 레이어를 포함해 새로운 이미지를 생성합니다.
DockerHub에 이미지 푸시하기
- 도커 허브에서 레파지토리를 생성합니다.
- 도커 허브에 푸시할 이미지를 생성합니다.
docker build -t <new-ropo:tagname> <도커파일이 있는 경로>
(이미지 생성)
docker tag <기존 이미지네임>:<기존 tag> <new-ropo:tagname>
(새로운 이미지 이름으로 복제)
- 도커 로그인 후 푸시합니다
docker login
docker push new-repo:tagname
도커 이미지 삭제
이미지가 더 이상 컨테이너에서 사용되지 않고 중지된 컨테이너에 포함된 경우에만 이미지를 제거할 수 있습니다.
중지된 컨테이너가 있는 경우 컨테이너에서 사용 중인 이미지를 제거할 수 없기 때문에 먼저 컨테이너를 제거해야 합니다.
docker rmi <이미지 ID>
docker rmi <이미지 ID> <이미지 ID> (동시에 여러개의 이미지를 제거)
prune
은 사용되지 않는 이미지를 모두 제거합니다.
docker image prune
--rm
옵션은 컨테이너가 중지되면 컨테이너가 자동으로 제거합니다.
docker run --rm <이미지 ID>
도커 컨테이너
- 이미지로 컨테이너를 생성하면 해당 이미지의 목적에 맞는 파일이 들어있는 파일 시스템과 격리된 시스템 자원 및 네트워크를 사용할 수 있는 독립된 공간이 생성됩니다.
- 컨테이너는 이미지의 구체적인 실행 인스턴스입니다.
- 이미지를 기반으로 하는 컨테이너를 실행합니다.
- 독립된 파일시스템을 제공받으며 특정 컨테이너에서 어떤 애플리케이션을 설치하거나 삭제해도 다른 컨테이너와 호스트는 변화가 없습니다.
- 컨테이너는 이미지를 읽기 전용으로 사용하되 이미지에서 변경된 사항만 컨테이너 계층에 저장하므로 컨테이너에서 무엇을 하든지 이미지에는 영향을 받지 않습니다.
컨테이너 생성
run
pull, create, start 명령어를 일괄적으로 실행한 후 attach가 가능합니다.
- 이미지 기반으로 새로운 컨테이이너 생성하고 실행합니다.
docker run --name <컨테이너 이름 지정> <이미지 ID>
--name
옵션으로 컨테이너 이름을 지정할 수 있습니다.
docker run -i -t node
- 위 명령어는 컨테이너 생성 및 실행과 동시에 컨테이너 내부로 들어갑니다.
- -i -t 옵션을 줬을 때 attached 모드로 는 실행 중인 컨테이너에 연결되어 컨테이너의 출력 결과를 수신할 수 있습니다.)
이미지가 로컬 도커 엔진에 존재하지 않으면 도커 중앙 이미지 저장소인 도커 허브에서 자동으로 이미지를 내려받습니다.
- 컨테이너에서 기본 사용자는 root이고 호스트 이름은 무작위의 16진수 해시값으로 컨테이너의 공유한 ID의 일부분입니다.
- 컨테이너 내부에서 빠져나오는 방법
- 셸에서
exit
를 입력하고나 컨트롤 + D
를 동시에 입력합니다.
- 컨테이너를 정지하지 않고 빠져나오려면
컨트롤 + P, Q
를 입력합니다.
- pull 명령어는 이미지를 내려받을 때 사용됩니다.
docker pull node
create
도커 이미지를 pull 한 뒤에 컨테이너를 생성만 할 뿐 start, attach를 실행하지 않습니다.
- 컨테이너를 생성만 할 뿐 컨테이너 내부로 들어가지 않습니다.
docker create -i -t --name <컨테이너 이름> <이미지>
start & attach 컨테이너 내부로 들어가기
docker start <이미지 ID>
- docker start로 시작하는 경우 detached 모드가 디폴드입니다.
- detached모드에서 실행 중인 컨테이너에 연결되어 컨테이너의 출력 결과를 수신할 수 없습니다.
docker attach <이미지 ID>
컨테이너 목록 확인
- docker ps 명령어는 실행 중인 컨테이너만 출력합니다.
docker ps
는 실행 중인 컨테이너 목록을 확인할 수 있습니다.
컨트롤 + P, Q
를 입력해 빠져나온 실행 중인 컨테이너가 목록에 출력됩니다.
- 정지된 컨테이너를 포함한 모든 컨테이너를 출력하려면
docker ps -a
-a(all) 옵션을 추가합니다.
컨테이너 중지하기
docker stop <컨테이너 이름>
- 컨테이너 이름을 지정하지 않았다면 자동으로 컨테이너 이름이 할당됩니다.
중지한 컨테이너 재시작
docker start <컨테이너 ID>
or
doker start <컨테이너 ID> -a
- 이미 실행 중인 컨테이너 연결하기
docker attach <컨테이너 이름>
컨테이너 삭제
컨테이너는 실행이 중지된 컨테이너만 제거가 가능합니다.
docker rm <컨테이너 이름>
docker rm <컨테이너 이름> <컨테이너 이름> (여러개를 한번에 삭제)