Docker : 이미지 편

Docker 2019. 2. 22. 15:00

Docker 이미지 개요


이번 편에서는 도커 이미지의 생성과 삭제, 이미지의 구조를 알아보려고 한다.


파일에 대한 분산버전관리를 웹 호스팅으로 지원하는 GitHub에서는 계정만 있으면 본인의 프로젝트를 push 할 수 있고 공개된 프로젝트라면 누구나 업로드 된 프로젝트를 pull 할 수 있다.



이와 마찬가지로 도커에서는 Docker Hub라는 중앙 이미지 저장소를 제공하고 있고 도커 계정이 있다면 누구나 업로드, 다운로드가 가능하다는 점에서 GitHub와 비슷하다고 볼 수 있다.


지난 컨테이너 편에서 컨테이너 생성 전에 docker pull 명령어로 묻지도 따지지도 않고 ubuntu 이미지를 내려 받았었다. docker pull 명령을 입력하면 기본적으로 도커 허브(Docker Hub)라는 중앙 이미지 저장소를 바라보고 해당 이미지가 있다면 내려받는다.




Docker 이미지 생성과 삭제


도커 이미지는 지난 컨테이너 편에서 한번 내려받았으므로 먼저 이미지 삭제 후 다시 내려받을것이다.

이미지 삭제는 컨테이너를 지우는 것 만큼 간단하게 할 수 있다. 지난시간에 만든 이미지 목록을 docker images 명령을 입력하여 확인해보자.


# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE ubuntutest_img latest b5d9797d2234 7 days ago 216 MB docker.io/ubuntu 14.04 5dbc3f318ea5 4 weeks ago 188 MB



apache2가 설치된 ubuntutest_img와 도커허브에서 내려받은 공식버전 ubuntu 14.04버전이 목록에 출력 되었다. docker rmi 명령어로 이미지를 삭제한다. (Deleted: sha256:b5d9797d22340d....와 같은 해시코드는 잠시 후 이미지 구조에서 설명하겠다.)


# docker rmi b5d9797d2234 Untagged: ubuntutest_img:latest Deleted: sha256:b5d9797d22340d09f6d3f1ad3bd324e32709c8c79193419ce182dc4241b57685 Deleted: sha256:9fc4083d26906a29c77640dea07a396d3cd8d23536d3a4a9a80249ab8272fe12

# docker rmi 5dbc3f318ea5

Untagged: docker.io/ubuntu:14.04 Untagged: docker.io/ubuntu@sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578 Deleted: sha256:5dbc3f318ea50ea06fca865425e7d2b47fa2baa6094d3cb3760a1721f828a0ae Deleted: sha256:5dfbfe35dbdbb50d4c55416c4f87d870243f1ab00c42c8df3a77fa6169babf5f Deleted: sha256:22ec73a9fd69b430b5e164916e6476bf7fc0963897c4af32e6c3857d3357f023 Deleted: sha256:28df65e350302192e76c49c6157d8c9925c65e9f2f7f882900f42915fa487a02 Deleted: sha256:e8769e218081127b7c313bde4a0ba2cb0107d72167b5c0d198bfb5dadfd81ad6



이미지가 잘 지워졌다.


# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE



이제 콘솔에 docker images 명령어를 아무리 외쳐봐도 텅 빈 Repository만 출력 될 뿐이다.

공허함에 사무쳐 오늘도 눈물을 흘린다.


(저쪽 세상에서도 행복해야해!!)




는 테스트를 위해 재빨리 새로운 이미지를 내려받도록 하자


# docker run -i -t ubuntu:14.04

Unable to find image 'ubuntu:14.04' locally Trying to pull repository docker.io/library/ubuntu ... 14.04: Pulling from docker.io/library/ubuntu e53f134edff2: Pull complete efbbd466a715: Pull complete e11368b8e0c7: Pull complete 7dab2de7692b: Pull complete Digest: sha256:cac55e5d97fad634d954d00a5c2a56d80576a08dcc01036011f26b88263f1578 Status: Downloaded newer image for docker.io/ubuntu:14.04




