DevOps/Docker

[Docker] docker commit 명령을 이용하여 이미지 빌드하기

TTOII 2022. 5. 10. 23:55
728x90

✔️ Docker 이미지 빌드

https://jungeeyou.github.io/docker-3-post/

방법

  • docker commit 명령
  • Dockerfile

✔️ 명령으로 이미지 생성하기

우선 컨테이너를 띄운다.

 vagrant@docker  ~  docker run -d httpd
2b0edf3314a92f329e117f8e706732afcd108b882d97ca704d89108d861193ee

 vagrant@docker  ~  docker exec -it 2b bash
root@2b0edf3314a9:/usr/local/apache2# pwd
/usr/local/apache2
root@2b0edf3314a9:/usr/local/apache2# cd htdocs/
root@2b0edf3314a9:/usr/local/apache2/htdocs# ls
index.html
root@2b0edf3314a9:/usr/local/apache2/htdocs# echo "<h1> hello world </h1>" > index.html
root@2b0edf3314a9:/usr/local/apache2/htdocs# cat index.html
<h1> hello world </h1>
root@2b0edf3314a9:/usr/local/apache2/htdocs# exit
exit

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED              STATUS              PORTS     NAMES
2b0edf3314a9   httpd     "httpd-foreground"   About a minute ago   Up About a minute   80/tcp    modest_hopper

 vagrant@docker  ~  docker diff 2b
C /usr
C /usr/local
C /usr/local/apache2
C /usr/local/apache2/logs
A /usr/local/apache2/logs/httpd.pid # httpd 프로세스의 id가 저장되는 파일 (커널 관리 파일) 프로세스 id가 몇번인지 기록한다. 
                                    # 항상 바뀌고 생성되는 파일이다. 
C /usr/local/apache2/htdocs
C /usr/local/apache2/htdocs/index.html # 실질적으로 내용을 변경한 부분 
                                       # 파일을 변경하면 파일의 속성이 변경되며 상위 디렉토리로 연쇄적으로 영향을 준다.
C /root # 그 부모의 디렉토리가 같이 변경됨 
A /root/.bash_history # 아예 파일이 생성이 된 것 

 

✔️ docker diff

docker diff <CONTAINER>

: Linux의 diff command와 같다.
기준 이미지와 커스텀한 컨테이너 사이의 변경 내역을 출력한다.

  • A : add
  • C : change
  • D : delete

✔️ 예시

 vagrant@docker  ~  docker exec -it 2b bash
root@2b0edf3314a9:/usr/local/apache2# ls
root@2b0edf3314a9:/usr/local/apache2# cd icons/
root@2b0edf3314a9:/usr/local/apache2/icons# ls
root@2b0edf3314a9:/usr/local/apache2/icons# rm a.gif
root@2b0edf3314a9:/usr/local/apache2/icons# exit
exit

 vagrant@docker  ~  docker diff 2b
C /usr
C /usr/local
C /usr/local/apache2
C /usr/local/apache2/icons
D /usr/local/apache2/icons/a.gif # 삭제되었음
C /usr/local/apache2/logs
A /usr/local/apache2/logs/httpd.pid
C /usr/local/apache2/htdocs
C /usr/local/apache2/htdocs/index.html
C /root
A /root/.bash_history
 vagrant@docker  ~ 

 

✔️ docker commit

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

CMD 변경

docker commit -c "CMD XXX" CONTAINER [REPOSITORY[:TAG]]

ExposedPort 변경

docker commit -c "EXPOSE PORT/PROTOCOL" CONTAINER [REPOSITORY[:TAG]]

ExposedPort는 실제 작동여부와 상관 X

✔️ 예시

 vagrant@docker  ~  docker commit 2b myhttpd
sha256:26cb7321f015df26cd4cb244983776f200777370a5f56df5b4910018c473e011

 vagrant@docker  ~  docker images
REPOSITORY                           TAG        IMAGE ID       CREATED         SIZE
myhttpd                              latest     26cb7321f015   3 seconds ago   144MB
 vagrant@docker  ~  docker run -d -p 80:80 myhttpd
