빌드

출처: https://www.mindmeister.com/ko/740843162/continuous-integration-workflow


1) 빌드 컨텍스트를 읽어 들인다.

-> 빌드 컨텍스트는 이미지를 생성하는데 필요한 각종 파일, 소스코드 등을 담고 있는 디렉토리이며 DockerFile이 있는 디렉토리이다.


2) 파일을 추가할 때도 사용된다. (ADD, COPY)






Dockerfile로 빌드 시 주의점


1) 하나의 명령어를 \로 나누어 가독성을 높인다.

2) RUN 명령어는 하나의 이미지 레이어가 될 수 있다. 여러 개의 Run 명령어를 && 옵션과 함께 되도록이면 하나로 묶자.


명령어


docker file 한줄이 하나의 명령어가 되고 명령어를 명시한 옵션을 추가하는 방식. 스크립트와 동일하게 위에서 아래로 실행되며 명령어는 일반적으로 대문자로 표시한다.



FROM

 생성할 이미지의 베이스가 이미지. From 명령어는 Dockerfile 작성할 반드시 이상 입력해야 하며, 이미지의 이름의 포맷은 docker run 명령어에서 이미지 읾을 사용했을 떄와 같다. 이미지가 도커에 없다면 자동으로 pull 한다.

 Maintainer

 이미지를 생성한 개발자의 정보. 일반적으로 메일 정보를 작성한다.

 LABEL

 메타데이터 추가. 메타데이터는 : 형태로 저장되며, 여러 개의 메타데이터가 저장될 있다. inspect 명령어로 이미지의 정보를 구해서 확인 있다.

 RUN

 이미지를 만들기 위해 컨테이너 내부에서 명령어를 실행한다.

 ADD, COPY

 파일을 이미지에 추가합니다. 파일은 Dockerfile 위치한 디렉터리인 컨텍스트에서 가져온다. (dockerfile 위치한 데릭터리에서 파일을 가져온다.)

ADD와 COPY의 차이점은 파일을 추가한다는 베이스는 동일하지만, ADD는 URL 및 .tar 파일의 추가가 가능하다. tar 파일의 경우 자동 압축해제된다.

 WORKDIR

 명령어를 실행할 디렉터리 지정한다.

 EXPOSE

 커파일의 빌드로 생성된 이미지에서 노출할 포트를 설정한다. 이미지에 노출됬다는 것은 호스트의 포트와 반드시 바인딩 되었음을 의미하는 것이아니며, 이포트를 호스트에서 사용할 있음을 의미한다.

 CMD

 CMD 컨테이너가 시작될 때마다 실행할 명령어를 설정하며, dockerfile에서 사용할 있다.

 ENTRYPOINT

 ENTRYPOINT entrypoint는 cmd와 동일하게 컨테이너가 시작될 때 수행할 명령을 지정한다는 점에서 같다. 그러나 entrypoint는 커맨드를 인자로 받아 스크립트로 수행할 수 있다는 점에서 다르다.

docker file에 entrypoint를 지정하거나 docker run 단계에서 entrypoint 옵션을 줄 수 있다.

 ENV

Dockerfile에서 환경변수를 지정한다. 이 환경변수는 Dockerfile 뿐 아니라 이미지에도 저장되므로 빌드된 이미지로 컨테이너를 생성하면 내부에서 사용할 수 있다. 

 ARG

 build 명령어를 실행할 때 추가로 입력을 받아 Dockerfile 내에서 사용될 변수의 값을 설정한다.

 USER

User로 컨테이너 내에서 사용될 사용자 계정이나 uid를 설정한다. 

 ONBUILD

빌드된 이미지를 기반으로 하는 다른 이미지가 Dockerfile로 생성될 때 실행할 명령어를 추가한다. 

 STOPSIGNAL

컨테이너가 정지될 때 사용될 시스템 콜의 종류를 지정한다. default는 SIGTERM으로 설정된다.

ex) STOPSIGNAL SIGKILL 

 HEALTHCHECK