Docker 이미지의 구조



도커 이미지는 Layer라는 계층구조를 가지고 있다. ubuntu 이미지를 내려받은 시점부터 어떤 변화가 일어나면 도커는 그 내용을 Layer라는 항목으로 저장한다.



도커 이미지의 Layer 정보를 확인하려면 inspect 명령으로 확인 할 수 있다. 방금 다운로드 받은 ubuntu 이미지의 Layer를 확인 해보자.

총 4개의 Layer가 확인 되었다. 


# docker inspect ubuntu:14.04 ...

"Layers": [ "sha256:e8769e218081127b7c313bde4a0ba2cb0107d72167b5c0d198bfb5dadfd81ad6", "sha256:d1b9ba926eff7fe934a15b295c9d86e899aa0d9ebdd9064501ffe28ae6ab3f7f", "sha256:8f9b85d7bbd37cd511f70bb4d25078177cd7f0d2b7644cd7f545b60e084d6b09", "sha256:40f4c1f68b3783868af0759c34c67d7338b0a640b3a452275dd34541424a7f24" ]


Layer가 추가되는 과정을 확인 해보기위해 새로운 컨테이너를 생성하고 docker commit 명령어로  두 개의 이미지를 더 생성한다.


# docker run -i -t --name layer_test ubuntu:14.04

root@c73025587f2b:/# exit exit # docker commit layer_test layer_test:first sha256:48f47ef8257da1311d3bd68d0874b5078075760c5162042b674c009a005e22c8 # docker run -i -t --name layer_test2 layer_test:first

root@d33a60d75c45:/# echo layer_test2 >> test2 root@d33a60d75c45:/# exit exit

# docker commit layer_test2 layer_test:second

sha256:127ab2a395852fb94f21a165c0848961c40b3c098c06dfbb215220953accd5a0



이제 Layer가 어떻게 늘어났는지 각 이미지들의 정보를 확인해보자


# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE layer_test second 303124b8ac57 2 minutes ago 188 MB layer_test first 48f47ef8257d 2 minutes ago 188 MB docker.io/ubuntu 14.04 5dbc3f318ea5 4 weeks ago 188 MB

# docker inspect layer_test:first


...


"Layers": [ "sha256:e8769e218081127b7c313bde4a0ba2cb0107d72167b5c0d198bfb5dadfd81ad6", "sha256:d1b9ba926eff7fe934a15b295c9d86e899aa0d9ebdd9064501ffe28ae6ab3f7f", "sha256:8f9b85d7bbd37cd511f70bb4d25078177cd7f0d2b7644cd7f545b60e084d6b09", "sha256:40f4c1f68b3783868af0759c34c67d7338b0a640b3a452275dd34541424a7f24", "sha256:2e3b0a26611390fb38e16eda5c942b8fa0a8db41097cf57286b3d530b240e809" ]


# docker inspect layer_test:second

...

"Layers": [ "sha256:e8769e218081127b7c313bde4a0ba2cb0107d72167b5c0d198bfb5dadfd81ad6", "sha256:d1b9ba926eff7fe934a15b295c9d86e899aa0d9ebdd9064501ffe28ae6ab3f7f", "sha256:8f9b85d7bbd37cd511f70bb4d25078177cd7f0d2b7644cd7f545b60e084d6b09", "sha256:40f4c1f68b3783868af0759c34c67d7338b0a640b3a452275dd34541424a7f24", "sha256:2e3b0a26611390fb38e16eda5c942b8fa0a8db41097cf57286b3d530b240e809", "sha256:257c7e092ad9a30f4ee28ba63bd7bf296d2ef55244f6cc4ca7952c06e911e666" ]



파란색은 원본인 ubuntu:14.04, 노란색은 layer_test:first, 연두색은 layer_test:second이다.

컨테이너 생성 후 docker commit으로 새로운 이미지가 생성 될 때 마다 레이어가 추가 된 모습을 볼 수 있다.

이해를 돕기 위해 이것을 그림으로 나타내면 아래와 같다. 필자는 이것을 변화의 레이어 화 라고 하겠다.






