Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- 코딩테스트실력진단
- BOJ1655
- 웹개발기초
- 운영체제
- 이것이자바다
- 백준9012
- 가운데를말해요
- 냅색알고리즘
- 윤곽선검출
- 백준가운데를말해요
- 스파르타코딩클럽
- 이것이자바다확인문제
- java
- 딥러닝
- 백준스택
- 확인문제
- BOJ
- 코드트리
- 코테
- 2019카카오코테
- 백준괄호
- 백준10828
- 컴퓨터비전
- 합성곱연산
- KT포트포워딩
- 백준평범한배낭
- 카카오코테
- 이것이자바다9장
- 백준온라인저지
- 백준
Archives
- Today
- Total
코딩하는 락커
섹션2. Docker이미지 & 컨테이너: 코어 빌딩 블록 본문
이미지 & 컨테이너: 무엇이며, 왜 사용하는가?
도커의 2가지 기초 개념


- 컨테이너
- 애플리케이션, 웹사이트, 노드 서버, 애플리케이션을 실행하는 전체 환경 등을 포함하는 작은 패키지
- 소프트웨어 실행 유닛이 존재하여 그 유닛이 실행됨
- 이미지의 구체적인 실행 인스턴스, 즉 실행 애플리케이션이 됨
- 이미지
- 템플릿, 컨테이너의 청사진
- 모든 설정 명령과 모든 코드가 포함된 공유 가능한 패키지
- 이미지를 사용하여 이를 기반으로 한 여러 컨테이너를 만들 수 있음
이미지와 컨테이너의 관계
- 컨테이너에 설치된 이미지는 컴퓨터에서 실행되는 것이 아니라 컨테이너 내부에 설치되고 실행됨
- 이미지는 run 명령어를 사용하여 이미지의 인스턴스를 만들고, 이 이미지를 기반으로 하는 구체적인 컨테이너를 생성함
- 즉 컨테이너는 이미지의 인스턴스가 됨
- 두개의 컨테이너가 동시에 실행될 수 있음
이미지를 사용하는 2가지 방법

- 이미 존재하는 이미지를 가져오는 방법
- 이미 개발된 이미지
- 미리 구축된 공식 이미지
- https://hub.docker.com/ 등에서 공식 개발 팀에서 배포, 생성, 유지, 관리되는 이미지
- 커스텀 이미지를 만드는 방법
- 공식 이미지 베이스를 가져온 다음 그 위에 코드를 추가하여 그 이미지로 개발한 코드를 실행
- 개발한 코드는 도커 허브에 공유해야함
커스텀 이미지로 nodeJS 앱 만들기 실습
- Dockerfile 생성

