2장. 도커 엔진
2.3 도커 이미지
도커 이미지
- 기본적으로 도커 허브라는 중앙 이미지 저장소에서 이미지를 내려받음
- 도커 허브
- 도커에서 공식적으로 제공하는 이미지 저장소
- 다른 사람들과 이미지를 쉽게 공유
- private 저장소를 사용할려면 요금 지불
- docker search 명령어
도커 이미지 생성
- docker commit 명령어
- 특정 이미지로부터 변경 사항이 있는 컨테이너를 이미지로 생성
- 이미지 태그를 입력하지 않으면 자동으로 lastest로 설정
이미지 구조 이해
- docker inspect 명령어
- Layers
- 16진수 해시값
- 각 이미지에 대한 inspect 명령어의 출력 결과
- docker commit으로 생성된 이미지
- 이미지 레이어 + 컨테이너 레이어
- 컨테이너를 커밋할 때, 기존 이미지 레이어 재사용
- docker rmi
- 이미지 삭제
- 이미지를 사용 중인 컨테이너가 존재하면 해당 이미지는 삭제할 수 없음
- 댕글링(dangling)
- 컨테이너가 사용 중인 이미지를 rmi -f로 강제로 삭제하면 이미지의 이름이 none으로 변경
- 댕글링 이미지
- 해당 이미지를 기반으로 하는 하위 이미지가 존재하면 이미지를 삭제해도 해당 이미지 레이어 파일이 삭제되지 않음
- 실제 이미지 파일을 삭제하지 않고 부여된 이름만 삭제
- Untagged
- 하위 이미지가 존재하지 않으면 이미지 레이어가 삭제
이미지 추출
- docker save 명령어
- 도커 이미지를 별도로 저장하거나 옮기는 등 필요에 따라 이미지를 바이너리 파일로 저장
- 컨테이너의 커맨드, 이미지 이름과 태그 등 이미지의 모든 메타데이터를 포함해 하나의 파일로 추출
- -o
- docker load 명령어
- save 명령어로 추출된 이미지를 로드하면 이전의 이미지와 완전히 동일한 이미지가 도커 엔진에 생성
이미지 배포
- 이미지 추출은 도커 이미지 구조인 레이어 형태를 이용하지 않음
- 도커 허브 이미지 저장소
- 도커 이미지를 저장하기 위한 클라우드 서비스
- docker push
- docker pull
- 조직(Organizations), 팀(Teams)
- 도커 사설 레지스트리
- 사용자가 직접 만드는 이미지 저장소
- 내부망과 같은 곳에서 도커 이미지 배포할 때 사용
- 사설 레지스트리 컨테이너
- ${Private-registry-ip}:[Port]/[Image-name]:[Version]
- --insecure-registry
- HTTPS를 사용하지 않는 레지스트리 컨테이너에 이미지 push, pull 허용
- Nginx 서버로 접근 권한 생성
- 사설 레지스트리 RESTful API
- 사설 레지스트리 옵션 설정
- 이미지 삭제뿐만 아니라 스토리지 백엔드, 이미지 레이어 파일이 저장될 디렉토리, 웹훅 설정
- /etc/docker/registry/config.yml을 통해 환경변수 설정 가능
2.4 Dockerfile
이미지를 생성하는 방법
- build 명령어
- 일련의 과정을 손쉽게 기록하고 수행
- 완성된 이미지를 생성하기 위해 컨테이너에 설치해야 하는 패키지, 추가해야 하는 소스코드, 실행해야 하는 명령어와 셸 스크릡트 등 하나의 파일에 기록
- Dockerfile
- 직접 컨테이너를 생성하고 이미지로 커밋해야 하는 번거로움을 덜 수 있음
- 깃과 같은 개발 도구를 통해 애플리케이션의 빌드 및 배포를 자동화 가능
- 생성한 이미지를 도커 허브 등을 통해 배포할 때, 이미지 대신 이미지를 생성하는 방법을 기록해 놓은 Dockerfile 배포 가능
- 컨테이너에서 작업 후 커밋하는 방법보다 이미지를 생성하는 방법을 기록하는 방법이 빌드, 배포 측면에서 유리
Dockerfile 작성
- Dockerfile 명령어
- FROM
- 생성할 이미지의 베이스가 될 이미지
- 반드시 한 번 이상 입력
- 사용하려는 이미지가 도커에 없다면 자동으로 pull
- MAINTAINER
- 이미지를 생성한 개발자 정보
- 이메일
- 도커 1.13.0 버전 이후로 사용하지 않음
- LABEL로 교체
- LABEL
- 이미지에 메타데이터 추가
- key-value 구조
- docker inspect 명령어로 확인
- RUN
- 이미지를 만들기 위해 컨테이너 내부에서 실행할 명령어
- 이미지를 빌드할 때 별도의 입력을 받아야 하는 RUN은 build 명령어는 오류 발생
- ADD
- 파일을 이미지에 추가
- Dockerfile이 위치한 디렉토리
- 특정 위치에서 이미지로 파일을 복사
- 복사하려는 대상 파일이 압축 파일인 경우, 해당 파일 압축을 해제하여 복사
- wget 등 원격 파일을 복사 대상으로 지정 가능
- COPY
- WORKDIR
- 명령어를 실행할 디렉토리
- bash shell에서 cd 명령어와 동일
- EXPOSE
- Dockerfile의 빌드로 생성된 이미지를 노출할 포트 설정
- -p 플래그와 함께 사용
- CMD
- 컨테이너가 시작될 때마다 실행할 명령어 설정
- Dockerfile에서 한 번만 사용할 수 있음
- -d 옵션을 사용
- docker run 명령어 인자가 존재하면 CMD는 run 명령어로 덮임
- ENTRYPOINT
Dockerfile 빌드
- 이미지 생성
- docker build -t [Image-name]/[Version][Path]
- -t
- 생성될 이미지 이름 설정
- 사용하지 않으면 16진수 형태 이름으로 저장
- Path
- docker run
- -P
- EXPOSE로 노출된 포트를 호스트에서 사용 가능한 포트에 차례로 연결
- docker images
- 이미지 빌드 과정
- 빌드 컨텍스트 로드
- 이미지 생성하는 데 필요한 각종 파일, 소스코드, 메타데이터 등을 담고 있는 디렉토리
- Dockerfile이 위치한 디렉토리
- Dockerfile에서 빌드될 이미지에 파일을 추가할 때 사용
- ADD, COPY
- 컨텍스트는 build 명령어의 맨 마지막에 지정된 위치에 있는 파일 전부 포함
- 하위 디렉토리도 전부 포함
- Dockerfile이 위치한 곳에는 이미지 빌드에 필요한 파일만 있는 것이 바람직
- .dockerignore 파일
- Dockerfile을 이용한 컨테이너 생성과 커밋
- 이미지를 만드는 것이 하나의 컨테이너에서 일어나는 것이 아님
- ADD, RUN 등 명령어가 실행될 때마다 새로운 컨테이너가 하나씩 생성되며 이를 이미지로 커밋
- Dockerfile에서 명령어 한 줄이 실행될 때마다 이전 step에서 생성된 이미지에 의해 새로운 컨테이너 생성되고 명령어를 수행하고 다시 새로운 이미지 레이어로 저장
- 빌드 과정에서 명령어 줄 수만큼 컨테이너가 생성되고 삭제
- 캐시를 이용한 이미지 빌드
- 한 번 이미지 빌드를 마치고 난 뒤 다시 같은 빌드를 진행하면, 이전에 이미지 빌드에서 사용했던 캐시 사용
- 이전에 빌드했던 Dockerfile에 같은 내용이 있으면 build 명령어는 새로 빌드하지 않고 이전에 이미지 레이어를 활용
- --no-cache 옵션 사용
- 멀티 스테이지
- 이미지의 크기를 줄이기 위해 사용하는 빌드 방법
- 하나의 Dockerfile 안에 여러 개의 FROM 이미지를 정의
- 최종적으로 생성될 이미지의 크기를 줄이는 역할
- 반드시 필요한 실행 파일만 최종 이미지 결과물에 포함시킴으로써 이미지 크기를 줄일 수 있음
기타 Dockerfile 명령어
- ENV
- VOLUME
- 빌드된 이미지로 컨테이너를 생성했을 때 호스트와 공유할 컨테이너 내부 디렉토리 설정
- ARG
- build 명령어를 실행할 때 추가로 입력 받아 Dockerfile 내에서 사용될 변수 값 설정
- --build-arg
- USER
- 컨테이너 내에서 사용될 사용자 계정의 이름이나 UID 설정하면 그 아래의 명령어는 해당 사용자의 권한으로 실행
- Onbuild
- 빌드된 이미지를 기반으로 하는 다른 이미지가 Dockerfile로 생성될 때 실행할 명령어
- Stopsignal
- 컨테이너가 정지될 때 사용될 시스템 콜 종류 지정
- Healthcheck
- 이미지로부터 생성된 컨테이너에서 동작하는 애플리케이션의 상태를 체크하도록 설정
- --interval
- Shell
- ADD
- COPY
- ENTRYPOINT
- 커맨드를 인자로 받아 사용할 수 있는 스크립트 역할
- run 커맨드는 entrypoint에 대한 인자 기능
- CMD
Dockerfile로 빌드할 때 주의할 점
- 좋은 습관
- 가독성을 위해 역슬래시 사용
- 이미지 레이어로 파일은 삭제되어도 용량 차지
- docker export, import
2.5 도커 데몬
도커의 구조
- 도커 명령어 위치
- 도커 엔진 프로세스 파일
- /usr/bin/dockerd
- docker 명령어가 실제 도커 엔진이 아닌 클라이언트의 도커
- 도커 구조
- 클라이언트
- 도커 데몬은 API를 입력 받아 도커 엔진 기능 수행
- 도커 클라이언트는 API를 사용할 수 있도록 CLI(Command Line Interface) 제공
- docker로 시작하는 명령어를 입력하면 도커 클라이언트를 사용하는 것
- 도커 클라이언트는 도커 데몬에게 API로서 전달
- 도커 클라이언트는 /var/run/docker.sock에 위치한 유닉스 소켓을 통해 도커 데몬의 API 호출
- 서버
- 실제로 컨테이너를 생성하고 실행
- 이미지를 관리
- dockerd 프로세스로서 동작
- 도커 엔진
- 외부에서 API 입력을 받아 도커 엔진 기능 수행
- 도커 데몬
- 도커 프로세스가 실행되어 서버로서 입력을 받을 준비가 된 상태
도커 데몬 실행
- 도커 서비스는 dockerd로 도커 데몬 실행
도커 데몬 설정
- 도커 설정 파일
- 도커 데몬 제어
- -H
- IP와 포트 번호를 입력하면 원격 API인 Docker Remote API로 도커 제어할 수 있음
- 도커 데몬 보안 적용
- --tlsverify
- TLS 보안 적용
- ca.pem, server-cert.pem, server-key.pem, cert.pem, key.pem 파일 필요
- 도커 스토리지 드라이버 변경
- 특정 스토리지 백엔드 기술을 사용해 도커 컨테이너와 이미지를 저장하고 관리
- --storage-driver
- 스토리지 드라이버 변경
- 스냅숏
- 원본 파일은 읽기 전용으로 사용
- 해당 파일이 변경되면 새로운 공간을 할당
- Copy-on-Write(CoW)
- 스냅숏 파일에 쓰기 작업 수행할 때 스냅숏 공간에 원본 파일을 복사 후 쓰기 요청
- 오버헤드 발생
- Redirect-on-Write(RoW)
- 파일을 스냅숏 공간에 복사하는 것이 아니라 스냅숏에 기록된 원본 파일을 묶은 뒤 변경된 사항을 새로운 장소에 할당받아 덮어쓰는 방식
- AUFS 드라이버
- Devicemapper 드라이버
- OverlayFS 드라이버
- Btrfs 드라이버
- ZFS 드라이버
- 컨테이너 저장 공간 설정
- 컨테이너 내부에서 사용되는 파일시스템의 크기는 도커가 사용하고 있는 스토리지 드라이버에 따라 다름
도커 데몬 모니터링
- 도커 데몬 디버그 모드
- events
- 도커가 기본으로 제공하는 명령어
- 도커 데몬에 어떤 일이 일어나고 있는지를 실시간 스트림 로그로 보여줌
- 도커 클라이언트에서 입력하는 모든 명령어가 출력되는 것이 아니라 컨테이너, 이미지, 볼륨, 네트워크, 플러그인 관련 명령어 수행 결과 출력
- state
- 실행 중인 모든 컨테이너의 자원 사용량을 스트림으로 출력
- 실행 중인 모든 컨테이너의 CPU, 메모리 제한 및 사용량, 네트워크 입출력, 블록 입출력 정보 출력
- system df
- 도커에서 사용하고 있는 이미지, 컨테이너, 로컬 볼륨의 총 개수 및 사용 중인 개수, 크기, 삭제함으로써 확보 가능한 공간 출력
- CAdvisor
- 구글에서 만든 컨테이너 모니터링 도구
- 컨테이너별 실시간 자원 사용량 및 도커 모니터링 정보 등 시각화해서 보여줌
- 도커 데몬의 정보를 가져올 수 있는 호스트의 모든 디렉토리를 CAdvisor 컨테이너 볼륨으로 마운트
Remote API 라이브러리를 이용한 도커 사용