그런데 여기서 한 가지 의문이 드는 부분이 있다. 이미지 size가 생성 할 때 마다 188MB씩 늘어나고 있는데 그렇다면 매번 commit 할 때마다 용량이 늘어나는것인가? 


# docker images

REPOSITORY TAG IMAGE ID CREATED SIZE layer_test second 303124b8ac57 2 minutes ago 188 MB layer_test first 48f47ef8257d 2 minutes ago 188 MB docker.io/ubuntu 14.04 5dbc3f318ea5 4 weeks ago 188 MB



결론부터 말하자면 용량이 증분 형태로 늘어나지는 않는다. 말 그대로 Layer를 생성하여 이미지 위에 덧 붙인다고 생각하면 쉽다. 원본 ubuntu:14.04의 용량 188MB에 layer_test:first의 용량 1MB 미만, layer_test:second의 용량 1MB미만이라고 보면 된다. 



그럼 layer_test:second는 layer_test:first기반으로 만들어진 이미지인데 layer_test:first가 삭제되면 layer_test:second는 어떻게 되는 것인가?


# docker rmi layer_test:first (?)


이 경우 layer_test:first를 기반으로 두고 있는 layer_test:second가 아직 살아 있기 때문에 layer_test:first의 Layer의 내용은 보존 된 채로 layer_test:first라는 이미지 이름만 사라지게 된다.



여기까지 도커 이미지의 생성과 삭제 그리고 도커 이미지의 구조까지 간략히 살펴보았다. 

도커 이미지의 Layer 구조는 포토샵에서 쓰이는 Layer 기능과 비슷하다고 생각하면 이해가 쉬울 것이다.

이상으로 Docker : 이미지 편을 마치겠다.

(급하게 마치는 감이 없지않아 있는데 절대 시간에 쫓겨서 쓴 글이 아니다.)




Docker : 이미지 편
끝.

'Docker' 카테고리의 다른 글

Docker : Dockerfile 실습 편  (0) 2019.03.22
Docker : Dockerfile 편  (0) 2019.03.07
Docker : 이미지 편  (0) 2019.02.22
Docker : 컨테이너 편  (1) 2019.02.15
Docker : 설치 편  (0) 2019.01.31
Docker : 기초 편  (2) 2019.01.16
Posted by DevStream

댓글을 달아 주세요

INTRO

일정 규모 이상의 정보 서비스를 제공하고 있다면, 아마도 대부분 한대 이상의 서버를 배치하여 부하분산을 시키고 있을 것입니다. 이런 배치 전략을 로드밸런싱이라고 하죠.


로드밸런싱은 대량의 트래픽을 수용하기 위해 여러대의 (동일한) 서버가 요청을 나눠서 처리하도록 하는 부하분산을 통해 서비스의 처리량을 증가 시키고자 하는 것이 주 목적입니다.

 

물론 로드분배 알고리즘과 서버 상태를 기반으로 해서 고가용성(HA)의 요건도 같이 충족되는 것이 일반적입니다.


만일 트래픽이 점점 더 늘어난다면, 그에 맞춰 Service #4, Service #5, ... 이런식으로 서비스의 복제본을 늘려 나가기만 하면 되기 때문에 손쉽게 확장이 가능합니다.


애플리케이션의 확장성을 보장하기 위해서는 다양한 전략을 구사할 수 있습니다. 로드밸런싱은 그 중에서도 트래픽의 처리량을 증가시켜서 서비스의 능력을 향상하는 아키텍처 전략에 해당합니다.


이 글에서는 애플리케이션의 확장성 보장을 위한 다양한 전략을 'Scale Cube'라는  규모 확장성 모델에 근거하여 설명하고자 합니다.



확장성

먼저 소프트웨어 분야의 확장성이라는 개념을 먼저 정리하자. 확장성은 쉽게 말해서,

애플리케이션이 얼마나 손쉽게 확장될 수 있는 가에 대한 가능성에 대한 정도로써 애플리케이션의 여러 품질속성 중 하나이다.