- DockerFile 작성
# FROM: 다른 베이스 이미지에 커스텀 된 이미지를 구축할 수 있음
# node: 현재 시스템에 존재하거나 도커 허브 사에 존재하는 이미지 이름
# (위에서 node 도커 허브 이미지를 실행했을 때 node 이미지가 로컬로 다운로드 및 캐시 되었으므로)
# (이 이미지를 기반으로 컨테이너를 실행한 순간 로컬 컴퓨터에도 존재함)
# node라는 이름의 이미지가 존재하며, 도커가 이를 찾을 수 있다는 것을 의미함
FROM node
# WORKDIR: 도커 컨테이너의 작업 디렉토리 설정
# 이곳에 /app을 넣게 되면 이후로부터 도커에게 내리는 모든 후속 명령이 /app 폴더에서 실행될 것을 알림
WORKDIR /app
# 도커에게 로컬 컴퓨터에 있는 파일이 이미지에 들어가야 한다고 알려줌
# 첫번째 .: 이미지로 복사되어야 할 파일들이 있는 곳의 경로를 작성하는 곳
# 이곳에 .을 넣으면 도커에게 기본적으로 Dockerfile이 포함된 동일한 폴더임을 알림 (DockerFile은 제외)
# 이 프로젝트의 모든 폴더, 하위 폴더 및 파일을 복사해야 한다는 것을 의미함
# 두번째 .: 그 파일을 저장해야 하는 이미지 내부의 경로를 작성하는 곳
# 모든 이미지와 이미지를 기반으로 하는 컨테이너에는 로컬 컴퓨터와 분리된 자체 내부 파일 시스템이 존재
# /app: 도커 컨테이너의 루트 엔트리를 사용하는 것이 아니라 서브 폴더 /app을 만들어서 사용하겠다는 것을 알림
# 이렇게 되면 DockerFile과 동일한 폴더에 있는 모든 파일 및 하위 폴더가 컨테이너 내부의 app 폴더에 복사됨
# .: 현재는 위에서 작업 디렉토리를 설정했으므로 현재 도커 작업 디렉토리를 의미하는 ./으로 작성가능
# /app: 이런식으로 명시적으로 절대 경로를 작성할 수도 있음
COPY . /app
# RUN: 도커 컨터이너에 필요한 종속성을 설치하는 등의 명령어 수행가능
# node에 필요한 nmp 설치하라는 것을 의미함
RUN npm install
# EXPOSE: 로컬 컴퓨터에 도커 컨테이너의 특정 포트를 노출하는 명령어
# 도커 컨테이너는 로컬 컴퓨터와 분리되어 있고 자체 내부 네트워크도 분리되어 있음
# 컨테이너 내부의 노드 애플리케이션에서 포트 80을 수신할 때 로컬로 노출해 달라는 의미
EXPOSE 80
# CMD: 이미지가 생성될 때 실행되는 것이 아니라 이미지를 기반으로 컨테이너가 시작될 때 실행하라는 명령어
# 이미지를 기반으로 한 컨테이너가 생성될 때마다 컨테이너 내부에 있는 node 명령어를 사용하여 server.js 파일을 실행하라는 의미
# 만약 cmd로 특정하지 않으면 베이스 이미지가 실행되며, 없는 경우 에러가 발생함
CMD ["node", "server.js"]
- 도커 이미지 빌드
// docker build: 도커 이미지를 빌드하는 명령어
// build 뒤에 .을 입력하여 도커에게 이 명령을 실행하는 곳과 동일한 폴더에 dockerfile이 있음을 알림
// (--platform arm64: ARM64 Mac을 사용하여 해당 플랫폼에 맞게 빌드)
$ docker build --platform amd64 .
- 도커 컨테이너 실행
$ docker run {이미지_id}
- 그러나 localhost에서 웹 사이트가 표시되지 않는 것을 확인
- 현재 실행중인 프로세스 보기
// -a 옵션 없이 ps만 붙이면 현재 실행중인 프로세스만 표시됨
$ docker ps
- 컨테이너 이름으로 도커 컨테이너 종료
$ docker stop {컨테이너_이름}
- 도커 포트 80에 엑세스 할 수 있는 로컬 컴퓨터 포트를 추가하여 도커 실행
$ docker run -p {로컬 컴퓨터 포트}:{도커 컨테이너 노출 포트} {이미지_id}
이미지는 읽기 전용
- 이미지는 읽기 전용이므로 소스 파일이 변경되면 도커 이미지를 새롭게 빌드해야 함
이미지 레이어 이해하기
- 이미지는 레이어 기반 아키텍처로 이루어져 있음
- 즉, 이미지를 빌드하거나 이미지를 다시 빌드할 때 변경된 부분의 명령과 그 이후의 모든 명령이 재평가 됨
- 프로젝트 변경 없이 이미지를 빌드 시 매우 빠르게 완료 되는데, 그 이유는 캐쉬를 사용했기 때문임
- 도커는 도커 파일을 사용하여 이미지를 빌드 했을 때 결과가 이전과 동일하다는 것을 인식하고, 이를 빌드 하는 것이 아니라 캐쉬 함
- 이미지 레이어는 Dockerfile의 명령어를 기반으로 하여 생성됨
- FROM, WORKDIR, COPY, RUN 등 CMD 명령어 이전의 명령어는 별도의 레이어가 됨
- 그리고 이미지를 기반으로 컨테이너를 실행하면, Dockerfile 명령어를 기반으로 한 이미지 레이어 위에 새로운 레이어를 추가함
- 이렇게 되면 이미지를 레이어로 실행할 때만 활성화 되는 최종 레이어가 추가됨
- 한 레이어가 변경된다면 후속 레이어도 다시 실행됨
- 코드 파일이 변경되어 COPY 레이어가 변경되면, 그 이후의 RUN 레이어도 다시 실행됨
- 그러나 이것은 node를 재설치 하는 것은 불필요한 작업임
- 따라서 아래 코드와 같이 Dockerfile을 최적화 할 수 있음
FROM node
WORKDIR /app
# package.json 파일을 app 폴더에 복사하고
COPY package.json /app
# 그 후에 RUN npm install을 실행하는 것
# 따라서 소스 코드가 변경되어도 npm install은 캐시된 결과를 사용함
# 따라서 재빌드 할 때도 속도가 빠름
RUN npm install
COPY . /app
EXPOSE 80
CMD ["node", "server.js"]
이미지 & 컨테이너 관리
- 모든 도커 명령어에 --help를 추가하여 사용 가능한 모든 옵션을 볼 수 있음
컨테이너 중지 & 재시작
- 실행중인 컨테이너 리스트 보기
$ docker ps
- 모든 컨테이너 리스트 보기
$ docker ps -a
- 중지된 컨테이너 시작하기
- 그러나 즉시 종료 됨
# 컨테이너 리스트 검색 명렁어로 중지된 컨테이너를 검색하고
$ docker ps -a
# 찾은 컨테이너의 이름으로 컨테이너 시작
$ docker start {컨테이너_이름/컨테이너_ID}
Attached & Detached 컨테이너 이해하기
- $ docker start 로 실행시 실행이 되나 즉시 종료됨
- 하지만 여전히 실행 중임
- $ docker run 명령어로 실행할 경우 (다른 포트를 사용하여 동일한 이미지를 기반으로 새로운 추가 컨테이너 실행) 이 프로세스에서 막혀서 더 이상의 명령어를 입력할 수 없음)
- $ docker start 는 background에서 실행되고, $ docker run은 foreground에서 실행되는 것
- $ docker start 는 dettached 모드가 default
- $ docker run 은 attached 모드가 default
- attached 모드: 컨테이너의 출력 결과를 수신
- $ docker run을 dettached 모드로 실행하는 방법
$ docker run -p {로컬 컴퓨터 포트}:{도커 컨테이너 노출 포트} -d {이미지_id}
- $ docker start을 attached 모드로 실행하는 방법
$ docker start -a {컨테이너_이름/컨테이너_id}
- dettached 모드로 실행중인 컨테이너를 보는 방법
$ docker attached {컨테이너_이름/컨테이너_id}
- 컨테이너의 로그를 보는 방법
$ docker logs {컨테이너_이름/컨테이너_id}
# 컨테이너 로그를 Follow 모드로 실행하여 계속 수신 대기
$ docker logs -f {컨테이너_이름/컨테이너_id}
인터렉티브 모드로 들어가기
- 컨테이너의 표준 입력을 열린 상태로 실행
# -i: 컨테이너를 인터렉티브 모드로 시작하여 표준 입력을 열린 상태로 유지하는 옵션
# -t: 컨테이너의 터미널을 생성하여 노출하는 옵션
$ docker run -i -t {컨테이너_이름/컨테이너_id}
- 컨테이너를 dettached 모드에서 표준 입력을 열린 상태로 실행
# -i: 컨테이너를 인터렉티브 모드로 시작하여 표준 입력을 열린 상태로 유지하는 옵션
# -a: 출력 결과를 계속 수신하게 하는 옵션
$ docker start -a -i {컨테이너_이름/컨테이너_id}
이미지 & 컨테이너 삭제하기
- 컨테이너 삭제하기
$ docker rm {컨테이너_이름/컨테이너_id}
- 이미지 삭제하기
도커 명령어
// Docker hub에서 찾은 공식 노드 이미지를 사용하여 이 이미지를 기반으로 하는 컨테이너를 생성하는 명령어
$ docker run node
// ps: 프로세스
// -a: 도커가 생성한 모든 컨테이너, 모든 프로세스가 표시됨
$ docker ps -a
// -it: 도커에게 컨테이너 내부에서 호스팅 머신으로 대화형 세션을 노출하고 싶다고 알리는 것
// 실제로 기본 노드 명령을 실행할 수 있는 언터렉티브 노드 터미널로 들어가 실행중인 노드와 상호작용 가능
$ docker run -it node
'🐳 도커와 쿠버네티스' 카테고리의 다른 글
섹션 7: "유틸리티 컨테이너"로 작업하기 & 컨테이너에서 명령 실행하기 (0) | 2022.08.02 |
---|---|
섹션 6: Docker Compose: 우아한 다중 컨테이너 오케스트레이션 (0) | 2022.07.26 |
섹션 5: Docker로 다중 컨테이너 애플리케이션 구축하기 (0) | 2022.07.13 |
섹션4: 네트워킹: (교차) 컨테이너 통신 (0) | 2022.07.06 |
섹션3. 데이터 관리 및 볼륨으로 작업하기 (0) | 2022.06.29 |
Comments