docker 기본 개념을 아는 상태에서 진행합니다.
pull 명령어로 docker hub에 있는 image를 다운받는것도 있지만
내가 작접 만드는 두가지를 알아볼게요.
■ 첫번째는 commit 입니다.
container를 대상으로 image 만드는 건데요.
container는 image가 실행된 상태인데요. 왜 image를 다시 만들까요?
간단하게 백업 의미라고 생각하시면 될 거예요.
container로 실행 중에 변경 사항이 생겨 container 안에서 뭔가 변경을 했다면
이 변경된 내용은 원래 image에는 저장되지 않습니다.
이럴 때 container에 변경된 내용까지 포함된 현재 상태의 container 그대로
새로운 image를 만들어야 될 때 commit을 사용합니다.
docker commit [container명] [만들image명]
commit을 이용해 간단하게 image 만들어 볼게요
.
docker hub에서 다운받은 ubuntu 이미지를 이용합니다.
[sidepower@localhost ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu latest 2dc39ba059dc 2 weeks ago 77.8MB
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
컨테이너 이름을 cont_sample1로 지정했어요.
[sidepower@localhost ~]$ docker run --name cont_sample1 -it ubuntu
root@fbcfbfee08ea:/# ls
bin boot dev etc home lib lib32 lib64 libx32 media mnt opt
proc root run sbin srv sys tmp usr var
처음 실행했을 때 컨테이너 안에 tmp 디렉터리 안에는 아무것도 없습니다.
root@fbcfbfee08ea:/# cd tmp
root@fbcfbfee08ea:/tmp# ll
total 0
drwxrwxrwt. 2 root root 6 Aug 15 11:53 ./
drwxr-xr-x. 1 root root 18 Sep 17 06:10 ../
변경을 주기 위해 check.conf라는 파일을 만들었어요
root@fbcfbfee08ea:/tmp# touch check.conf
root@fbcfbfee08ea:/tmp# ll
total 0
drwxrwxrwt. 1 root root 24 Sep 17 06:11 ./
drwxr-xr-x. 1 root root 29 Sep 17 06:10 ../
-rw-r--r--. 1 root root 0 Sep 17 06:11 check.conf
/tmp 디렉터리 안에 check.conf 파일을 만든 현재 상태에서
commit으로 image를 만들어 볼게요.
cont_sample1 이름의 container를 대상으로
cont_sample1_img 이름으로 새로운 image를 만듭니다.
[sidepower@localhost ~]$ docker commit cont_sample1 cont_sample1 _img
sha256:c7c21004209956ea93f1e62f4096456451d754606ccb41be0e811fbdb6838c50
새로 만든 cont_sample1_img 이미지를
다시 cont_sample1_img_run 이름으로 container를 실행해서 확인해 볼게요.
[sidepower@localhost ~]$ docker run --name cont_sample1 _img_run -it cont_sample1_img
root@1c9b0a49fb64:/# cd tmp
root@1c9b0a49fb64:/tmp# ll
total 0
drwxrwxrwt. 1 root root 24 Sep 17 06:11 ./
drwxr-xr-x. 1 root root 6 Sep 17 06:13 ../
-rw-r--r--. 1 root root 0 Sep 17 06:11 check.conf
check.conf가 있죠. ㅋ
commit은 이렇게 변경된 컨테이너 상태 그대로 이미지를 만드는
스냅샷(백업용)으로 많이들 사용합니다.
■ 두번째 build입니다.
build는 Dockerfile이라는 이름의 설정 파일을 이용해서 image를 만들 때 사용됩니다.
그래서 Dockerfile 작성 문법을 알고 있어야 됩니다.
엄청 심플한 Dockerfile를 만들어 image를 만들어볼게요.
● Dockerfile 만들기
파일 이름은 Dockerfile로 정해져 있어요. 다른 이름으로 하시면 안돼요.
FROM ubuntu:latest
Dockerfile안에 내용이 위에 보이는 한 줄.. ㅋ 이게 다 한 거예요. 너무 간단하죠.
참고로 latest는 최신버전을 뜻합니다.
docker 명령어에서 image를 지정할 때 [이미지:버전] 형태로 사용하는데
버전은 생략해도 됩니다.
Dockerfile 작성의 기본 문법은 [명령어 인자 값]이며
FROM이라는 명령어와 ubuntu:latest라는 인자값을 뜻합니다.
♠ FROM
docker에서의 image 구성은 기본 image를 바탕으로
필요한 명령어나 설정 값들을 지정하고
또 다른 image가 필요하다면 기본 image에 레이어(layer) 형태로 추가되어
층층이 image가 쌓여서 만들어집니다.
그래서 image를 만들 때 최초의 기본 image가 필요하고
Dockerfile에서 기본 image를 지정하는 명령어가 FROM입니다.
항상 Dockerfile 처음에 FROM이 있는 이유죠.
[sidepower@localhost docfiles]$ cat Dockerfile
FROM ubuntu:latest
이 한 줄로도 dcoker image가 만들어지는지 볼게요.
드뎌 build 명령어를 사용합니다.
docker build -t image명 Dockerfile경로
-t 옵션으로 새로 만들 image 이름을 지정합니다.
Dockerfile경로는 Dockerfile파일이 있는 디렉터리 경로이며
현재 위치를 가리키는 점(.)으로 했어요.
다른 경로에 있으면 절대경로 또는 상대경로 해당 경로를 지정하면 됩니다.
[sidepower@localhost docfiles]$ docker build -t webserver2_img .
[+] Building 0.1s (5/5) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 115B 0.0s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 0.0s
=> [1/1] FROM docker.io/library/ubuntu:latest 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:4d163d6d5123121d08e9c7b9b8765d481eb720b169234bae8fca5ba05681a791 0.0s
=> => naming to docker.io/library/webserver2 0.0s
webserver2_img 이미지가 생성된 게 보이시죠.
[sidepower@localhost docfiles]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver2_img latest 4d163d6d5123 2 weeks ago 77.8MB
ubuntu latest 2dc39ba059dc 2 weeks ago 77.8MB
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
이렇게 Dockerfile를 이용해서 build로 이미지를 생성할 수 있어요.
자 이제 한 단계 더 나아가서 Dockerfile 명령어들을 알아볼게요.
FROM ubuntu:latest
RUN apt update && apt install -y python3
WORKDIR /usr/doc/test
RUN echo "Hello Docker" > hello.dat
COPY ["index.html","."]
CMD ["python3","-u","-m","http.server"]
♠ RUN
build 되는 과정에서 인자 값으로 지정된 문자열을 실행시키는 명령어입니다.
그리고 && 연산자를 이용해서 여러 명령어를 한 줄에 실행할 수 있습니다.
원래는 두줄인데 && 로 한 줄로 표현했습니다.
RUN apt update
RUN apt install -y pythone3
=> RUN apt update && apt install -y python3
RUN echo "Hello Docker" > hello.dat
=> "Hello Docker"라는 문자열을 hello.dat 파일에 기록하며
WORKDIR에 지정된 디렉터리 안에 만들어진다.
♠ WORKDIR
작업 디렉터리를 지정하는 명령어입니다.
지정된 디렉터리가 없으면 생성까지 해줍니다.
WORKDIR /usr/doc/test
♠ COPY
host에 있는 파일을 image안으로 복사하는 명령어입니다.
COPY ["index.html","."]
=> host의 index.html 파일을 image안의 WORKDIR에 복사하며
점(.)으로 지정해서 WORKDIR로 copy 되는 것이고
원하는 경로를 지정하면 그쪽으로 복사됩니다.
♠ CMD
build가 완료되어 container가 실행될 때 같이 실행되는 명령어를 지정합니다.
CMD ["python3","-u","-m","http.server"]
=> python 웹서버를 실행하는 python3 -u -m http.server를 지정했습니다.
RUN과 CMD 둘 다 지정된 문자열을 실행하는 건데요.
차이점이라면
RUN은 build하는 과정에서 실행되어 image에 적용되고
CMD는 build가 완료되어 container가 실행될 때 같이 실행됩니다.
Dockerfile 내용을 요약하면
ubuntu 리눅스를 설치하고
리눅스에서 apt update와 python3 설치하며
/usr/doc/test안에 hello.dat파일과 index.html을 생성하고
python 웹서버를 실행하게 하는 docker image를 만드는 것입니다.
[sidepower@localhost docfiles]$ docker build -t webserver3_img .
[+] Building 18.1s (9/9) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 244B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/ubuntu:latest 0.0s
=> CACHED [1/4] FROM docker.io/library/ubuntu:latest 0.0s
=> [internal] load build context 0.1s
=> => transferring context: 163B 0.0s
=> [2/4] RUN apt update && apt install -y python3 17.4s
=> [3/4] WORKDIR /usr/doc/test 0.1s
=> [4/4] COPY [index.html,.] 0.0s
=> exporting to image 0.6s
=> => exporting layers 0.6s
=> => writing image sha256:4658de663b28e3d18d4c9833e5fad185f4fe26cb916900b0cb37e51bf9f37a21 0.0s
=> => naming to docker.io/library/webserver3_img 0.0s
webserver3_img 이미지가 생성된 게 보이네요. ^^
[sidepower@localhost docfiles]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
webserver3_img latest 4658de663b28 About a minute ago 145MB
webserver1_back1 latest 88f5f1d0cfe5 2 hours ago 77.8MB
ubuntu latest 2dc39ba059dc 2 weeks ago 77.8MB
webserver2 latest 4d163d6d5123 2 weeks ago 77.8MB
hello-world latest feb5d9fea6a5 11 months ago 13.3kB
webserver3_img 이미지를 실행해 볼게요.
python 웹서버 기본 port가 8000입니다.
-p 옵션을 이용해서 host의 8080 port를 지정해서
python 웹서버 8000 port로 포트 포워딩을 지정할 수 있습니다.
container 이름을 webserver3로 지정해서 실행하니
HTTP 서버가 8000 port 기동 되는 게 표시되네요.
[sidepower@localhost docfiles]$ docker run -p 8080:8000 --name webserver3 webserver3_img
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
ps명령어로 container 조회해 보니 webserver3 실행된 게 보이네요. ^^
[sidepower@localhost docfiles]$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cca4c9aedf76 webserver3_img "python3 -u -m http.…" 37 seconds ago Up 36 seconds 0.0.0.0:8080->8000/tcp, :::8080->8000/tcp webserver3
925c797272f5 ubuntu "bash" 2 hours ago Up 2 hours webserver1
webserver3 컨테이너의 python 웹서버가 정말로 잘 동작하는지
curl를 이용해서 url 호출해봤어요.
8080으로 호출하면 -p 옵션에 지정된 container 8000 port로 자동으로 호출되겠죠.
[sidepower@localhost docfiles]$ curl localhost:8080
<html>
<body>
hello . docker . Dockerfile..start!!
</body>
</html>
COPY ["index.html","."] 로 지정한 index.html 내용이 잘 표시됩니다.
또 HTTP python 웹서버에 호출이 들어왔다는 로그가 한 줄 생기네요.
[sidepower@localhost docfiles]$ docker run -p 8080:8000 --name webserver4 webserver3_img
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
172.17.0.1 - - [16/Sep/2022 15:54:10] "GET / HTTP/1.1" 200 -
여기까지 간단하게 image 만드는 방법을 확인해 봤습니다.
그리고 여기에 있는 Dockerfile 명령어보다 더 많이 있습니다.
docker 사이트에 잘 정리되어 있으니 한 번씩 살펴보시면 될 거예요.
https://docs.docker.com/engine/reference/builder/
감사합니다.
도커 자료 찾다가 우연히 눈에 띄어 내돈내산 도커컨테이너 각티슈에요.
사진보다 실물이 더 튼튼하고 깔끔해서 득템한거 같아 사진 몇장 올립니다.
왠지 다시 도커 열공 모드로 돌입해야 될거 같네요.ㅋ
https://incatos.shop/surl/O/11
'IT > CLOUD' 카테고리의 다른 글
docker에서 자바 개발 환경 만들기 (0) | 2023.02.28 |
---|---|
쿠버네티스 설치 없이 웹에서 구축 연습하기 . Play with Kubernetes (2) | 2022.10.09 |
Docker(도커) 개념 정리와 이미지 컨테이너 명령어 사용하기 (0) | 2021.07.21 |
[클라우드] Cloud 꼭 배워야 하는 이유 . IaaS PaaS SaaS 개념정리 (0) | 2021.07.04 |
리눅스 CentOS8 Spark 3.0.2 설치하기 . 빅데이터 스파크란 (0) | 2021.03.06 |
댓글