4월, 2019의 게시물 표시

2019.04.23 - Bind Mounting, Persistent Data

a bind mount is just a mapping of the host files or directories, into a container file or directory. basically just two locations pointing to the same file. host files overwrite any in container, but doesn't change or overwrite just because of host file change. can't use in dockerfile, must be at container run (run time) ex ) . . . run -v //c/Users/Jun/stuff:/path/container (windows) ex ) . . . run -v /Users/Jun/stuff:/path/container (mac/linux) docker container run -d --name nginx -p 80:80 -v $(pwd):/usr/share/nginx/html nginx * $(pwd) : shell script로 현재 디렉토리다. * 뒤에 나오는 경로는 샘플 assignment의 경로이므로 고정이 아님. * Udemy에 질문사항이 있어 현재 확인 중

2019.04.22 - Dockerfile 알아보기, Docker volume 개론

Node 로 만들어진 웹 앱이 하나 있는데 이걸 다른 거 필요없이 그냥 도커 파일을 이용해 이미지를 빌드하고 컨테이너를 실행해서 그 위에서 돌려버리는 경험을 했다. 실로 어메이징하다. 만약 내 피씨에서 실행하려고 했으면 일단 노드부터 깔고, 환경변수 잡아주고, 포트 설정등등 귀찮았을텐데 갓커는 그냥 도커파일 이용해서 빌드해 하고 던져주니까 알아서 잘 돌려버린다. 도커파일을 한 번 뜯어보자 ------- dockerfile -------- FROM node:6-alpine # 실행할 이미지 EXPOSE 3000 # container의 3000번 포트를 사용 준비상태로 둔다. (지금 당장 3000포트로 뭐 받는게 아니라 호스트에서 전달받으면 이 포트로 받겠다는 의미) RUN apk add --update tini # container에서 실행할 명령어 RUN mkdir -p /usr/src/app # 마찬가지로 container에서 실행할 명령어 WORKDIR /usr/src/app # Working direcotory는 이 곳 COPY package.json package.json # 호스트 현재 디렉토리의 package.json을 container의 워킹디렉토리로복사한다. RUN npm install && npm cache clean # npm을 설치하고 캐싱된 것들을 지운다 COPY . . # 호스트의 현재 디렉토리에 있는 것을 container의 워킹 디렉토리로 복붙한다. CMD ["/sbin/tini", "--", "node", "./bin/www"] --> ' '.join(list)로 결합 된 string을 커맨드라인에서 실행한다. -----end of dockerfile----- dockerfile을 이용한 빌드 명령어 : docker build [-t TAGNAME] [DIRECTORY(rel...

2019.04.21 - Docker Tag, Dockerfile (Docker의 빌드과정)

1. Docker Tag 태그는 이미지에 붙은 일종의 포인터 같은 역할을 한다고 볼 수 있겠다. 다운로드할 때 이미지 레파지토리명:태그 를 하면 원하는 이미지를 선택해서 받아올 수 있다. 기존에 있는 이미지의 태그말고 새로운 이미지 태그도 만들어낼 수 있다. docker image ls : 이미지 목록을 보여준다 docker image tag OLD_TAG NEW_TAG : old tag를 가진 이미지로부터 new_tag를 가진 이미지를 새로 만든다. docker image push (AccountName)/IMAGE_NAME: 지칭한 이름을 단 이미지를 레파지토리에 전송한다. 2. Dockerfile (Docker의 빌드과정) Dockerfile은 쉽게 얘기하면 내 이미지를 만드는 레시피를 의미하는 것으로, 지정한 이미지를 어떻게 빌드할 것인지 알려주는 적은 용량의 텍스트 파일이다. Dockerfile 내부에는 여러 단계가 있는데 좀 살펴보자면 FROM debian:stretch-slim : 주로 minimal distribution으로 요즘엔 alpine이 많을 것 ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ ENV NGINX_VERSION 1.13.6-1~stretch : 환경변수를 설정하는 것 ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ RUN apt-get update : Shell에서 실행할 run command. &&로 묶인거는 스크립트를 이어서 실행한다는 의미다.  ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ ~ Blah Blah ~ EXPOSE : 개방할 포트. 자동으로 열리는 건 아니고 -p 커맨드를 줘야 뚫리는 듯 하다. 컨테이너로부터 데이터를 받을 때 사용할 포트 목록. ~ Blah Blah ~ ~ Blah Blah ~...

2019.04.20 - Docker Image와 Image layer, Image를 통해 실행할 때 발생하는 상황