확장성이 좋다는 말은, 애플리케이션의 능력을 손쉽게 향상 시킬수 있다는 의미가 된다.

여기서 애플리케이션의 능력이란, 알고리즘이나 로직과 같은 세부적인 기능 측면보다는 성능/가용성/보안과 같은 비기능적인 요소(이를 품질속성이라 함)에 해당하는 능력을 말한다.


'정보통신기술용어해설'에서는 확장성을 다음과 같이 정의하고 있다.

대규모적인 재설계/재설치 등의 필요없이 확장이 얼마나 쉽고 가능한가에 대한 용이성

확장의 대상과 확장 방식에 따라 확장성을 다음과 같이 세분화 할 수 있다.


1) 규모 확장성

일반적으로 모든 확장성은 규모 확장성을 의미한다. 규모란 용어는 양적인 측면의 크기를 지칭하는 용어로써 특정 대상만을 한정하지는 않는다. 예를 들어 트래픽 처리량에 대한 규모, 데이터 보관량에 대한 규모, 기능의 종류와 양에 대한 규모 등 얼마든지 수식이 가능하다.


다만, 여기서의 규모 확장성은 아래에 설명하는 다른 확장성과 구분하기 위해 트래픽 처리량에 대한 확장으로 한정하고자 한다. 

규모 확장성을 보장하기 위해서는 앞서 살펴본 로드밸런싱과 같이, 동일한 기능을 수행하는 애플리케이션의 복사본을 여러대 구성하여 트래픽 부하를 나눠 가지도록 구성한다. 이런 구성을 Scale out(수평 스케일)이라고도 하며 손쉽게 트래픽 처리량을 확장할 수 있어 흔히 사용되는 방법이다.


규모 확장성을 보장하는 로드밸런싱의 구조를 다시 확인해 보자. Service #1~#3은 모두 동일한 복제본으로 동일한 기능을 수행한다.





2) 기능 확장성
애플리케이션의 기능을 얼마나 손쉽게 추가, 수정할 수 있느냐에 대한 정도이다. 다시 말해, 기존 기능을 확장하거나 새기능을 추가하여 애플리케이션의 능력을 향상시킬 수 있는 가능성에 대한 정도로 풀어 쓸 수 있다.


과거 유행했던 SOA(Service Oriented Architecture)와 근래 유행하는 MSA(Micro Service Architecture)가 바로 기능 확장성 보장하는 아키텍처 구조이다.


MSA는 애플리케이션을 기능 및 역할 관점에서 분리하여 개별 서비스로 구성하고 상호 연동을 통해서 전체 애플리케이션을 구성하는 방식으로 애플리케이션의 독립성과 자율성을 보장함으로써 유지보수와 기능 확장을 용이하게 하는 아키텍처 구조이다.

다음 그림은 애플리케이션이 역할 단위로 분리되어 서로 다른 기능을 제공하는 모습을 보여준다.



3) 데이터 확장성

각각의 애플리케이션이 데이터의 일부분만을 책임지도록 하여 처리 효율을 증가시키거나 데이터 규모에 대한 확장성을 확보하는 기법이다. 데이터 샤딩이나 파티셔닝같이 데이터 자체를 분리하여 저장하는 방식으로 많이 활용되며 경우에 따라서는 애플리케이션 단위의 파티셔닝을 통해 각각이 애플리케이션이 서로 다른 데이터 영역을 책임지게 함으로써 데이터의 처리효율과 애플리케이션의 처리 성능을 향상시킬 수 있다.


다음 그림은 서로 다른 데이터가 서로 다른 저장소에 분리되어 저장된 샤딩된 구조를 보여준다.
여기서 각 Application은 모두 동일한 복제본으로 동일한 기능을 실행하지만 책임지는 데이터 영역이 서로 다르다.


예를 들어, 대량의 데이터에 대한 검색 기능을 개발한다고 할 경우, 다음과 같이 검색 API를 두고 뒷단으로 애플리케이션을 파티셔닝해 그 결과를 조합해서 반환하도록 구성할 수도 있다.




The Scale Cube