healthcheck는 이미지로부터 생성된 컨테이너에서 동작하는 애플리케이션의 상태를 체크하도록 설정한다. 애플리케이션의 프로세스는 종료되지 않았으나, 애플리케이션이 동작하지 않을 때 사용된다. 

 SHELL

기본 Shell을 변경할 수 있다.

ex) SHELL ["/usr/local/bin/node"] 













빌드


docker build -t  mybuild:0.0   ./

  • -t 옵션 : 빌드할 이미지의 이름 지정

  • build:0.0 : 이미지의 이름과 버전

  • ./ : dockerfile이 위치한 디렉토리







* docker build 시 이전에 했던 이미지가 남아있는 채로 다시 빌드하면, 이전 빌드에서 사용했던 캐시를 사용하게 된다.

* 캐시를 사용하지 않으려면 --no-cache 옵션, 특정 이미지로 사용하려면 --cache-from 옵션을 주면 된다.


ex) docker build --cache-from nginix mynginix:0.0



'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Max TCP Connection limit  (0) 2019.01.15
Docker Build Context  (0) 2018.11.05
DockerFile (1)  (0) 2018.10.15
Docker Network (3) - host, none, container network  (0) 2018.09.18
Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17

DockerFile


도커는 애플리케이션의 배포의 일련의 과정(copy, commit..) 등의 빌드 명령어를 제공하며 DockerFile에 기록한다.


Dockerfile은 사용자가 이미지를 어셈블하기 위해 명령 행에서 호출 할 수있는 모든 명령을 포함하는 텍스트 문서이다. docker 빌드 사용자를 사용하면 몇 가지 명령 줄 명령을 연속적으로 실행하는 자동화 된 빌드를 만들 수 있다.


DockerFile을 통해 직접 컨테이너를 생성하고 이미지로 커밋해야하는 번거로움을 덜 수 있을 뿐 아니라 git과 같은 개발 도구를 통해 자동화를 할 수 있다.


애플리케이션을 개발하는 용도 이외에 여러 목적으로 사용 가능하며, 결국 도커파일을 작성하는 이유는 배포의 유연성과 자동화와 연관 깊다.


 






https://docs.docker.com/engine/reference/builder/#usage

Host network


네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있다.


# docker run -i -t --name host_ubuntu --net host ubuntu:latest


컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부 앱의 별도 포트 포워딩 없이 바로 접근할 수 있다.






none network



말그대로 아무런 네트워크를 사용하지 않는 것을 뜻하며, 외부와 단절된다.


# docker run -i -t --name none_ubuntu --net none ubuntu:latest




Container network


말그대로 다른 컨테이너의 네트워크 환경을 공유한다. 이 때, 한 컨테이너는 다른 컨테이너의 네트워크 환경을 공유하므로 내부 IP를 새로 할당받지 않고 호스트의 가상 네트워크 인터페이스도 생성되지 않는다. 



# docker run -i -t --name container_ubuntu ubuntu:latest


# docker run -i -t --name container2_ubuntu --net container:container_ubuntu ubuntu:latest








브리지 네트워크


앞서 기본적으로 쓸 수 있는 네트워크 중 bridge와 host, none을 확인했다.

도커에서는 브리지 네트워크를 사용자가 구성해 docker0을 대신해 각 컨테이너에 연결할 수 있도록 지원하며, 외부와 통신할 수 있다.


다음 명령어를 통해 새로운 브리지 네트워크를 생성할 수 있다.


#docker network create --driver bridge swift-bridge


# docker run -i -t --name net_ubuntu -p 8080:8080 --net swift-bridge ubuntu:latest


# docker inspect net_ubuntu






--subnet, --ip-range,--gateway 옵션 등을 통해 추가 네트워크 설정도 할 수 있다.






--net-alist


호스트의 별칭을 생성


사용자 정의 브리지 네트워크와 run 명령어의 --net-alias 옵션을 함께 쓰면 특정 호스트 이름으로 컨테이너의 여러개 IP의 목록을 갖는다.



# docker run -i -t --name ubuntu_alias_container1 --net swift-bridge --net-alias swift ubuntu:latest


# docker run -i -t --name ubuntu_alias_container2 --net swift-bridge --net-alias swift ubuntu:latest