1. What is image? - 공식 설명으로는 An Image is an ordered collection of root filesystem changes and the corresponding execution parameters for use within a container runtime. - 야매로 이해하자면 App 바이너리와 디펜던시 + 메타데이터와 이미지를 실행하는 방법을 포함하는 것이다. - 컨테이너에서 이미지를 실행한다는 것은 VM에서 프로세스를 실행하는 것과 다르다고 했다. 컨테이너를 통해 이미지를 띄워서 실행하면 Full OS를 부팅하지 않고 커널은 호스트에서 제공한다는 점이 VM과 크게 다른 점이다. - 그래서 컨테이너는 그냥 프로세스에 가깝다. 파일 크기는 아주 작을수도 있고 클 수도 있고! command) docker image ls go to hub.docker.com -> can find the tag and you can download the image of your choice specifying the version. (docker image pull mongo:3.6 < will download the exact one) 2. Image layer? - 이미지라는게 하나의 거대한 바이너리들은 아니다. - COW(copy on write) 컨셉을 사용. COW란, write를 하는 시점에 이전에 있는 것들을 copy한다는 것인데 말 그대로 복붙하는게 아니라 기존의 자원 위에 새로운 레이어를 두고 쓴다고 생각하면 되겠다. - 이미지 레이어 컨셉을 쓴다. 처음 업로드를 할 때 레이어가 만들어지고 그 위에 수정이 가해지면 또 이미지 레이어가 생기고. 계속계속 올라가고 생겨난다. 마치 git의 커밋 내역이 생겨난다. - 모든 레이어는 각각의 유니크한 SHA를 가진다. - 우분투 이미지(레이어) 위에 Apt를 설치하고 그 위에 환경변수를 바꿨다면 이 모든 것들이 하나의 이미지이다. ...

2019.04.16 - docker에서 실행한 컨테이너가 제대로 돌고 있을까? DNS RoundRobin check를 통해 컨테이너가 제대로 실행되는지 확인하기

어제 배운 Docker이 네트워크 컨셉을 recap하자면, Host 위에서 기본적으로 컨테이너를 돌릴 수도 있지만 새로운 network bridge를 생성하고 그 위에서 컨테이너를 실행할 수 있다는 것이었다. 그리고 그 네트워크 브릿지 위에서 돌아가는 컨테이너들은 서로 간에 통신이 가능하다는 것이었다. 일단 네트워크를 새로 생성하고 (docker network create helloworld) 준비시킨다. 그리고 이제 새로운 컨테이너는 저 네트워크 위에서 run 시키는데 이 때 그냥 run을 하면 host의 네트워크에서 돌아가므로 옵션에 network명과 network-alias를 같이 주도록 한다. (docker container run --rm -d --network dude --network-alias nginx --name nginx nginx) * --rm : container가 stop되면 바로 지워버린다. * -d : detached, 백그라운드에서 실행. * --network-alias: 네트워크의 알리아스로 아이피주소나 아이디 값 없이 curl을 날리거나 할 수 있다. 자 이렇게 되면 내가 새롭게 생성한 network bridge(dude)에서 nginx가 돌아가고 있는 상태이다. 똑같은 녀석을 하나 더 만들자. 단 이름은 겹치지 않아야 하니 --name nginx2로 바꿔준다. (네트워크 알리아스, 이름은 모두 다 nginx일 필요가 없다. 마지막에 이미지명만 nginx이면 되는데 그냥 헷갈리지 않게 통일했다.) 자 그럼 이제 2개의 nginx가 dude network에서 돌아가고 있다. 이 친구들한테 curl을 날려보고 응답을 받아보자. 이론 상으로는 nginx가 2개이므로 round robin 패턴에 따라 두 개의 id가 로테이션을 돌아야 한다. (100% 라운드로빈은 아니고 그냥 왔다갔다 하나보다) 그럴려면 curl 명령어를 사용하거나 (centos에서) 혹은 nslookup을 사용해야하는데 ...

2019.04.15 - Docker에서 네트워크가 돌아가는 방식, 컨테이너와 네트워크를 붙여주고 inspect 하는 방법, Docker에서 IP에 의존하면 안 되는 이유

