일반적으로 딥러닝을 한다고 했을 때 보통 로컬 컴퓨터 (노트북 등) → GPU가 달려있는 Remote server 에 접속하여 사용하거나 server 내에서 docker 를 만들어 사용한다.
- 밑의 그림은 server내에서 docker를 사용하는 경우를 그림으로 나타낸것이다.
여러 블로그를 참고해서 어떻게 어떻게 환경 구성을 하기는 하지만 이를 제대로 이해하고 하고 있지는 않더라. 그래서 새로운 환경을 구성한다는것은 항상 스트레스이다.
또한 최근에 vscode를 원격 server에 존재하는 docker에 연결해서 사용하려고 했는데 무언가 환경이 꼬여 하지못하고 있었다.
이번 기회에 이 프로세스를 이해해서 앞으로 스트레스를 받는 일이 없길 바라며 작성한다...
Local에서 원격 서버에 존재하는 Docker에 접속하기
SSH
The Secure Shell Protocol (SSH) is a cryptographic network protocol for operating network services securely over an unsecured network.
SSH는 보안되지 않은 네트워크 간 안전한 네트워크 서비스를 운영하기 위해 사용되는 암호화 프로토콜이다.
- SSH는 일종의 네트워크 프로토콜이다.
- 보안 되지 않은 네트워크 즉, public network 간 통신을 할 때, 안전성을 보장하기 위하여 사용된다.
- 일반적으로 1) 데이터 통신 2) 원격 제어 에 사용된다.
- 가끔 SCP를 통하여 데이터를 서버로 보낼 일이 있다.
- 원격 서버나 클라우드 서버 접속 할 때 SSH로 접속한다.
- 기본적으로는 22번 포트를 사용한다.
SSH는 어떻게 동작하는가
- SSH 프로토콜은 서버-클라이언트 모델을 따른다.
- SSH는 다음과 같이 동작한다.
- 클라이언트에서 SSH 서버에 대한 연결을 시작한다.
- 서버는 클라이언트에게 public key 라는것을 보낸다.
- 클라이언트는 서버에서 보낸 public key를 file의 형태로 저장한다.
- 클라이언트와 서버의 연결을 위한 parameter 들을 설정한다.
- User가 server의 os system에 접속한다.
- 동작방식을 보면 'key' 라는것을 주고받는데, 이것이 SSH 프로토콜의 핵심같이 보인다.
Public key & private key
- 서버와 클라이언트는 각각 'key'를 가지고 있고 이를 이용하여 서로 인증하고, 안전한 통신을 한다.
- key는 public key와 private key의 쌍으로 이루어져있고, 이를 서버와 클라이언트가 가지고 있다.
- Private key는 클라이언트가 가지고 있다.
- Public key는 서버가 가지고 있다.
- 서버와 클라이언트가 가지고 있는 key가 다르기 때문에 비대칭 암호방식이라 한다.
그래서 어떻게 동작하냐고
- 서버가 public key를, 클라이언트가 private key를 가지고 있다.
- 클라이언트가 key를 이용하여 인증하여 서버에 접속하려 한다.
- 그렇다면 서버는 클라이언트가 private key를 가지고 있는지 알아야 한다.
- 위의 그림을 자세히봐보자
- 클라이언트가 서버에 SSH 연결을 요청한다.
- 서버는 challenge string이라는 랜덤 string을 생성하여 클라이언트에게 보낸다.
- 클라이언트는 서버로 부터 받은 challenge string을 자신이 가지고 있는 private key를 이용하여 암호화 하여 서버에 다시 보낸다.
- 만약 클라이언트와 서버가 적절한 한 쌍의 key를 가지고 있다면 서버는 클라이언트로 받은 암호화된 메세지를 해석 할 수 있다.
- 분명 (2) 단계에서 서버가 challenge string을 만들었다. 즉, 서버는 이 string을 가지고 있다. 클라이언트로부터 받은 암호화된 메세지를 해석하였을때, (2)에서 만든 string과 해석한 string이 일치한다면 인증이 완료된다.
Local computer 에서 remote server 내 docker에 접근하는 여정
- 아니 docker 설명한다면서 ssh를 뭐이렇게 길게 했나 싶다.
- 기억이 안날까봐 맨위의 그림을 가져왔다.
- SSH는 Remote server에 접속하기 위해 필요하다.
- 도커를 빌드 할 때, host OS (remote server)와의 포트 포워딩을 통하여 remote server와 docker가 연결된다.
- Local — (SSH) —- remote server —- (port forwarding) —- docker
원격 서버의 docker에서 Jupyter notebook을 실행해서 local에서 접속하기
- 사실 앞의 모든 과정은 jupyter notebook에 접속하기 위함이었다.
- 이를 말하기전에 jupyter가 어떻게 이루어지고, 우리가 어떻게 웹에 접속 할 수있는지 알아보자.
Jupyter
Jupyter notebook
Project jupyter Project Jupyter is a project and community whose goal is to "develop open-source software, open-standards, and services for interactive computing across dozens of programming languages
- Jupyter에 대해 간단하게 알아보기 전 근본부터 보기 위해 위키피디아에서 가져왔다.
- 여러 프로그래밍 언어에서 interactive한 컴퓨팅을 위한 open source software, open-표준(?), 서비스를 만드는게 목적.
- 근본을 보니 우리가 쓰는 jupyter notebook 이란것은 여러 프로그래밍 언어를 지원하고 interactive한 컴퓨팅이 가능한 무언가라는것을 알 수 있다.
- Jupyter notebook은 jupyter notebook documents 라는것을 생성하기 위한 웹 기반의 interactive한 컴퓨터 환경이다.
Jupyter notebook은 다음의 두가지 요소로 이루어진다.- Web application : notebook은 브라우저 기반으로 동작한다. 웹 기반 어플리케이션이다.
- Notebook documents : 연산 입력 및 출력, 설명 텍스트, 수학, 이미지 및 객체와 같은 web에서 표현 할 수 있는 모든 컨텐츠를 표현 할 수 있다.
- Notebook documents는 내부적으로 json 파일이고, .ipynb 형태로 저장된다.
Architecture of jupyter
- 나는 예전부터 jupyter가 어떤 구조를 가지고 있어서 이렇게 편하게 웹 기반으로 작업을 할 수 있게 해주는지 궁금했다.
- 위의 귀여운 그림을 보자. 이는 크게 보았을 때 jupyter의 architecture를 나타낸다고 볼 수 있다.
- 우리는 브라우저를 통해서 jupyter server와 통신을 하고 내부적으로 notebook file과 kernel이 어떠한 동작을 수행하여 우리에게 응답을 주게 된다.
Kernel
- Kernel은 jupyter application, user interface와 상호작용하는 각 언어별 독립적으로 실행되는 프로세스이다.
- Kernel은 Notebook document를 실행시키기위한 "computational engine" 이다. 즉, 실행환경.
- 가상환경과 유사한 기능을 수행해준다고 이해해도 될 것 같다.
아니 local에서 remote server의 docker에서 실행한 jupyter notebook에 접속 언제하냐고
- Remote server의 docker에서 jupyter server를 키고 local browser에서 접근을 해 사용을 하고싶다.
- Local — (SSH) —- remote server —- (port forwarding) —- docker —- jupyter
- 환형 큐 마냥 Local 과 jupyter가 연결이 되어야 한다.
- 그러기 위해서는 다음의 것들이 되어있어야 한다.
- Local computer와 remote server가 SSH로 연결이 되어야 한다.
- 그러기 위해서 remote server의 포트가 열려있어야 한다.
- Remote server와 도커도 연결이 되어야 한다. 이는 포트 포워딩으로 해결한다.
- Remote server 내에서 jupyter server를 실행시켜야 한다. 만약 remote server에 포트 제한이 걸려있다면 local browser에서 연결 할 수 있도록 허용해준다.
Local computer → remote server
ssh-keygen <option>
1. ssh-copy-id -i ~/path/id_rsa[private_key_path] user_name@remote_ip
2. cat ~/path/id_rsa[private_key_path] | ssh user_name@remote_ip "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys
- 먼저 ssh-keygen을 통해 key를 만들면 ~/.ssh에 key-pair 가 생성된다. 이에 관해서는 다른 블로그에 많이 정리 되어있으니 알아서 참고하시라
- 만들어진 key-pair 중 public key인 .pub 파일을 server측에 보내야 한다.
- ssh-copy-id 혹은 직접 copy를 하여 서버에 public key를 복사하자 [4]
- 밑의 테이블은 혹시나 ssh-keygen의 option에 들어갈 파라미터가 궁금할까봐 넣어놨다.
Remote server → Docker
- Server에서 container를 만들고, run 할 때 port를 매핑해주면 된다.
- 이는 Docker network interface의 port와 server의 port를 연결해주는 과정이다.
- 만만한 docker image하나 pull 해와서 써보자
- nvidia-docker2 까지는 알아서 깔자...
- -p 를 파라미터를 통하여 컨테이너와 host의 8888번 포트와 6006포트들을 각각 연결해주었다.
docker pull ufoym/deepo:all-jupyter-py36-cu90
nvidia-docker run -it --gpus all -p 8888:8888 --name jupyter_test ufoym/deepo:all-jupyter-py36-cu90
Docker → Jupyter 그리고 local computer
- 서버의 아이피 주소를 로컬 브라우저에서 입력하여 접속한다.
- ip:8888
- Local browser → server → container → jupyter 로 이어지는 데이터의 네트워크가 완성되었다.
jupyter notebook --ip 0.0.0.0 --allow-root
Reference
'CS' 카테고리의 다른 글
Deep learning 개발자를 위한 Docker [2] (0) | 2021.06.27 |
---|---|
Deep learning 개발자를 위한 Docker [1] (0) | 2021.06.18 |