각각의 IP가 생성되었으며  docker 엔진에 내장된 DNS가 swift라는 host 이름의 별칭으로 생성된 컨테이너로 변환한다. 


컨테이너 실행 시 ubuntu_alias_container1과 ubuntu_alias_container2는 swift라는 이름의 호스트 이름으로 swift-bridge에 등록 했으며, 도커 내장 DNS 서버는 swift라는 호스트 이름의 IP 목록을 여러 개 들고 있다.








해당 호스트 이름으로 ping을 날려보자.

# docker run -i -t --name ubuntu_ping --net swift-bridge ubuntu:latest


# ping -c 1 swift


결과, 각 각 IP로 Ping이 전송된 것을 확인 할 수 있는데, 매 번 전달되는 ping이 달라지는 것은 DNS가 랜덤하게 순서가 바뀐 IP의 리스트를 반환하고 클라이언트는 이 중 첫번 째 IP를 사용한다.







도커의 컨테이너 IP는 수시로 재시작 혹은 변경될 요소가 있다. 도커의 DNS는 --link 옵션과 같은 호스트 이름으로 유동적으로 컨테이너를 찾을 때 주로 사용한다. 이는 컨테이너 IP가 변경되어도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동 관리 되는데, --link 옵션은 디폴트 브리지 네트워크의 컨테이너 DNS라는 점이 다르다.

# docker run -i -t --name ubuntu_container --link test12345:alias_ubuntu ubuntu:latest


# cat /etc/hosts







참고- https://m.blog.naver.com/PostView.nhn?blogId=alice_k106&logNo=220747224965&proxyReferer=https%3A%2F%2Fwww.google.co.kr%2F




'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

DockerFile (1)  (0) 2018.10.15
Docker Network (3) - host, none, container network  (0) 2018.09.18
Docker Network (1) - docker0  (0) 2018.09.14
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker Engine, image  (0) 2018.09.08

Network


도커는 컨테이너 내부 IP를 순차적으로 할당하며 컨테이너가 재시작 할 때마다 변경될 수 있다.


내부 IP는 도커가 설치된 호스트, 즉 내부망에서만 쓸 수 있는 IP이므로 외부와 연결될 필요가 있다.


도커는 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스 이름은 veth로 시작한다. veth 인터페이스는 사용자가 직접 생성하지 않아도 되며 컨테이너가 생성될 때 도커엔진에 의해 자동 생성된다.




Docker0


Docker0 브리지의  각 컨테이너의 veth 인터페이스와 바인딩되며, 호스트OS의 eth0 인터페이스와 이어주는 역할을 한다.

특징은 다음과 같다.


  • IP 는 자동으로 172.17.42.1 로 설정 되며 16 bit netmask(255.255.0.0) 로 설정된다. 
  • 이 IP는 DHCP를 통해 할당 받는 것은 아니며, docker 내부 로직에 의해 자동 할당 받는 것이다.
  • docker0 는 일반적인 interface가 아니며, virtual ethernet bridge 이다.



Docker Network 기능

도커에서 기본적으로 쓸 수 있는 네트워크는 docker network ls 명령어로 확인가능하다.


# docker network ls





기본적으로 bridge, host, none 네트워크가 있는 것 을 알 수있다. 브리지 네트워크는 컨테이너를 생성 할 때 자동으로 연결되는 docker0 브리지를 활용하도록 설정되었으며 네트워크는 172.17.0.x IP 대역을 순차적으로 할당한다.




'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Network (3) - host, none, container network  (0) 2018.09.18
Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker Engine, image  (0) 2018.09.08
Docker?  (0) 2018.09.08

Container


컨테이너는 간단히 생각하면 애플리케이션를 포함한 그릇 혹은 집 정도로 의미를 두면 될 것 같다.

컨테이너는 각자의 독립된 공간을 갖고 있으며 OS의 커널을 공유할 수 있으며 컨테이너간 영향을 주지 않으며 OS 호스트에도 영향을 주지 않는다.







명령어



1) run vs create