1. Docker에서 네트워크가 돌아가는 방식 $ docker container port NAME $ docker container inspect --format '{{ .NetworkSettings.IPAddress }}' NAME <도커의 네트워크 다이어그램> 실제 사용하는 네트워크 - HOST(도커를 실행하는 노드) - ETHERNET < FIREWALL > - NETWORK BRIGDE - CONTAINER(s) - application(image) 눈 여겨 봐야 할 것은 호스트와 컨테이너 사이에 네트워크 브릿지가 있어서 이 브릿지를 통해 호스트와 컨테이너가 통신할 수 있다는 것 이다. 네트워크 브릿지는 사용자가 임의로 추가할 수 있다. 같은 네트워크 브릿지를 사용하는 컨테이너들은 서로간의 통신이 자유롭게 가능하다. 하지만 네트워크 브릿지가 다른 컨테이너가 있다면 걔네들은 호스트를 거쳐서 통신해야 한다. (컨테이너1 -> host -> 컨테이너2.. 이렇게) 아 그리고 --publish 8080:80 or -p 8080:80 옵션의 의미를 명확히 알겠다. 호스트의 8080포트로 들어오는 패킷을 컨테이너의 80으로 넘긴다는 것이다. 그럼 네트워크 브릿지를 통해 80번 포트로 리스닝 중인 컨테이너로 패킷이 넘어갈테고 그 패킷을 적절한 서비스가 처리하게 되는 것이다. 2. 컨테이너와 네트워크를 붙여주기, 새로운 네트워크 만들기, 네트워크 inspect 하기 $ docker network ls : 현재 도커에서 돌아가는 네트워크 목록들이 나타난다 -> bridge(or docker0) : 네트워크 브릿지 -> host : 호스트에 바로 붙어있는 네트워크. 이걸 사용하면 높은 네트워크 퍼포먼스를 기대할 수 있지만 보안 이슈도 잘 생각해야한다. -> none : 커스텀 가능한 넽워크 $ docker network inspect NETWORK_NAM...

2019.04.14 - Docker에서 이미지 다운/실행하기, 컨테이너 상태 확인하기, 각 컨테이너에서 실행중인 프로그램에 옵션주거나 bash 띄우기

Container는 마치 VM 같지만그냥 OS 위에서 돌아가는 프로세스에 가깝고 VM과는 거리가 멀다. 1. Docker에서 이미지 다운받아 실행하기 - docker pull IMAGE : IMAGE를 레파지토리에서 다운받는다. - docker container run IMAGE : IMAGE를 실행한다 (없으면 자동으로 레파지토리에서 받아온다) EXAMPLE) 1) mysql download 및 실행 -> docker container run -d --name mysql -p 3306:3306 -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql -> docker container logs mysql -> 여기에 generated random password가 있어서 이 password를 이용하면 접속 가능 2) apache down / execute -> docker container run -d --name 아파치 -p 로컬에서 넘기는 포트:아파치에서 받는 포트  httpd 3) nginx down / execute -> docker container run -p 8888:80 --name nginx nginx 2. Docker에서 실행중인 Container의 상태 점검 * docker container inspect IMAGE : Docker에서 실행중인 컨테이너의 메타데이터(network, config, volumes...)를 확인한다. * docker top NAME : 해당 NAME의 컨테이너에서 실행중인 프로세스를 보여준다. * docker image ls : docker에 다운 받은 이미지 이름들을 보여준다 * docker container stats [NAME] or None : 해당 NAME의 컨테이너의 상태 (CPU사용률, 메모리 사용률등)을 보여주고 NAME을 입력하지 않으면 모든 컨테이너의 상태가 나타난다. * docker-...

2019.04.10 - Docker run을 할 경우 what's happening ?

$ docker container run --publish 90:3000 nginx를 타이핑하면 실제로 어떤 일이 발생하는가? 1) 로컬에 캐싱 된 이미지를 찾는다. 2) (없으면) remote repository에서 이미지를 찾는다 (기본 레포는 docker hub) 3) 최신버전의 이미지를 받는다. 4) 해당 이미지로 컨테이너를 띄운다. 5) 도커 엔진 내의 사설 네트워크에 가상 IP를 부여한다. 6) 호스트의 90번 포트로 리퀘스트가 들어오면, 컨테이너의 3000번 포트에게 전달해주고 이를 해당 컨테이너 안의 이미지가 실행한다. 7) 이미지 dockerfile을 이용해 컨테이너를 시작한다.

2019.04.09 - Docker 기본명령어