28294f64fab4a1b941587629b0945b08dd876d94a3af46f37a06120428f75ac6

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                               NAMES
28294f64fab4   myhttpd   "httpd-foreground"   4 seconds ago    Up 3 seconds    0.0.0.0:80->80/tcp, :::80->80/tcp   charming_kapitsa
2b0edf3314a9   httpd     "httpd-foreground"   10 minutes ago   Up 10 minutes   80/tcp                              modest_hopper

 

✔️ docker cp

컨테이너에서 도커 호스트로 파일 옮기기

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-

도커 호스트에서 컨테이너로 파일 옮기기

docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

 

✔️ 예시

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS          PORTS                                   NAMES
2b0edf3314a9   httpd     "httpd-foreground"   25 minutes ago   Up 25 minutes   80/tcp                                  modest_hopper

 vagrant@docker  ~  docker cp 2b:/usr/local/apache2/conf/httpd.conf ./httpd.conf
 vagrant@docker  ~  ls
centos7  centos7.tar  contents  hello-world.tar  httpd.conf
 vagrant@docker  ~  vi httpd.conf

 vagrant@docker  ~  docker cp ./httpd.conf 2b:/usr/local/apache2/conf/httpd.conf

 vagrant@docker  ~  docker diff 2b
C /usr
C /usr/local
C /usr/local/apache2
C /usr/local/apache2/conf
C /usr/local/apache2/conf/httpd.conf
C /usr/local/apache2/htdocs
C /usr/local/apache2/htdocs/index.html
C /usr/local/apache2/logs
A /usr/local/apache2/logs/httpd.pid
C /usr/local/apache2/icons
D /usr/local/apache2/icons/a.gif
C /root
A /root/.bash_history

  vagrant@docker  ~  docker commit 2b myhttpd:p8080
sha256:25293436b34bd32e5c4c1e116e9908591b34699a354d4e375a69cbe2ff8428e0

 vagrant@docker  ~  docker run -d -p 80:8080 myhttpd:p8080
d40bc6f4a8a6350bfddedaab67dc02bdd64a9a84e25e67a6f05eeea02380239a

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE           COMMAND              CREATED         STATUS        PORTS                                           NAMES
d40bc6f4a8a6   myhttpd:p8080   "httpd-foreground"   2 seconds ago   Up 1 second   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp   distracted_faraday
 vagrant@docker  ~ 

 

✔️ -c 옵션으로 실행할 CMD 변경하기

-c 옵션을 이용해서 실행할 CMD를 변경할 수 있다.

 

우리가 apache 서비스를 실행시키기위해 systemctl start httpd 명령을 실행하면 실제로는
/usr/lib/systemd/system/httpd.service의 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND가 변경되는 것이다.

[vagrant@controller ~]$ cat /usr/lib/systemd/system/httpd.service
[Unit]
Description=The Apache HTTP Server
After=network.target remote-fs.target nss-lookup.target
Documentation=man:httpd(8)
Documentation=man:apachectl(8)

[Service]
Type=notify
EnvironmentFile=/etc/sysconfig/httpd 
ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND # 여 라인이 실행된다.
ExecReload=/usr/sbin/httpd $OPTIONS -k graceful
ExecStop=/bin/kill -WINCH ${MAINPID}
# We want systemd to give httpd some time to finish gracefully, but still want
# it to kill httpd after TimeoutStopSec if something went wrong during the
# graceful stop. Normally, Systemd sends SIGTERM signal right after the
# ExecStop, which would kill httpd. We are sending useless SIGCONT here to give
# httpd time to finish.
KillSignal=SIGCONT
PrivateTmp=true

[Install]
WantedBy=multi-user.target

직접 실행하는 방법

[vagrant@controller ~]$ sudo /usr/sbin/httpd -DFOREGROUND &

이것을 이용하면 Base Image를 이용해 apache를 실행할 수 있는 이미지로 빌드할 수 있다.

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE           COMMAND              CREATED          STATUS          PORTS                                           NAMES
263cbeebea4e   centos:7        "/bin/bash"          8 minutes ago    Up 8 minutes                                                    loving_kapitsa
d40bc6f4a8a6   myhttpd:p8080   "httpd-foreground"   41 minutes ago   Up 41 minutes   80/tcp, 0.0.0.0:80->8080/tcp, :::80->8080/tcp   distracted_faraday
 vagrant@docker  ~  docker exec -it 26 bash
