1. 도커파일 생성
root@k8s-node1:~# mkdir dockerFile root@k8s-node1:~# cd dockerFile/ root@k8s-node1:~/dockerFile# ll total 8 drwxr-xr-x 2 root root 4096 10월 26 13:45 ./ drwx------ 8 root root 4096 10월 26 13:45 ../ root@k8s-node1:~/dockerFile# echo test >> test.html
새로운 디렉토리를 하나 만들어서 안에서 작업한다.
도커파일을 빌드시에 해당 디렉토리가 루트가 되어 작업이 수행된다.
vi Dockerfile #FROM : Base Image FROM ubuntu:14.04 #LABEL, MAINTAINER : 메타데이터로 개발자 정보, 값등 #RUN : 컨테이너 내부에서 실행할 명령 RUN apt-get update RUN apt-get install apache2 -y # 추가 입력을 못받기에 -y 명령어로 사용 #ADD : 파일을 이미지에 추가 ADD test.html /var/www/html #WORKDIR : 명령을 싱행할 디렉토리 WORKDIR /var/www/html #RUN : RUN ["실행 파일" "인자1" "인자2" ... ] Json배열 형태로 사용 RUN ["/bin/bash", "-c", "echo hello >> test2.html"] #EXPOSE : 노출할 포트 설정 EXPOSE 80 #CMD : 컨테이너가 시작될 때 마다 실행 할 명령어 CMD apachectl -DFOREGROUND
도커파일은 위에서부터 순차적으로 내려오며 읽어서 실행된다.
2. 도커파일 빌드
root@k8s-node1:~/dockerFile# docker build -t mybuild:0.1 ./ Sending build context to Docker daemon 3.584kB Step 1/8 : FROM ubuntu:14.04 ---> 13b66b487594 Step 2/8 : RUN apt-get update ---> Running in ec30c95a84c7 Get:1 http://security.ubuntu.com trusty-security InRelease [65.9 kB] Ign http://archive.ubuntu.com trusty InRelease ... ... Get:22 http://archive.ubuntu.com trusty/universe amd64 Packages [7589 kB] Get:23 http://archive.ubuntu.com trusty/multiverse amd64 Packages [169 kB] Fetched 14.1 MB in 7s (1762 kB/s) Reading package lists... Removing intermediate container ec30c95a84c7 ---> 8317f4450af5 Step 3/8 : RUN apt-get install apache2 -y # 추가 입력을 못받기에 -y 명령어로 사용 ---> Running in 5a4cc1022034 Reading package lists... Building dependency tree... ... ... Processing triggers for ureadahead (0.100.0-16) ... Removing intermediate container 5a4cc1022034 ---> 1c0aef9f2846 Step 4/8 : ADD test.html /var/www/html ---> 9f175727acb1 Step 5/8 : WORKDIR /var/www/html ---> Running in 9d47a9483dd2 Removing intermediate container 9d47a9483dd2 ---> d98431c8d706 Step 6/8 : RUN ["/bin/bash", "-c", "echo hello >> test2.html"] ---> Running in 1061fdc52a45 Removing intermediate container 1061fdc52a45 ---> 0341237730d3 Step 7/8 : EXPOSE 80 ---> Running in 07267649ec33 Removing intermediate container 07267649ec33 ---> d9acba71ccc3 Step 8/8 : CMD apachectl -DFOREGROUND ---> Running in f33cb528eddb Removing intermediate container f33cb528eddb ---> 32ffe5369290 Successfully built 32ffe5369290 Successfully tagged mybuild:0.1
docker build -t [이미지이름:버전] [도커파일위치]
도커파일 위치는 상대기준으로 현재 dockerFile 이 있는 곳에 위치해있기 때문에 위에선 ./ 을 입력했다.
만약 인터넷에서 받아서 사용할 경우 url 을 입력해도 된다.
또한 -t 옵션은 이미지 이름을 지정하는 옵션으로 지정하지않는다면 16진수 해시값이 무작위로 출력되므로 하는것이 좋다.
완료가 되었다면
도커 파일을 이용해 만든 mybuild:0.1 이미지를 사용해서 컨테이너 생성
root@k8s-node1:~/dockerFile# docker run -d -P --name myserver mybuild:0.1 159aaec0e61c09899a7f106a968937e7d649a4baadf084f96326d64ed9a7b511 root@k8s-node1:~/dockerFile# docker port myserver 80/tcp -> 0.0.0.0:49154 80/tcp -> :::49154
docker run 옵션을 이용해 생성해본다. -P 옵션은 EXPOSE 한 옵션들을 호스트와 바인딩 시켜준다.
위는 49154 포트와 연동되었다.
docker port [컨테이너이름] 으로 포트 상황을 살펴볼 수 있다.
서버가 정상적으로 잘 되었는지 접속하여 확인
root@k8s-node1:~/dockerFile# curl 127.0.0.1:49154/test.html test root@k8s-node1:~/dockerFile# curl 127.0.0.1:49154/test2.html hello
curl [주소] 명령어로 확인해보니 아까 만들었던 test.html test2.html 호출이 잘 되는것을 볼 수 있다.
* 도커파일 빌드시 .dockerignore 파일을 이용하여 원하지 않는 파일들을 빌드 제외시킬 수 있다. (마치 .gitignore 처럼)
docker build 시 출력되는 문구를 보면 이미지레이어를 생성했다가 removing 하는 작업들을 확인 할 수 있다.
레이어를 만들어 이를 새 레이어에 덮어씌워 최종 완성본이 나오는 것이다.
3. 여러 도커파일 빌드
어떤 이미지들은 기능이 많지 않음에도 불구하고 여러 레이어들이 겹겹이 쌓여있어 불필요하게 용량이 큰 경우가 있다.
root@k8s-node1:~/dockerFile# vi Hello.java public class Hello { public static void main(String[] args){ System.out.println("Hello World!!"); } }
root@k8s-node1:~/dockerFile# vi Dockerfile FROM openjdk:8 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Hello.java CMD ["java", "Hello"]
이 도커파일은 Hello.java 를 컴파일해서 Hello World를 찍는 이미지다.
openjdk 8버전을 베이스 이미지로 javac 컴파일해서 java hello 를 수행한다.
root@k8s-node1:~/dockerFile# docker build -t my-java-app . Sending build context to Docker daemon 3.072kB Step 1/5 : FROM openjdk:8 ---> b273004037cc Step 2/5 : COPY . /usr/src/myapp ---> 622eb058a4dd Step 3/5 : WORKDIR /usr/src/myapp ---> Running in abd5247667c1 Removing intermediate container abd5247667c1 ---> b66ea5a281f6 Step 4/5 : RUN javac Hello.java ---> Running in c260317e1971 Removing intermediate container c260317e1971 ---> cd6acb380b6c Step 5/5 : CMD ["java", "Hello"] ---> Running in 2603d7d9cf6c Removing intermediate container 2603d7d9cf6c ---> b1909a3ac473 Successfully built b1909a3ac473 Successfully tagged my-java-app:latest root@k8s-node1:~/dockerFile# docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-java-app latest b1909a3ac473 About a minute ago 526MB
해당 이미지를 빌드해보니 용량이 약 526MB 가량 차지한다.
root@k8s-node1:~/dockerFile# docker run -i -t --name my-java-container my-java-app:latest Hello World!!
원하는대로 잘나온다.
root@k8s-node1:~/dockerFile# vi Dockerfile FROM openjdk:8 COPY . /usr/src/myapp WORKDIR /usr/src/myapp RUN javac Hello.java FROM openjdk:8-alpine WORKDIR /root COPY --from=0 /usr/src/myapp/Hello.class . CMD ["java", "Hello"]
멀티스테이지를 이용해서 도커파일을 작성하고 빌드
(베이스 이미지가 두개 이상)
이러면 맨 처음 이미지인 openjdk:8 은 버리고 아래가 베이스이미지가 된다.
COPY –from=0 은 기존 이미지에서 가져오겠다는 거
root@k8s-node1:~/dockerFile# docker build -t my-java-app:multi . Sending build context to Docker daemon 3.072kB Step 1/8 : FROM openjdk:8 ---> b273004037cc Step 2/8 : COPY . /usr/src/myapp ---> 1b52b8837bca Step 3/8 : WORKDIR /usr/src/myapp ---> Running in 4610d03481e2 Removing intermediate container 4610d03481e2 ---> 22e4f0c82835 Step 4/8 : RUN javac Hello.java ---> Running in f6fb9bd25da7 Removing intermediate container f6fb9bd25da7 ---> 65fc039ec8ac Step 5/8 : FROM openjdk:8-alpine ---> a3562aa0b991 Step 6/8 : WORKDIR /root ---> Using cache ---> df4d33e44f01 Step 7/8 : COPY --from=0 /usr/src/myapp/Hello.class . ---> 457873025785 Step 8/8 : CMD ["java", "Hello"] ---> Running in 258b393c2c3f Removing intermediate container 258b393c2c3f ---> 1de582853652 Successfully built 1de582853652 Successfully tagged my-java-app:multi root@k8s-node1:~/dockerFile# docker images REPOSITORY TAG IMAGE ID CREATED SIZE my-java-app multi 1de582853652 About a minute ago 105MB my-java-app latest b1909a3ac473 11 minutes ago 526MB
빌드가 잘 됐고 my-java-app:multi 용량을 살펴보니 105MB 로 이전보다 확연히 줄었음을 알 수 있다.
(이건 예시를 위한것으로 처음부터 그냥 alpine 이미지 써서 컴파일까지 다했으면 105MB긴 함)
(alpine 이미지는 경량화된 이미지)
root@k8s-node1:~/dockerFile# docker run -i -t --name my-java-contiainer-multi my-java-app:multi Hello World!!
아무튼 동작이 잘 된다…