1. Docker 설치 완료 - 윈 10 Home 이하(윈8, 윈7)은 Docker toolbox를 이용해서 다운로드, 설치해야한다. - 얘네는 Docker가 운영체제에 붙어서 돌아가는게 아니라 VM으로 docker용 리눅스를 만들고 그 위에서 돌리는 방식이다. 2. Docker 기본 명령어 $ docker version --> client version과 server의 version이 둘 다 나온다. (server가 안 나온다면 config 수정 필요) $ docker container run --publish 8888:80 nginx $ docker container run --publish 8888:80 --detach nginx $ docker container run --publish 8888:80 --name helloworld nginx -> docker toolbox를 이용하는 경우엔 192.168.99.100:8888 로 접속하면 nginx가 돌아가는 걸 볼 수 있다. 3. Image vs container 이미지란, application을 구동하기 위해 필요한 바이너리, 소스코드, 라이브러리를 총칭한다. 컨테이너는, 이미지가 Process로 running 될 때의 인스턴스를 의미한다. 따라서 하나의 이미지를 통해 여러 컨테이너를 돌릴 수 있다.

2019.04.08 - Docker 강의 수강 시작

Python만 하다보니 가끔은 질릴 때도 있고 실질적으로 기술에 대한 지식 깊이는 깊어져도 폭이 넓어지지는 않는 느낌이라서 즉흥적으로 Docker를 수강하기 시작했다. 1. docker 설치 윈도우는 docker toolbox를 통해 독커를 설치하게 된다. 이 곳( https://docs.docker.com/docker-for-windows/ )에서 Docker를 다운받고 기본값으로 설치했다. Oracle 범용 직렬 컨트롤러 등등 여러 드라이버들이 깔리고 설치가 완료됐다. 근데 Docker toolbox quick start terminal을 실행했더니.. VM에서 에러가 계속 나서 몇번을 지우고 재설치해보고 별 짓 다했는데도 실패 ㅠ 결국 데스크탑이 아닌 노트북에 설치했다. 이거 때문에 오늘 종 침...

2019.04.07 - [Python.Iterable] islice, Flask에 Vue 붙여보기

1. islice는 lazy iterator다. 다른 lazy 동작 방식들이 그러하듯 itertools.islice는 lazy iterator를 반환한다. from itertools import islice def test():     yield from range(0, 10) islice(test(), 0, 10, 2)  -> lazy iterator라서 itertools.islice 객체를 반환하고 next()를 호출할 때마다 값을 하나씩 consume하기 시작한다.

2019.04.04 - [Python.Iterable] iterable, iterator 차이, islice, yield from, nested list comprehension

1. iterable 과 iterator의 차이 1) iterable 정의 : An object capable of returning its members one at a time.  - 가장 대표적인 예로는 sequence type인  list, str, tuple  이 대표적이다.  - 이들은 sequence 타입인데 single element를 하나씩 차례대로 반환할 수 있다. - iter(a: list)로 선언한 뒤에 next(a: list)를 하면 a 안에 있는 값을 하나씩 리턴받을 수 있다. 2) iterator 정의 : An object representing a stream of data.  Repeated calls to the iterator’s  next()  method return successive items in the stream.  - 가장 대표적인 예로는 generator 가 될 것 같다. - next()를 이용해서 커서가 sequence를 한 칸씩 뒤로 이동하며 값을 호출하고, 끝에 도달하면 StopIteration 에러를 발생시킨다. 그렇다면 list는 next(list)하면 에러가 발생하는데 어째서 for문에서는 잘 동작하는거지?!  -> 답은 list를 for문에 집어넣으면 f or문이 자동적으로 iter(리스트: list)를 해주기 때문이다. 참고:  https://bluese05.tistory.com/55 2. itertool의 islice # islice(iterator|iterable, start, end, step) from itertools import islice l = range(0, 10) result = islice(l, 0, 5) list(result) list(result) # islice는 lazy iterator다 == generator...

2019.04.03 - [Python.Iterable] Aggregator

오늘 학습한 내용 1. aggregator란 무엇인가? - iterable을 iterate하며 각각의 element를 고려하고 결과적으로 한 개의 값을 return하는 함수. - 쉽게 말해 min, max, sum 함수가 그러하다 2. Python의 모든 Object는 bool값이 있다. 3. 그 중 Bool값이 True가 아닌 항목들 - None - False - 0 in any numeric - empty mapping types (빈 list, tuple, set등...) - custom classes that implement a __bool__ or __len__ method that returns False or 0 (custom class에 bool, len 매직메소드가 모두 정의되어 있으면 bool을 우선한다. 만약 bool이 없다면 len을 호출한다) 이 외에는 기본적으로 True값을 갖는다. 좀 신기한 경우가 있는데 다 써버린 generator를 bool로 랩핑하면 False이어야 할 것 같지만 True다. 아무런 시그니처도 없는 Class의 인스턴스도 마찬가지이다. 4. predicate란 무엇인가 - 하나의 arg를 받고 True or False를 반환하는 함수