'THE ART OF SCALABILITY'라는 책에서는 매우 유용한 3가지 차원의 규모 확장성 모델을 제시한다고, 'Chris Richardson'이 서술한 바 있다.

상단의 그림은 Chris Richardson의 The Scale Cube라는 글에서 발췌해온 것이다. Chris Richardson은 해당 글에서 각 축(axis)에 대해서 설명한다. 글이 짧지만 핵심을 잘 전달해 주고 있으니 일독해 보기를 권장한다.


어느 훌륭한 한국분이 이 글을 번역해서 올려 뒀으니 참고 바란다.
스케일 큐브 (크리스 리차드슨)



X축 확장
애플리케이션의 동일한 복제본을 다수로 구성하여 애플리케이션의 처리 능력을 향상시키는 기법이다.
앞서 살펴본 처리량에 대한 확장성 즉, '규모 확장성'이 바로 이 축에 해당한다.


Y축 확장
애플리케이션의 기능을 역할별로 분리하여 서로 독립적인 서비스로 구성하는 기법이다.
앞서 살펴본 '기능 확장성'이 바로 이 축에 해당한다.


Z축 확장
데이터이 일부만을 책임지도록 하여 데이터 저장과 활용 관점에서 애플리케이션의 처리 능력을 향상시키는 기법이다. 앞서 살펴본 '데이터 확장성'이 바로 이 축에 해당한다




확장성 모델 요약

각각의 확장성 모델을 다음과 같이 하나의 표로 정리해 보았다.




실무 환경

실제 실무환경에서는 각각의 확장성 축이 모두 혼합되어 구성되는 것이 일반적이다. 특히 MSA 아키텍처 구조를 표방하는 애플리케이션들은 거의 대부분 아래와 같은 구조로 설계된다. 즉 모든 축의 확장성을 보장하는 형태로 구성하여 극강의(?) 확장성을 확보한다.

[그림출처: 마이크로서비스 아키텍처로 개발하기(안재우)]

Posted by 사용자 박종명

댓글을 달아 주세요




사내 메신저로 로켓챗을 사용하고 있다. 
이번 글에서는 로켓챗을 채택한 과정과 운영하면서 생긴 이슈와 그를 해결했던 경험을 다루려고 한다.




메신저 선정

메신저를 이용해야 할 인원이 많지 않다면 카카오톡도 좋은 메신저가 될 수 있다. 
하지만 규모가 커지고 다루어야할 주제(단톡방?)가 많아 진다면 한계가 오기 시작한다.
인원 관리도 힘들고 보안에도 좋지 않기 때문이다.

그래서 사내에서 사용할 메신저 서비스를 찾게 되었다.

필요한 조건은 2가지였다.


오픈소스
  • 유지비용이 가급적 들지 않으면 좋겠다.
  • 모두가 신뢰할 수 있는 구조여야 한다.

설치형
  • 데이터 이전이 자유로워야 한다.

처음에는 많이들 사용하는 슬랙이 거론 되었다.
하지만 유지비용과 보안 측면으로 인해 쉽게 선정 결정을 내리지 못했다.

후보로 나온것은 매터모스트, 로켓챗 이었다. 둘 다 슬랙의 기능을 대부분 제공하고 있었다.

이들의 특징으로는 오픈소스 기반에 설치형 버전을 제공한다. 
필요하다면 월사용료를 내고 호스팅과 기술지원을 받을수도 있는 유료모델도 있다.

그 중 로켓챗의 모바일앱이 좀 더 활용하기 편한것으로 보여서 최종적으로 로켓챗으로 선정하였다.
자체적으로 돌릴수 있는 서버가 있었기에 유료모델은 고려하지 않았고 설치형 버전을 사용하기로 하였다.




설치


설치는 리눅스 계열을 추천하는듯 하다. 
Debian(Ubuntu), CentOS 계열에 대한 설치방법을 안내하고 있다.
설치 자체는 심플한 편이다.  링크를 참조하여 진행하면 된다.




운영중 이슈 및 해결


앱에서 푸쉬는 어찌 받을 수 있나

