도커 이미지는 실제로 파일 시스템 계층의 링크 된 목록입니다. Dockerfile의 각 명령어 는 해당 명령어 실행 전후에 파일 시스템의 차이점을 설명하는 파일 시스템 계층을 만듭니다. docker inspect
부속은 파일 시스템 계층의 링크 된리스트가되는 그 특성을 표시하는 고정 표시기 이미지를 사용할 수있다.
이미지에 사용 된 레이어 수는 중요합니다
- 동시 업로드 또는 다운로드 횟수에 영향을 미치므로 이미지를 밀거나 당길 때.
- 컨테이너를 시작할 때, 컨테이너에 사용되는 파일 시스템을 생성하기 위해 레이어들이 서로 결합 될 때; 계층이 많을수록 성능이 저하되지만 다른 파일 시스템 백엔드는 이로 인해 다른 영향을받습니다.
이것은 이미지를 어떻게 구축해야하는지에 대한 몇 가지 결과를 초래합니다. 내가 줄 수있는 가장 중요한 조언은 다음과 같습니다.
조언 # 1 소스 코드가 관련된 빌드 단계가 Dockerfile 에서 가능한 한 늦게 진행되고 a &&
또는 a를 사용하는 이전 명령과 연결되어 있지 않은지 확인하십시오 ;
.
그 이유는 이전의 모든 단계가 캐시되고 해당 계층을 반복해서 다운로드 할 필요가 없기 때문입니다. 이것은 더 빠른 빌드와 더 빠른 릴리즈를 의미하며, 아마도 당신이 원하는 것입니다. 흥미롭게도 도커 캐시를 최적으로 사용하는 것은 놀랍게도 어렵습니다.
두 번째 조언은 덜 중요하지만 유지 관리 관점에서 매우 유용합니다.
조언 # 2 Dockerfile에 복잡한 명령을 쓰지 말고 복사하고 실행할 스크립트를 사용하십시오.
Dockerfile 과 같을 것이다이 다음과 같은 사항을
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
COPY install_pacakges.sh /root/
RUN sh -x /root/install_packages.sh
등등. 여러 명령을 바인딩 &&
하는 데는 제한이 없습니다. 중복을 피하거나 문서화 목적으로 함수 등을 사용할 수있는 스크립트로 작성하는 것이 훨씬 쉽습니다.
사람들은 사전 프로세서 관심과로 인한 작은 오버 헤드를 피하기 위해 기꺼이 COPY
a를 온 - 더 - 플라이 단계를하고 실제로 생성하는 Dockerfile을 어디에
COPY apt_setup.sh /root/
RUN sh -x /root/apt_setup.sh
순서는
RUN base64 --decode … | sh -x
여기서는 …
base64로 인코딩 된 버전입니다 apt_setup.sh
.
세 번째 조언은 가능한 더 긴 빌드 비용으로 레이어의 크기와 수를 제한하려는 사람들을위한 것입니다.
조언 # 3with
-idiom을 사용하여 중간 계층에는 있지만 결과 파일 시스템에는없는 파일을 피하십시오.
일부 도커 명령어에 의해 추가되고 나중의 명령어에 의해 제거 된 파일은 결과 파일 시스템에 존재하지 않지만, 도커 이미지를 구성하는 도커 레이어에서 두 번 언급된다. 명령을 추가하면 레이어에 이름과 전체 내용이 한 번, 명령이 삭제되면 레이어에서 삭제 알림으로 한 번.
예를 들어, 일시적으로 C 컴파일러와 이미지가 필요하다고 가정하고
# !!! THIS DISPLAYS SOME PROBLEM --- DO NOT USE !!!
RUN apt-get install -y gcc
RUN gcc --version
RUN apt-get --purge autoremove -y gcc
(보다 현실적인 예는 단순히 --version
플래그로 그 존재를 주장하는 대신 컴파일러로 일부 소프트웨어를 빌드하는 것 입니다.)
Dockerfile 스 니펫은 세 개의 레이어를 생성합니다. 첫 번째 레이어에는 전체 gcc 제품군이 포함되어 있으므로 최종 파일 시스템에 존재하지 않더라도 해당 데이터는 여전히 동일한 방식으로 이미지의 일부이며 다운로드 할 때마다 다운로드, 업로드 및 언 패킹해야합니다. 최종 이미지입니다.
with
-idiom는 분리 자원 소유권과 자원을 이용하여 로직을 해제 함수형 프로그래밍의 일반적인 형태이다. 이 관용구를 쉘 스크립팅으로 바꾸는 것은 쉬우 며, Advice # 2COPY & RUN
에서 와 같이 이전 명령을 다음 스크립트로 바꿔서 사용할 수 있습니다 .
# with_c_compiler SIMPLE-COMMAND
# Execute SIMPLE-COMMAND in a sub-shell with gcc being available.
with_c_compiler()
(
set -e
apt-get install -y gcc
"$@"
trap 'apt-get --purge autoremove -y gcc' EXIT
)
with_c_compiler\
gcc --version
복잡한 명령을 기능으로 전환하여에 전달할 수 있습니다 with_c_compiler
. 여러 with_whatever
함수의 호출을 연결하는 것도 가능 하지만 그다지 바람직하지는 않습니다. (쉘의 좀 더 난해한 기능을 사용하면 with_c_compiler
복잡한 명령을 수락 하는 것이 가능 하지만 모든 측면에서 이러한 복잡한 명령을 함수로 래핑하는 것이 바람직합니다.)
Advice # 2를 무시하고 싶다면 결과 Dockerfile 스 니펫은
RUN apt-get install -y gcc\
&& gcc --version\
&& apt-get --purge autoremove -y gcc
난독 화로 인해 읽고 유지하기가 쉽지 않습니다. 셸 스크립트 변형이 중요한 부분 gcc --version
을 강조하는 반면 체인 &&
변형이 소음의 한 부분에 해당 부분을 묻는 방법을 참조하십시오 .