방법
docker run -d httpd
docker exec -it id bash
웹컨텐츠는 /usr/local/apache2/htdocs 있음
echo "<h1>hello world!</h1>" > index.html
vagrant@docker ~ docker commit --help
Usage: docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
vagrant@docker ~ docker commit 컨테이너이름 myhttpd(생성할 이미지이름)
sha256:59bbcc0fc00c7b1717c12298aa1279f883ade402322469e0bab192d8e0c41668
vagrant@docker ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
myhttpd latest 59bbcc0fc00c 3 seconds ago 144MB
...
vagrant@docker ~ docker run -d -p 80:80 myhttpd
76d3bc12e27541bada2ad47483131f067ef8920db75fed50b24fc6e20c57b068
docker diff id
비교대상군은 이미지
✘ vagrant@docker ~ docker diff 8f
C /root
A /root/.bash_history # bash의 명령어를 실행했기 때문에
C /usr
C /usr/local
C /usr/local/apache2
C /usr/local/apache2/logs
A /usr/local/apache2/logs/httpd.pid
# 아파치 프로세스의 ID가 저장되는 파일, 커널이ㅣ 관리 프로세스 ID가 몇번이지 기록 -> 항상 바뀌거나 생성
C /usr/local/apache2/htdocs # 파일 속성바뀌면 위에위에 다 영향을 받음
C /usr/local/apache2/htdocs/index.html #변경한 내용, 파일 속성 바뀜
root@8fbaa302aea5:/usr/local/apache2# cd icons
root@8fbaa302aea5:/usr/local/apache2/icons# rm a.gif
root@8fbaa302aea5:/usr/local/apache2/icons# exit
exit
vagrant@docker ~ docker diff 8f
...
D /usr/local/apache2/icons/a.gif
...
A=add, C=change, D=delete
기준 이미지 <-> 컨테이너 차이
docker cp
를 활용하기vagrant@docker ~ docker cp --help
Usage: docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|- # 컨테이너에서 호스트로 복사
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH # 호스트에서 컨테이너로
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
76d3bc12e275 myhttpd "httpd-foreground" 18 minutes ago Up 18 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp peaceful_babbage
docker cp 76:/usr/local/apache2/conf/httpd.conf ./httpd.conf
# 파일의 Listen 80 -> Listen 8080
docker cp ./httpd.conf 76:/usr/local/apache2/conf/httpd.conf
docker commit id myhttpd:p8080(tag)
docker run -d -p 80:8080 myhttpd:p8080
-c
옵션을 사용
docker commit -c "CMD=~~" id
docker run -itd ubuntu
docker exec -it NAME bash
# 아파치 설치
docker commit -c 'CMD /usr/sbin/apachectl -DFOREGROUND' [NAME] [images name you want]
systemctl이 없기 때문에 아파치를 실행하는 명령어를 직접 사용하여 실행
centos는 /usr/bin/httpd -DFOREGROUND
CMD의 항목이
/usr/sbin/apachectl -DFOREGROUND
만 있는게 아니라
/bin/sh # 셸로
-c # 뒤에 문자열을 셸이 실행하도록 하는 옵션
/usr/sbin/apachectl -DFOREGROUND # 를 실행하겠다
로 되어 있음
ExposedPorts
가 없음ExposedPorts 는 사용자에게 제공되는 정보로 실제 작동과는 연관이 없음
EX)
"ExposedPorts": {
"80/tcp": {}
},
이더라도 실제 서비스가 80포트에서 이뤄진다고 확신 할 수 없음 -> httpd.conf의 Listen의 영향을 받음
ExposedPorts
는 필요하다면 설정가능docker commit -c "CMD /usr/sbin/apachectl -DFOREGROUND" -c "EXPOSE 80/TCP" ID IMAGENAME:TAG
이미지는 전부 RO -> 이미지를 가지고 컨테이너를 생성하면 컨테이너는 레이어를 하나 더 얹음(RW) -> 컨테이너가 됨 -> 변경한 데이터는 이 새로만든 레이어에 저장 -> 명령어를 가지고 커밋
--> 결론은 이미지지를 사용해 컨테이너를 만들면 RW 레이어가 추가되어 컨테이너가 되고, commit으로 이미지를 생성하게 되면 RW 레이어가 RO 레이어로 변경되어 합쳐져 이미지가 됨
docker inspect id
해서 보면 아래와 같은 항목에서
LowerDir
의 첫 번째줄은 RO 레이어
두 번째 줄은 RW 레이어
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/~~~~:
/var/lib/docker/overlay2/~~",
}
레이어에서 파일 하나 지우면 레이어를 지웠다는 정보를 가진 레이어를 만들어서 결합 -> 지워진 파일이 보이지 않게 됨
이미지 레이어를 상세하기 보기 위한 명령어
docker history, docker image history
vagrant@docker ~ docker history httpd
IMAGE CREATED CREATED BY SIZE COMMENT
c30a46771695 2 weeks ago /bin/sh -c #(nop) CMD ["httpd-foreground"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) EXPOSE 80 0B
<missing> 2 weeks ago /bin/sh -c #(nop) COPY file:c432ff61c4993ecd… 138B
<missing> 2 weeks ago /bin/sh -c #(nop) STOPSIGNAL SIGWINCH 0B
<missing> 2 weeks ago /bin/sh -c set -eux; savedAptMark="$(apt-m… 60.6MB
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PATCHES= 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_SHA256=d0bbd112… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_VERSION=2.4.53 0B
<missing> 2 weeks ago /bin/sh -c set -eux; apt-get update; apt-g… 2.63MB
<missing> 2 weeks ago /bin/sh -c #(nop) WORKDIR /usr/local/apache2 0B
<missing> 2 weeks ago /bin/sh -c mkdir -p "$HTTPD_PREFIX" && chow… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV PATH=/usr/local/apach… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ENV HTTPD_PREFIX=/usr/loc… 0B
<missing> 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:8b1e79f91081eb527… 80.4MB
missing -> 로컬 저장소에 없다
사용했던 명령어들이 적혀져있음
저장소 및 네트워크 전송 효율성 높임
레이어를 분리 시키면 동일한 레이어가 있는경우는 해당되는 레이어를 받지 않아도 됨 -> 중복된 레이어는 별도로 저장할 필요가 없음
파일을 분리하여 저장할 수 있음
변경될일이 없을거 같으면 한번에 파일을 저장하는게 효율적
변경이 될거같으면 면 레이어 분리시키는게 효율적
커밋한번당 레이어 한번
docker export
컨테이너 -> 아카이브
docker export <CONTAINER> -o <TARFILE>
docker save는 이미지를 아카이브 하는 명령어
docker import
아카이브 -> 이미지
docker import <TARFILE> <IMAGE>:<TAG>
TIP! 1개의 레이어로 가져오기
하나의 레이어로 만들고싶으면 export하고 import하면 하나의 레이어로 가지고 올 수 있음
docker load는 docker save에 의해 생성된 아카이브를 이미지로 가져오는 명령어
docker import 는 docker export에 의해 생성된 아카이브를 이미지로 가져오는 명령어
https://docs.docker.com/engine/reference/builder/
파일명은 Dockerfile
로 정해져 있음
docker build . 를 통해 도커파일에 정의 된대로 이미지를 빌드하게 됨
.은 경로 현재디렉토리
❗❗ 도커파일을 /에 만들지 않기->현재 디렉토리 밑에 전부 이미지로 만들어서 루트에 하면 루트시스템을 전부 다 만들어버림
-t
옵션으로 태그를 지정할 수 있음
이름이 여러개라면 -t 를 여러개 만들면 됨
# Comment
INSTRUCTION arguments
새로 빌드할 이미지의 베이스 이미지 지정, 컨테이너를 띄울 베이스 이미지를 지정
FROM <image>
FROM <image>[:<tag>]
FROM <image>[@<digest>]
플랫폼은 x86 x86장비인데 amd 용 이미지는 불가
latest는 안써야함
AS name 별칭 -> 따로 상황이 있음
이미지를 만들때 이미지를 빌드할때 FROM에서 베이스이미지를 지정할때, 베이스이미지를 지정하고 이미지를 빌드할때 실행할 명령어
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
docker run -d httpd
docker stop ~~ -> 금방 종료가 돔
docker start ~~
docker stop ~~
time docker stop ~~ -> 1.5 초 정도걸림
docker inspect ~~ 보면 State라는 항목 status exited, ExitCode 0 정상종료
컨테이너 중지 -> 프로세스 종료 프로세스를 정상적으로 종료시켜야 리턴코드가 0
RUN ["/bin/bash", "-c", "echo hello"]
docker run -d myweb
docker stop ~~
docker start ~~
time docker stop ~~ 10초가 걸림
docker inspect ~~ 상태를 보면 ExitCode 137
쌍따음표만 가능❗
프로세스의 정상종료는
X창누르면 15번 시그널이 전송 됨 SIGTERM (kill -l 로 확인) = 정상 종료 시그널
15번 시그널을 보냈을때 정상종료 -> 부모프로세스에 리턴코드를 보냄
stop 은 15번 시그널 전송 시키는 것
httpd-fore~ httpd가 직접받음 httpd가 제대로 받고 정상 종료
/bin/sh ~~ 은 셸이 직접받음 -> 15번 시그널 무시 -> apache에 보내야하는데 무시해서 아무작업을 안함
도커는 10초동안 응답이 안오면 9번시그널을 보냄 -> 어떤 프로세스도 무시 불가 137-128=9
9번으로 종료시킨 것
RUN은 shell form, CMD, ENTRYPOINT는 exec form
shell form은 하위 프로세스에게 시그널을 전달하지 않기 때문에
빌드시 실행할 명령
Shell Form
RUN yum install httpd
=> /bin/sh -c yum install httpd
Exec Form
RUN ["yum", "install", "httpd"]
=> exec yum install httpd
exec는 명령 X
기본 실행 어플리케이션
Shell Form
CMD /usr/sbin/httpd -DFOREGROUND
=> /bin/sh -c yum install httpd
Exec Form(선호)
CMD ["/usr/sbin/httpd", "-DFOREGROUND"]
외부에 노출할 포트 및 프로토콜
EXPOSE <PORT>/<PROTOCOL>
쉘 환경 변수
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
도커 호스트 -> 컨테이너 파일 복사
ADD <SRC> <DEST>
COPY <SRC> <DEST>
호스트에 있는 게 소스 -> 컨테이너로 복사
ADD는 SRC로 URL 지정 가능
CMD의 명령으로 사용
ENTRYPOINT | CMD | Result |
---|---|---|
X | X | 허용X |
X | abc | abc |
xyz | X | xyz |
xyz | abc | xyz abc |
ENTRYPOINT가 CMD보다 먼저❗
ls -l
을 사용할 때 ENTRYPOINT를 ls
로 설정하고 CMD를 -l
로 설정하면 옵션을 바꾸고 싶을 때 CMD의 내용만 변경하기
자동으로 마운트할 볼륨 마운트 포인트 지정
VOLUME /myvol
작업 디렉토리
RUN
, CMD
, ENTRYPOINT
, ADD
, COPY
에 영향을 미침
WORKDIR /usr/local
RUN
, ADD
, COPY
레이어를 만듦
mkdir -p ~/image-build/myweb
cd ~/image-build/myweb
Dockerfile
FROM centos:7
RUN yum install -y httpd
ADD index.html /var/www/html/index.html
CMD ["/usr/sbin/httpd", "-DFOREGROUND" ]
EXPOSE 80/tcp
index.html
hello dockerfile
docker build -t myweb:centos .
/etc/localtime
파일이 가리키고 있는 파일이 시간대
시간대
/usr/share/zoneinfo/*
sudo ln -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
sudo timedatectl
ubuntu 20.04/focal 이미지 부터 시간대가 설정되어 있지 않음
우회: ENV DEBIAN_FRONTEND=noninteractive
timezone을 세팅하는 패키지
도커파일 빌드 시 타임존 설정을 미리 하는 방법
DEBIAN_FRONTEND=noninteractive apt install tzdata
이렇게하면 넘어가짐
ls -sf /usr/share/zoneinfo/Asia/Seoul /etc/localtime
apt install -y apache2
FROM ubuntu:focal
RUN apt update
RUN DEBIAN_FRONTEND-noninteractive apt install tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Seoul /ect/localtime
RUN apt install -y apache2
ADD index.html /var/www/html/index.html
EXPOSE 80/tcp
진행하게 되면 경고가 나옴
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
apt는 안정적인 CLI 인터페이스가 아니다 스크립트 사용시 주의해라
처음부터 apt존재하진 않았음
apt-get은 처음부터 존재한 명령어
apt-get install 하고 검색할때는
apt0cache search 명령어가 다 다름
apt-~~~ 명령어 분리되어 있어서 귀찮음 -> 그래서 만든게 apt 명령어
자주쓰는 명령어만 뽑아온거
apt 다른거의 100 가져온거아니고 일부 주요한 기능들만 가져왔고
일부기능만 있을수있으니까 경고를 주는것
도커파일 베스트 프렉티스
https://docs.docker.com/develop/develop-images/dockerfile_best-practices/