로켓챗은 다양한 방법으로 푸쉬를 지원하고 있다. 푸쉬 관련해서 기본설정으로도 잘 되는 편이다.
하지만.. 로켓챗 푸시서버의 상태가 안좋을 때 푸시가 제대로 서비스 안 될 수도 있기에 다른 방법들에 대해서도 미리 검토를 해보았다.


기본설정 푸시

로켓챗의 푸시 게이트웨이(https://gateway.rocket.chat)를 통해 푸시를 전달한다.
이 푸시는 로켓챗 공식앱을 통해 사용자의 앱으로 푸시가 전달된다.
푸시 발생 후 앱에서 푸시를 받을때까지 보통 2~5초 정도로 응답속도는 준수한 편이다.


자체 게이트웨이 구축

공용으로 쓰는 로켓챗의 푸시 게이트웨이가 가끔 안될 때가 있다. 
지금까지 로켓챗을 1년 넘게 사용해본 결과… 
안되는 상황이, 빈도로 보면 1년에 몇번 정도로 잦은편은 아니다.

하지만 높은 신뢰도가 필요하다면 이것도 불안할 수 있다.
그때는 자체 게이트웨이를 사용하면 된다. 
이와 함께 앱에 들어가는 앱 푸시 정보(APNS, FCM 등)를 마켓 개발자 계정으로 새로 발급받고 앱 소스에 넣어서 새로 빌드 해야한다.

.....이건 쉽게 할 수 있는 작업이 아니다. 
안드로이드 앱은 그나마 개발자 계정 새로 만들어서 배포 하면 되겠지만,
iOS 앱은 개발자 계정으로 설치할 수 있는 기기수 제한도 있고 설치도 불편하다.

나는  자체구축을 포기하고 기본설정 푸시를 사용했다.
혹시 도전하고픈 분들이 계시다면 아래 링크가 도움이 될 것이다.




웹훅 API

레드마인, 젠킨스, 컨플루언스 등 다양한 서비스에서 특정 상황이 되면 
로켓챗에 메시지를 보내주었으면 요청이 있었다.

예를 들자면, 젠킨스에서 빌드가 완료되었을 때 빌드 정보를 로켓챗의 특정 채널 이나 사용자에게 전달해 주는 것이다.

대부분의 서비스에서는 이런 상황을 위해 슬랙에서 사용하는 웹훅API 를 지원하고 있다.
전달할 주소와 인증정보가 필요한데 이것을 슬랙에서 정의하고 서비스 설정에서 넣어서 연동하는 식이다.

로켓챗에서도 슬랙과 동일한 방식으로 웹훅API 연동이 가능하게 되어있다.

메뉴에서 Intergrations > New Integration > incomming webhook 이다.
이곳에서 정보를 등록하고 나온 URL 을 젠킨스 쪽에 넣어주면 된다.

등록해야하는 설정 중 주요 설정은 아래와 같다.

Post to Channel
메시지를 보낼 채널 혹은 사용자의 이름이다. ex) #channel_id , @user_id

Post as
채팅창에 나오는 봇의 이름이다.

Script
일괄적으로 적용하고 싶은 스크립트가 있다면 적는다. 
일반적으로는 비워두고 웹훅을 보내는쪽에서 넣는편이다.

등록을 마치면 WebHook URL 과 Token 이 나온다.

Example 에 있는 예시를 이용하면 커맨드라인 상에서  CURL 을 이용해 메시지를 보낼 수도 있다.

curl -X POST -H 'Content-Type: application/json' --data '{"icon_url":"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQnQFLCYQ-rg_iJFXBzazZjUqMXTHPmTQ-AVU_JymsxleUHI1Oe","text":"Example message","attachments":[{"title":"Rocket.Chat","title_link":"https://rocket.chat","text":"Rocket.Chat, the best open source chat","image_url":"/images/integration-attachment-example.png","color":"#764FA5"}]}' http://[로켓챗주소]/hooks/[토큰]

레드마인, 젠킨스, 컨플루언스 등에서는 각각 슬랙의 웹훅API 와 연동하는 방법이 각 공식사이트에 정리되어 있다.

