개발/docker

docker image 생성

덤벨로퍼 2020. 3. 30. 19:35

컨테이너를 멈추는 두가지방법

docker stop 

- sigterm(terminate signal) 을보냄 , clean up 과정후 셧다운(시간이 걸림)

docker kill

- sigkill(kill signal) 을보냄 , 추가적인 일하지 않고 당장 셧다운

 

 

추가적인 컨테이너를 실행하는방법

docker exec -it <id> <command>

 

1. exec 은 다른 커맨드를 실행시킬때 사용하는 명령어이다.

2.리눅스 환경에서 모든 프로세스에는 3가지 커뮤니케이션 채널이있다.( standard in , out , err)

터미널에서 뭘치면 standard in 을 통해 들어가며 응답은 standard out 을통해 터미널로 볼수잇게된다.

err 발생시 standard err 채널을 통해 응답된다

-i 는 이 standard in 을 의미한다.

3.<command>에서 sh 를 사용하면 해당 컨테이너 안에서 커맨드를 자유롭게 입력할수있다.

 

Dockerfile

#존재하는 도커 이미지 base 로 사용
From alpine
#dependency 다운 설치
Run apk add --update redis
# image 가 시작되면 뭐해야하는지 명령
CMD [ "redis-server" ]

From , Run Cmd  세가지 instruction 으로 Dockerfile을 생성했고

'docker build .' 명령어를 커맨드에 입력하면 다음과같이 실행되다.

여기서 build는 Dockerfile을 가져와실행해주고 . 은 buildContext 를 의미한다. (추후다시나옴)

Step 1/3 : From alpine
latest: Pulling from library/alpine
c9b1b535fdd9: Pull complete 
Digest: sha256:ab00606a42621fb68f2ed6ad3c88be54397f981a7b70a79db3d1172b11c4367d
Status: Downloaded newer image for alpine:latest
 ---> e7d92cdc71fe
Step 2/3 : Run apk add --update redis
 ---> Running in 7f30aea866e3
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (5.0.7-r0)
Executing redis-5.0.7-r0.pre-install
Executing redis-5.0.7-r0.post-install
Executing busybox-1.31.1-r9.trigger
OK: 7 MiB in 15 packages
Removing intermediate container 7f30aea866e3
 ---> 7c61a83a1056
Step 3/3 : CMD [ "redis-server" ]
 ---> Running in d27485ea5709
Removing intermediate container d27485ea5709
 ---> b6a0f3ddef5e
Successfully built b6a0f3ddef5e

from은 alpine 이라는것을 받아오고

run 은 alpine 에서 뭘 받아 redis를 설치한다. 

cmd에서 redis-server를 실행한다.

 

이와같이 dockerfile을 만드는 이유는 컴퓨터에서 os 없이 크롬을 까는것과같다.

alpine은 os 처럼 prebuilt 된것이 많아 꺼내서 바로 설치할수있게해준다.

 

step 2를보면 

---> Running in 7f30aea866e3
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (5.0.7-r0)
Executing redis-5.0.7-r0.pre-install
Executing redis-5.0.7-r0.post-install
Executing busybox-1.31.1-r9.trigger
OK: 7 MiB in 15 packages
Removing intermediate container 7f30aea866e3

 

runing 된 아이디가(7f30aea866e3) 마지막에 removing 되는것을 볼수있다.

한 컨테이너가 일시적으로 생겼다 사라지는것인데.

 

컨테이너 생성후 

alpine image를 가져와 redis를 설치한 새로운 file system 을 가진 이미지를 만든후 (알파인+레디스 가 포함된) 

컨테이너가 지워지는것이다. 

 

step3 에서는

Step 3/3 : CMD [ "redis-server" ]
 ---> Running in d27485ea5709
Removing intermediate container d27485ea5709
 ---> b6a0f3ddef5e
Successfully built b6a0f3ddef5e

또 새로운 컨테이너 생성후

step2에서 생성된 이미지를 가져와

'redis-server' 라는 primary command를 저장후 

b6a0f3ddef5e 라는 마지막 이미지를 만들어낸다

 

즉 step 2 는 1의 이미지를

step 3는 2의 이미지를 가져와 실행하고

더 step이없다면 output을 만들어낸다.

 

만약 docker file 을 수정하면 어떻게될까

dockerfile 가운데에 한줄의 명령어(Run apk add --update gcc) 를 추가했다.

 


