책 : 시작하세요! 도커/쿠버네티스 (개정판)을 이용한 Docker스터디 3W 주간 내용 정리
2.3 도커 이미지
당연히 기본적으로 docker search를 수행하면, 공식 Docker저장소인 도커 허브 "https://hub.docker.com/" 의 정보가 조회된다. docker search ubuntu→docker search docker.io/ubuntu 수행하는 것과 같은 결과를 제공한다.
- tag부분은 유동적으로 사용 (미 사용시 latest로 설정됨) - 제일 중요한 부분은 container이름을 적는 것이다. - a 옵션은 author의 의미이다. - m 옵션을 message 의미이다.
여기서 눈여겨볼 사항은 대상을 정할때, images명이 아닌 Container를 기준으로 한다는 점이다.!! commit을 할때, 기준이 Container가 된다.
commit을 통해서 다양한 tag버전을 생성할 수 있다.
- 2.3.2 이미지 구조 이해
엔진의 구성요소 : 컨테이너 → 이미지 + 레이어
여기서 Read Only속성의 이미지의 이해를 조금 더 해본다.
실습으로 확인해본 Layer항목
ubuntu기반으로 만들어진 이미지를 보면 당연히 예상한대로 증분을 통해서 기존의 사항(Layer)는 동일한 hash값을 가지고 있다.
<명령어> 1. docker history 이미지:tag // 이미지 레이어 구조를 파악하기 2. docker rm -f [container name] // 이미지 레이어는 실제 삭제 안되고 이미지 이름만 삭제됨 3. docker rmi [container_name]. // 이미지 레이어 삭제 4. docker images -f dangling=true // 사용중인 이미지 삭제시 이미지 이름이 <none>으로 변경되는 것 조회
- 2.3.3 이미지 추출
이미지를 별도로 저장하거나 이동할때 사용하는 방법
해당 방법은 효율적인 방법이 아닙니다.
위에서 언급된 Layer구조를 통한 용량관리에 대한 장점이 없습ㄴ디ㅏ.
용량을 각기 차지하게 됩니다.
> docker save -o [추출파일명] [대상컨테이너이름] 실행한 명령어 위치에 생성됨
> docker load -i ubuntu_14_04.tar 생성한 이미지를 다시 로드
save / load : container이미지 + 컨테이너 생성시 detached모드, 컨테이너 설정등도 다 포함
export / import : container 이미지 정보만 대상으로 합니다.
save로 추출한 파일을 import로 수행해서 동작시켜본 화면
실행은 정상적으로 되었음
- 2.3.4 이미지 배포
2가지 방법이 있습니다. DockerHub이용하는 방법 / 도커 사설 레지스트리를 사용하는 방법
① 공식 DockerHub를 이용하는 방법
public : 갯수 제한 없음 (대외 공개 필수)
private : 1개는 무료 제공 (추가 사용은 유료 결제가 필요함)
② 도커 사설 레지스트리 (Docker Private Registry)
사용자가 직접 이미지 저장소를 만드는 과정
- 2.3.4.1 도커 허브 저장소
docker pull을 수행시, 자동으로 host cpu 아키텍처에 해당하는 이미지를 자동으로 처리 (ex : amd64)
도커 엔진은 Dockerfile을 읽을 때 기본적으로 현재 디렉토리에 있는 Dockerfile 파일을 선택합니다.
- 2.4.1 이미지를 생성하는 방법 - 2.4.2 Dockerfile 작성
파일명을 Dockerfile이 아닌 dockerfile로 작성을 하여도 정상 작동은 한다.
Dockerfile 작성
명령어를 소문자로 작성해도 무관하지만, 관례적으로 대문자로 표기한다.
아래 예시에서 RUN, RUN, WORKDIR, RUN으로 수행한 이유가 있다.
cd역활을 하는 WORKDIR을 통해서 경로이동 후, 다음 작업을 진행하기 때문이다.
FROM ubuntu:14.04 → 이미지 이름을 의미함 (docker run에서 사용했던 동일한 이미지를 뜻함) → 이미지가 없으면 pull로 땡겨옴
MAINTAINER alicek106 → 이미지를 생성한 개발자 정보 → docker 1.13.0이후에는 사용하지 않음 → LABEL을 대신해서 사용함 → LABEL maintainer "alicek106 <aaaa@gmail.com>"
LABEL "purpose"="practice" → 이미지에 메타데이터를 추가합니다. → 키:값 형태로 입력 → docker inspect에서 출력되는 정보
RUN apt-get update RUN apt-get install apache2 -y → 이미지를 만들기 위해서 컨테이너 내부에서 명령어 실행 → Y/N옵션에 대해서 -y로 인자값 전달 ADD test.html /var/www/html → 파일을 이미지에 추가합니다. → 원본 파일을 Dockerfile이 있는 위치에서 조회합니다.
WORKDIR /var/www.html → 명령어를 실행할 디렉토리를 나타냄 → shell에서 cd와 같은 역활 RUN ["/bin/bash", "-c", "echo hello >> test2.html"] → RUN ["실행가능한 파일", "명령줄 인자1", "명령줄 인자2", ....] → Json형태로 구성함
EXPOSE 80 → 이미지에서 노출할 포트를 설정 → 단지 컨네이너가 해당 포트를 사용하는것을 나타내는 역활 → container run 수행시, 모든 노출된 컨테이너의 포트를 host에 퍼블리시 하는 -P 플래그와 함께 사용함 CMD apachectl -DFOREGROUND → container가 시작될때 마다 실행할 명령어 이다. → Dockerfile에서 한번만 사용이 가능하다 → Json형태로 ["실행간으한 파일", "명령줄 인자 1", "명령줄 인자 2", ....] 형태도 가능
- 2.4.3 Dockerfile 빌드
실습
build 명령어 사용
-t 옵션을 사용하지 않으면, 16진수 이름의 형태로 이미지가 저장되므로 -t옵션 사용하기
./ : 경로를 현재 폴더를 지정하였지만, 외부 경로를 사용할수도 있음
해당 시점은 이미지를 생성만 한 상태입니다. 아직 run 상태가 아닙니다.
생성된것 run하고 label로 검색 해보기
mac에서 80 port를 사용중이라서 접속이 안될것으로 생각된다.
여기 예시에서 -P는 대문자이다
이전에 port설정은 -p 소문자였다.
책에서는 -P옵션에 대해서 "EXPOSE로 노출된 포트를 호스트에서 사용가능한 포트에 차례로 연결하므로 이 컨테이너가 호스트의 어떤 포트와 연결되었는지 확인이 필요함" 설명하고 있습니다.
ADD 말고COPY 명령어도 있음
/ (root) 위치에서 이미지 빌드를 하지 않아야 합니다.
하위 디렉토리의 내용까지 전부 포함됩니다.
.dockerignore 파일
.gitignore와 같은 역활이며, build시 제외해야 할 파일을 정의합니다.
*.html → .html확장자를 가지는 모든 파일 */*.html → 디렉토리 구분을 의도한것 (위 예시는 1개의 디렉토리를 의미) → */*/*.html : 디렉토리 2개를 거치고 마지막이 *.html을 의미함 test.htm? → ?는 한자리 문자열을 의미함 → ??
각 명령어 1개마다 새로운 컨테이너가 생성됩니다. (중요한 개념)
Dockerfile이름이 아닌 다른 이름의 파일을 이용하려고 할때, 지정하는 옵션 -f
같은 폴더에 Dockerfile, Dockerfile2 2개가 있는경우, 의도한 파일로 지정하는 것입니다.
-f 가 force의 의미는 아니고, file의 의미입니다.
cache관련
--no-cache : 소스 영역등에 자주 변경되는 경우 cache 처리를 사용하지 않는 옵션
--cache-from : 특정 저장소에 대해서는 cache를 사용하는 것
- 2.4.3.3 멀티 스테이지를 이용한 Dockerfile빌드하기
간단한 go를 이용한 "hello world"를 출력하는데, 많은 용량을 차지힌다.
Multi-Stage 빌드 방법
여러개의 FROM이미지를 정의해서, 최종적으로 생성된 이미지를 줄이는 방법
아래와 같이 FROM을 2개 이상으로 구성
go에 build에 필요한 alpine(필수적인 런타임 요소가 포함된 리눅스 배포판)을 이용해서 구성