슬랙과의 연동방법을 참고해서 웹훅API 정보에 위에서 나온 로켓챗 웹훅 API URL 을 넣으면 된다.



젠킨스에서 슬랙 플러그인 설치 후 설정화면




챗봇

특정 메시지에 반응하는 챗봇을 만들고 싶다는 요청이 있었다.

휴봇(https://hubot.github.com/) 이라는 오픈소스로 된 챗봇이 있다. 
이 챗봇에서는 로켓챗에서 적용할 수 있도록 만든 버전을 지원한다.

설치는 아래 링크에서 참고하자.

2가지 설정파일이 필요하다. 환경설정(.env)과 스크립트(.js)이다.

환경설정 파일에는 로켓챗 접속정보를 넣는다.
스크립트 파일에는 봇이 동작할 로직을 넣으면 된다.

특정 문자열이 입력되면 다른 문자열로 고치는 로직을 간단하게 구현한 스크립트 내용이다. 
'onenote://' 라는 내용이 포함된 문자열이 들어오면 그 내용을 'onenotedesktop:' 으로 변경하는 로직이다.

module.exports = (robot) => {
  robot.hear(/^onenote:\/\/\/(.*)/, (res) => {
    var parsedMsg = res.match[1].replace(/\\/gi, "/")
    parsedMsg = 'onenotedesktop:' + parsedMsg
    parsedMsg = parsedMsg.replace(/\s/g, "%20")
    parsedMsg = parsedMsg.replace(/{/g, "%7B")
    parsedMsg = parsedMsg.replace(/}/g, "%7D")
    res.send(`${parsedMsg}`)
  })
}

휴봇 매뉴얼을 참조하면 이것 외에도 다양한 활용이 가능하다.

추가로, PM2 를 이용하면 nodeJS로 만들어진 휴봇 프로세스 관리를 좀 더 수월하게 할 수 있다.





Posted by panpid

댓글을 달아 주세요

머신러닝 관련 코드를 작성해보기 위해 환경을 세팅해보자. 다른 방법들도 많겠지만 가장 많이 쓰는 주피터 노트북을 설치하고 파이썬 패키지를 어떻게 관리할 것인지를 살펴보도록 하자.

주피터 노트북

주피터 노트북(jupyter notebook)은 웹 브라우저에서 파이썬 코드를 작성하고 실행까지 해볼 수 있는 REPL방식의 개발도구이다. 머신러닝이나 데이터분석 용도로 파이썬을 사용하는 사람들이 사용하는 툴로써 가벼우며 코드를 실행하고 수정하기가 간편하다. 또한 notebook형태로 파일이 공유가 가능하다.

REPL(Read–Eval–Print Loop) : 명령어를 한줄씩 입력하며 실행 상황을 지켜보는 방식(대화형)

먼저 파이썬을 설치하자. 파이썬이 이미 설치가 되어있다면 생략 하자.

$ sudo apt-get update                // apt-get 항목 업데이트
$ sudo apt-cache search python3      // 패키지 검색
$ sudo apt install python3.6         // 파이썬 3.6버전 설치
$ sudo apt install python3-pip       // 파이썬 패키지 관리

파이썬 pip를 설치한 후 pip install jupyter 로 주피터 노트북을 설치 할 수 있지만 일반적으로 아나콘다(Anaconda)를 설치하면 Jupyter Notebook이 함께 설치되어 주피터를 사용할 수 있다. 물론 pip를 이용하면 원하는 패키지만 그떄 그때 설치하여 사용할 수는 있지만, 아나콘다를 설치하면 데이터 처리 및 분석에 필요한 패키지가 모두 포함되어 설치가 되기 때문에 약간 설치시간이 오래 걸리긴 하지만 아나콘다를 사용하는 것을 추천한다.

아나콘다(Anaconda) 설치

이 글에서는 Ubuntu18.04 기준으로 설명하도록 하겠다. 또한 최신버전을 위해 반드시 아나콘다 사이트에서 최신 URL을 확인하여 설치를 진행하길 바란다.

$ wget https://repo.continuum.io/archive/Anaconda3-5.1.0-Linux-x86_64.sh
$ bash Anaconda3-5.1.0-Linux-x86_64.sh

계속 엔터를 눌러 설치한다(bashrc등록 여부는 Y로 입력해준다 - 그렇지 않으면 수동설정) 
아나콘다(Anaconda) 공식홈 참고

설치 확인

$ source ~/.bashrc    // bashrc에 등록한것을 활성해 준다
$ conda --version     // 버전확인
$ conda update conda  // 아나콘다 업데이트

만약 삭제하길 원한다면…

$ rm -rf ~/anaconda3
$ vi ~/.bashrc // # added by Anaconda3 installer 제거
$ rm -rf ~/.condarc ~/.conda ~/.continuum

주피터 노트북 실행

$ jupyter notebook


화면에 출력된 http://localhost:8888/?token=***으로 접속하면 된다.
(jupyter notebook --generate-config 명령으로 jupyter_notebook_config.py 파일을 생성하면 해당 파일에서 세부설정이 가능하다.)

접속화면


우측 상단에 New > Python3를 선택하면 새로운 창이 생성된다.

이제 웹상에서 파이썬 코드를 작성하고 실행 할 수 있다.

matplotlib 패키지를 이용하여 가공된 데이터를 그래프로 표현 할 수 있다.


주피터 노트북은 개인 로컬환경에 설치하여 직접 띄울수도 있지만, Microsoft에서는 azure notebook, Google에서는 Colab에서 클라우드상의 주피터환경을 제공해주고 있으니 간단한 학습용로라면 이를 활용하는 방법도 좋을 것이다. 공짜다!

(주피터 노트북 사용법에 대한 부분은 다루지 않겠다.)

더 살펴보자…

아나콘다 가상환경

개발을 위한 파이썬 패키지 가상환경을 별도로 만들고 싶다면 conda에서 지원하는 명령어로 사용이 가능하다. 만약 아나콘다를 사용하지 않고 pip를 사용한다면 virtualenv로 가상환경을 관리 할 수 있다.

$ conda create --name [가상환경명] python=3.6    // 가상환경을 만든다
$ conda info --envs                             // 설치된 가상환경 리스트 확인
$ source activate [가상환경명]                   // 가상환경 활성화

가상환경을 선택하여 활성화를 하게 되면 (가상환경명) winuss@ubuntu:~$와 같이 프롬프트 앞에 해당 가상환경명이 표시가 된다. 이후 패키지를 설치하게 되면 활성화된 가상환경에만 패키지가 설치가 된다.

다시 가상환경을 비활성화하거나 삭제하려면,

$ source deactivate 가상환경명          // 가상환경 비활성화
$ conda remove --name 가상환경명 -- all // 가상환경 삭제

파이썬에서는 한 라이브러리에 대해 하나의 버전만 설치가 가능한데 이는 여러개의 프로젝트를 진행하게 되면 문제가 될 수 있다. 작업을 바꿀때마다 다른 버전의 라이브러리를 설치해야 해야 하는 번거러움을 방지하기 위해 독립된 가상환경이 필요한 것이다.


아나콘다에 패키지 설치

가상환경을 활성화 하지 않고 가상환경명을 지정하여 패키지를 설치 할 수도 있다. mytest라는 가상환경에 tensorflow를 설치 및 삭제를 해보자.

$ conda search tensorflow                 // 패키지검색
$ conda install tensorflow                // 패키지 설치(전역)
$ conda install --name mytest tensorflow  // 패키지 설치(mytest 가상환경)
$ conda list                              // 패키지 리스트
$ conda remove --name mytest tensorflow   // 패키지 제거

주피터 확장기능 설치

주피터 확장기능을 사용하면 좀더 편리한 기능들을 사용할 수 있다.

$ conda install -c conda-forge jupyter_contrib_nbextensions

확장을 활성화 하려면 Nbextensions 탭을 클릭하거나 http://localhost:8888/nbextensions에서 확인 할 수 있다.


참고


Posted by @위너스

댓글을 달아 주세요