[root@263cbeebea4e /]# yum install httpd 
[root@263cbeebea4e /]# cd /var/www/html
[root@263cbeebea4e html]# ls
[root@263cbeebea4e html]# echo "<h1> hello centos </h1>" > index.html
[root@263cbeebea4e html]# ls
index.html
[root@263cbeebea4e html]# cat index.html
<h1> hello centos </h1>
[root@263cbeebea4e html]# exit
exit
 vagrant@docker  ~  docker commit -c "CMD /usr/sbin/httpd -DFOREGROUND" 26 myapache:v1
sha256:8c3ec12e434fdee3f97f58899ad5b520cde3aa5f1b9289ca46b7ebd856b0b4ff
 vagrant@docker  ~  docker images
REPOSITORY                           TAG        IMAGE ID       CREATED             SIZE
myapache                             v1         8c3ec12e434f   3 seconds ago       402MB
myhttpd                              p8080      25293436b34b   43 minutes ago      144MB
myhttpd                              latest     26cb7321f015   About an hour ago   144MB
ubuntu                               latest     d2e4e1f51132   10 days ago         77.8MB
mysql                                5.7        8aa4b5ffb001   12 days ago         462MB
wordpress                            5-apache   b44d413c437a   2 weeks ago         606MB
wordpress                            latest     b44d413c437a   2 weeks ago         606MB
httpd                                latest     c30a46771695   2 weeks ago         144MB
centos                               7          eeb6ee3f44bd   7 months ago        204MB
ghcr.io/c1t1d0s7/network-multitool   latest     802404fc76df   14 months ago       106MB
 vagrant@docker  ~  docker run -d -p 80:80 myapache:v1 
 vagrant@docker  ~  docker image inspect myweb:ubuntu
"Config": {
            "Cmd": [
                "/bin/sh",
                "-c",
                "/usr/sbin/apache2ctl -DFOREGROUND"
            ],
        },

/bin/sh -c /usr/sbin/apache2ctl -DFOREGROUND 실행이 된 것이다.

 vagrant@docker  ~  docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED          STATUS          PORTS                               NAMES
6a181b29347d   myweb:ubuntu   "/bin/sh -c '/usr/sb…"   3 minutes ago    Up 3 minutes    0.0.0.0:80->80/tcp, :::80->80/tcp   wonderful_shtern
f3e490c2b22a   ubuntu:focal   "bash"                   11 minutes ago   Up 11 minutes                                       naughty_benz

docker ps로 확인해봤을 때 COMMAND에서 해당 명령을 실행 중임을 알수 있다.

CMD /usr/sbin/apache2ctl -D FOREGROUND
/bin/sh -c /usr/sbin/apache2ctl -D FOREGROUND

CMD /usr/sbin/apache2ctl -D FOREGROUND 이렇게 옵션을 주면
자동적으로 /bin/sh(shell)이 명령(/usr/sbin/apache2ctl -D FOREGROUND)을 실행한다.

 vagrant@docker  ~  sh -c ls
centos7  centos7.tar  contents  hello-world.tar  httpd.conf
 vagrant@docker  ~  bash -c /usr/bin/ls
centos7  centos7.tar  contents  hello-world.tar  httpd.conf
 vagrant@docker  ~ 

실제로 sh -c 또는 bash -c 를 붙여 실행해도 그대로 잘 실행된다.

→ ​bash가 shell을 실행하고 shell이 ls을 실행하는 구조이다.

 

✔️ ExposedPort 변경

docker commit -c "EXPOSE PORT/PROTOCOL" 

내가 만든 이미지들의 Config 정보를 보면 ExposedPorts 설정이 없다.
단순히 사용자에게 제공하는 정보일 뿐 작동에는 아무런 의미가 없다.
여기에 80을 적는다고 실제 서비스가 80 포트로 서비스 하는 것이 아니다.

 vagrant@docker  ~  docker commit -c "CMD /usr/sbin/apache2ctl -DFOREGROUND" -c "EXPOSE 80/tcp" f3 myweb:ubuntu
sha256:ff55a00fed7bfa65adc1c6e197ceb0615bfc380bf3d6183fb0414cf513cf19bd

 vagrant@docker  ~  docker image inspect myweb:ubuntu
"ExposedPorts": {
                "80/tcp": {}
            },
728x90