- 두 명령어 모두 이미지를 통해 컨테이너를 생성하는 명령어이다.

- Run 명령어는 생성과 동시에 컨테이너 내부로 접근이 가능하다.

- Create 명령어는 생성에만 관여한다. 이 후 접근하기 위해 start 와  attatch(컨테이너 내부 접근) 명령을 추가로 수행해야 한다.


ex ) Docker run -i -t --name ubuntu ubuntu:latest

ex ) Docker create -i -t --name ubuntu ubuntu:latest

       Docker start  ubuntu

       Docker attach -i -t ubuntu




일반적으로 컨테이너를 생성과 동시에 접근하기 때문에 run 명령어에 익숙해지는 것이 좋다. 형식은 다음과 같다.



docker run [옵션] [이미지] [명령] [매개변수]





자주쓰는 옵션 대해 살펴보면..


옵션 

설명 

 -i, -t

 -interactive  -tty  i와 t는 터미널 입력을 위한 옵션으로 일반적으로 -it  혹은 -i -t

 -d

 detached mode 흔히 말하는 백그라운드 모드

 --name

 컨테이너 이름 설정

 -p

 호스트와 컨테이너 포트의 연결 : 포워딩

 -e 

 컨테이너 내에서 사용할 환경변수 설정

 -rm

 프로세스 종료시 컨테이너 자동 삭제

 --link

 컨테이너 연결 [컨테이너명:별칭] 

 -v

 호스트와 컨테이너의 디렉토리 연결 (마운트) 

 -e

 컨테이너 내에서 사용할 환경변수 설정 



보다 더 자세한 사항은 docker run --help 를 통해 확인할 수 있다.


위의 옵션을 사용한 예를 사용해보면..



docker run -d -i -t -p 80:80 -p 192.168.10.1:7777:80 --name myserver --link mysql:mysql ubuntu:latest 



=> 컨테이너 생성과 동시에 내부에 접근하며 호스트 포트 80과 외부에서 접근 가능하도록 192.168.10.1:7777 포트 2개를 포워딩했으며 mysql 이름을 갖는 mysql 서버를 링크했다.


=>  우분투 컨테이너 내부에 접근해서 mysql 서버의 DNS를 확인하면 다음과 같다.







아래표는 자주 사용하는 도커 명령어에 대한 정리 사항입니다.





명령어

설명 

 run, create

 컨테이너 생성

 pull

 docker hub로부터 이미지를 내려받음

 start

 컨테이너 시작 

 stop

 컨테이너 중지 

 ps [-a]

 컨테이너 목록 확인 
 -a 옵션은 중지된 컨테이너까지 확인 

 -q 옵션은 아이디만 얻어옴


 ex) docker stop $(docker ps -a -q)  : 모든 컨테이너 중지

 ex) docker rm $(docker ps -a -q) : 모든 컨테이너 삭제


 rm

 컨테이너 삭제 

 rmi

 이미지 삭제 

 prune


 모든 컨테이너 삭제


 ex) docker container prune 

 rename

 컨테이너 이름 재지정 

 exec

 

컨테이너 내부에서 명령어를 실행한 뒤 그 결과 값을 반환


ex) docker exec -it [container] [cmd] 

 inspect

 이미지,컨테이너, 볼륨 등 도커 모든 구성단위의 세부 정보 출력 





2) 도커 볼륨 (Volume)


도커 이미지로 컨테이너를 생성하면 이미지는 읽기 전용이 되며 컨테이너의 변경사항만 별도로 각 컨테이너의 정보로 보존한다.


예를 들어 mysql 이미지의 경우 이미지에는 mysql을 실행하는데 필요한 애플리케이션 정보만 들어있고, 컨테이너를 생성하여 mysql 컨테이너에는 쓰기모드가 가능하여 여러 


데이터가 저장된다. 하지만 만일 도커 컨테이너를 삭제한다면, 컨테이너 계층의 데이터도 모두 삭제 된다. 그렇기 때문에 데이터의 영속성을 유지해야 하는데 이 때 볼륨을 통해 