From alpine

Run apk add --update redis
Run apk add --update gcc

CMD [ "redis-server" ]

이런경우 docker build 를 실행해보면

Step 1/4 : From alpine
 ---> e7d92cdc71fe
Step 2/4 : Run apk add --update redis
 ---> Using cache
 ---> 7c61a83a1056
Step 3/4 : Run apk add --update gcc
 ---> Running in c56490f72a5c
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/10) Installing libgcc (9.2.0-r4)
(2/10) Installing libstdc++ (9.2.0-r4)
(3/10) Installing binutils (2.33.1-r0)
(4/10) Installing gmp (6.1.2-r1)
(5/10) Installing isl (0.18-r0)
(6/10) Installing libgomp (9.2.0-r4)
(7/10) Installing libatomic (9.2.0-r4)
(8/10) Installing mpfr4 (4.0.2-r1)
(9/10) Installing mpc1 (1.1.0-r1)
(10/10) Installing gcc (9.2.0-r4)
Executing busybox-1.31.1-r9.trigger
OK: 102 MiB in 25 packages
Removing intermediate container c56490f72a5c
 ---> 4682c41fa1f0
Step 4/4 : CMD [ "redis-server" ]
 ---> Running in 0bbeb9a1bc01
Removing intermediate container 0bbeb9a1bc01
 ---> 9518e430c39e
Successfully built 9518e430c39e

step 1 /2 을 보면  캐쉬를 사용해 건너 뛰는것을 확인할수있다.

이미 지시한 내용인줄 docker가 파악해서 캐시를 사용한다.

하지만 명령어의 순서가 바뀔경우는  해당 명령어를 실행한다.

 

dockerfile 수정없이 다시 docker build 실행시

Step 1/4 : From alpine
 ---> e7d92cdc71fe
Step 2/4 : Run apk add --update redis
 ---> Using cache
 ---> 7c61a83a1056
Step 3/4 : Run apk add --update gcc
 ---> Using cache
 ---> 4682c41fa1f0
Step 4/4 : CMD [ "redis-server" ]
 ---> Using cache
 ---> 9518e430c39e
Successfully built 9518e430c39e

캐시를 사용하는것을 확인할수있다.

 

docker build .

빌드한 파일을 실행하는경우 

"docker run 컨테이너 id " 이런식으로 실행할수도있지만

이름을 지정할수있다. 이를 이미지 tagging 이라 하는데

docker build -t khdrogba/tester:latest .
Sending build context to Docker daemon  2.048kB
Step 1/4 : From alpine
 ---> e7d92cdc71fe
Step 2/4 : Run apk add --update redis
 ---> Using cache
 ---> 7c61a83a1056
Step 3/4 : Run apk add --update gcc
 ---> Using cache
 ---> 4682c41fa1f0
Step 4/4 : CMD [ "redis-server" ]
 ---> Using cache
 ---> 9518e430c39e
Successfully built 9518e430c39e
Successfully tagged khdrogba/tester:latest

 

"docker build -t 도커아이디/리파지토리이름:버전  경로"

(docker build -t khdrogba/tester:latest . "

이렇게 명령하면 된다. 

이후 " docker run khdrogba/tester " 를 실행하면 알아서 최신 버전을 실행한다.

 

 

dockerfile 실행을 매뉴얼로한다면 이렇다

docker run -it alpine sh
/ # apk add --update redis
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/main/x86_64/APKINDEX.tar.gz
fetch http://dl-cdn.alpinelinux.org/alpine/v3.11/community/x86_64/APKINDEX.tar.gz
(1/1) Installing redis (5.0.7-r0)
Executing redis-5.0.7-r0.pre-install
Executing redis-5.0.7-r0.post-install
Executing busybox-1.31.1-r9.trigger
OK: 7 MiB in 15 packages

redis 설치후 새로운 터미널에서

docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
9c0afe722265        alpine              "sh"                2 minutes ago       Up 2 minutes                            optimistic_jones

ganghwiui-MacBook:redis-image hwi$ docker commit -c 'CMD ["redis-server"]' 9c0afe722265
sha256:ad92f481e80a812d3bc9775fc89046ff4d01aae5c7429db22531a2a496961f7d

해당 sha256 id 를 가져와서 (앞에부분만가져와도 알아서 찾음)

"docker run ad92f481e " 하면 실행된다.