쉽게 활용할 수 있다. 볼륨을 활용하는 방법은 호스트와 볼륨을 공유하거나, 볼륨 컨테이너를 활용하거나, 혹은 도커가 관리하는 볼륨을 생성할 수 있다.





[i] 호스트 볼륨 공유


docker run  -v  [호스트 공유 디렉토리] : [컨테이너 공유디렉토리] 컨테이너


ex) docker run -e MYSQL_ROOT_PASSWORD=1234 -v /Users/chul/Documents/Docker/volume:/var/lib/mysql mysql





해당 경로에 파일이 생성된 것을 확인 할 수 있다. 


혼동할 수 있는 점은 /var/lib/mysql 을 동기화 하는 것이 아닌 완전히 같은 디렉토리라는 것이다. 


호스트 디렉토리가 없다면, 생성하고 컨테이너 내부의 디렉토리는 삭제하게 된다. 


만일 컨테이너 내부에 디렉토리가 존재하고, 호스트 볼륨공유를 통해 호스트 디렉토리를 지정하면 컨테이너 디렉토리는 덮어씌워진다. (Mount)





[ii] 볼륨 컨테이너 


볼륨을 사용하는 두 번째 방법은 볼륨 컨테이너를 지정하여 공유하는 것이다.


볼륨 컨테이너는 -v, -volume 옵션을 통해 호스트 디렉토리와 공유하고 있으며, -volumes-from 옵션을 통해 컨테이너와 공유 할 수 있다.


ex) docker run --name mycontainer --volumes-from volumes_container ubuntu:latest



즉, 간접적으로 볼륨컨테이너와 연결해 데이터를 공유하는 방식이다.





[iii] 도커 볼륨



볼륨을 사용하는 세 번째 방법은 볼륨 명령어를 사용하는 것이다.


ex) docker volume create --name volume_container

 

ex) docker volume ls




ex) docker run -it --name volume_ex_server -v volume_container:/etc/ ubuntu:latest

[볼륨 이름 : 컨테이너의 공유 디렉토리]






 이 처럼 컨테이너가 아닌 외부에 데이터를 저장하고 동작하도록 stateless 하도록 설계하는 것이 바람직하다.









참고 

 

https://www.docker.com/

https://www.joinc.co.kr/w/man/12/docker/privateRepository

http://blog.naver.com/alice_k106        






'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Network (1) - docker0  (0) 2018.09.14
Docker Engine, image  (0) 2018.09.08
Docker?  (0) 2018.09.08
Docker in MacOS 설치  (0) 2018.08.04


Engine


도커엔진에서 사용하는 기본단위는 이미지와 컨테이너이며, 두가지가 도커엔진의 핵심이다.


앞서 정리했지만, 도커엔진은 컨테이너와 이미지를 생성하고 사용하는데 필요한 기능을 제공하는 경량 런타임 도구이다.




Images


도커에서 이미지는 여러개의 계층으로 된 바이너리 파일로 존재하고, 컨테이너를 생성하고 실행할 때 읽기 전용으로 실행된다.


Format은 다음과 같이 구분된다.


[저장소 이름]/[이미지이름]:[태그]


swifty/ubuntu:14.0.4   or    swifty/ubuntu:latest



저장소 : 이미지가 저장된 장소를 의미, 도커에서 기본적으로 제공하는 이미지 저장소인 Docker Hub를 통해 우분투, CentOS와 같은 이미지를 받을 수 있으며 애플리케이션을 관리하기 위해 개인 저장소를 만들어 이미지를 관리할 수 있다. 이미지를 생성할 때 저장소 이름을 명시할 필요하는 없으므로 생략가능.


이미지 이름: 생략 불가능. 이미지의 역햘 단위로 이름을 지정


태그 : 버전관리 목적





'Cloud & NoSQL & Middleware > Docker' 카테고리의 다른 글

Docker Network (2) - 브리지(bridge) network  (0) 2018.09.17
Docker Network (1) - docker0  (0) 2018.09.14
Docker Container - 명령어 & Volume  (0) 2018.09.09
Docker?  (0) 2018.09.08
Docker in MacOS 설치  (0) 2018.08.04

+ Recent posts