• 라즈베리 파이로 Docker Swarm 클러스터 만들기

    사실 처음부터 이 프로젝트를 하려고 한 건 아니였다. 혼자 시작한 프로젝트라면 자비로 모든 하드웨어를 사들여야 하는데, 필자가 그럴 돈이 어디 있는가. 그런데 우연히 학교에서 지원금 빵빵히 받아 프로젝트를 진행하던 친구가 기술 자문 겸 노가다꾼으로 초대해 주면서 열심히 노동하고 왔다. 사실 라즈베리 파이로 클러스터 만들어 가지고 노는 사람들은 이전부터 유튜브 등지에서 종종 봐 왔었고, 관심이 없는 것은 아니였기에 필자에게도 좋은 기회가 아니였나 싶다.

    프로젝트의 목표는 저비용 + 저전력 + 작은 공간에서 분산 컴퓨팅 환경을 직접 구축하고 체험하는 것이다. 물론 이 작은 ARM 보드가 몇개 더 모인다고 해서 프로덕션 단계의 애플리케이션을 돌리는 건 어렵고, AWS 등의 상용 클라우드 서비스를 사용하는 편이 훨씬 더 간단하고 강력하지만, 직접 그와 비슷한 환경을 구축해본다는 것 자체에 의미를 뒀다.

    piluster

    개발자의 본업은 이름 짓는 것이라고 종종 말해왔지만, 이번에는 도저히 시간을 투자할 수 없었다. 나는 한번의 작업을 위해 고속버스를 타고 슝슝슝 달려와야 하는 입장이라 도착도 하기 전에 피로가 한가득 쌓여있었고, 작업 중에도 역시나 생각하지도 않은 문제들이 펑펑 터져나와서 작명이라는 고도의 문학적이고 감성적인 일은 어려웠다. 결국 그냥 라즈베리 파이 + 클러스터 라고 해서 piluster로 퉁 쳤다. 당장 부를 이름이 없는데 어쩌겠는가 :).


    사용한 장비는 위와 같다. 라즈베리 파이 3 5대, 짱짱하고 싼 마이크로 5핀 5개, 외부 전원 공급이 가능한 USB 허브, 그리고 적당한 공유기, 스위칭 허브 (물론 인터넷에서 USB OTG만을 통한 클러스터 구축 방법도 보긴 했지만, 여기서는 가장 범용적인 방법을 선택했다.)

    각 파이에는 당시 최신 버전의 Raspbian Jessie LITE와 Docker Engine이 설치되었다. 이 곳이 곳에서 설치 정보를 참고할 수 있다.

    중간 과정

    사실 이전에 이미 Docker Swarm에 대해 작성한 글이 있다. 그러기에 자세한 내용은 언급하지 않겠으나, 최소한의 구축 방법만 적으려 한다.

    Leader로 삼을 라즈베리 파이에서 docker swarm init 명령어를 통해 Swarm 클러스터를 시작할 수 있다. 아마 아래와 같은 출력값이 나올 것이다.

    Swarm initialized: current node (gjm2fxwcx29ha4rfzkw3zskvt) is now a manager.
    
    To add a worker to this swarm, run the following command:
    
        docker swarm join \
        --token xxx \
        ip_address:2377
    
    To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
    

    저 중 docker swarm join으로 시작하는 출력값을 잘 복사해뒀다, worker로 삼을 파이들에 접속 후 입력하자. 그러면 고맙게도 알아서 차곡차곡 Swarm 클러스터에 노동자로 붙게 된다. 모두 끝났다면, Leader 노드에서 docker node ls 명령어를 입력해 제대로 클러스터가 구성되었는지 확인하자.

    ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS
    aaa *  rpi-01   Ready   Active        Leader
    bbb    rpi-02   Ready   Active
    ccc    rpi-03   Ready   Active
    ddd    rpi-04   Ready   Active
    eee    rpi-05   Ready   Active
    

    위와 비슷하게 출력된다면 별 문제 없다는 뜻이다.

    이제 클러스터가 묶였으니, 가장 중요한 애플리케이션을 올려볼 차례다. ARM용으로 빌드된 어떤 이미지라도 클러스터에 올릴 수 있지만, 필자는 편의상 직접 만든 divergence 웹 애플리케이션을 사용했다. 별도의 DB를 연결할 필요도 없어 여러모로 간편했기도 하고 말이다.

    원하는 이미지를 worker 노드에 다운로드 받은 후, 아래 명령어를 통해 서비스를 생성해보자.

    아래 명령어에 추가로 집어넣을 수 있는 옵션들은 여기에서 확인할 수 있다.

    docker service create --name 서비스_이름 -p 외부포트:내부포트 만든이/이미지_이름:1(컨테이너 갯수)
    

    생성 후에는 docker service ls 명령어로 전체 서비스 목록을, docker service ps 서비스_이름 으로 원하는 서비스의 자세한 정보를 볼 수 있다.

    ID            NAME      IMAGE              NODE     DESIRED STATE  CURRENT STATE            
    id  서비스_이름.1  만든이/이미지_이름:1  rpi-01  Running        Running 3 seconds ago
    

    위와 같이 정상적으로 서비스가 구동된 것을 확인한 후, curl이나 웹 브라우저 등을 통해 미리 지정한 포트로 접근을 해 보면 정상 가동되고 있는 것을 확인할 수 있다.

    여기서 잠깐, 클러스터에 서비스가 딱 한 컨테이너로 실행되고 있는 상태에서 간단한 퍼포먼스 테스트를 해보았다. 사용한 툴은 apib. 소개 그대로 심플한 http 퍼포먼스 테스팅 툴이다. macOS에서 brew를 통해 간단히 설치할 수 있었다.

    60초간 100명의 가상 접속자를 만들어 라즈베리 파이를 괴롭힌 결과, 아래와 같은 값을 얻었다.

    흠. 인터레스팅 하다. 무선 네트워크 간섭 등 여러가지 장애물이 껴 있어 신뢰도 높은 값이라고는 절대 지칭하지 못하겠지만, 추후 부하분산 상태에서의 값과 비교할 가치는 충분히 있어 보인다. 자 그럼, 바로 다음 값을 측정할 준비를 해보자.

    방금 우리가 측정한 서비스는 컨테이너 1개로 돌아가고 있었다. 다시 말해, 클러스터를 묶지 않은 상태와 다를 것이 없다는 뜻이다. 다행히 Swarm 클러스터는 정말 간편하게 이미 돌아가는 서비스의 부하분산 설정을 할 수 있다. 아래 명령어를 따라와 보자.

    docker swarm scale 서비스_이름=컨테이너_갯수
    

    위에서 입력한 숫자만큼 내 서비스의 컨테이너 갯수가 늘어난다. Leader 포함 5개의 노드로 구성된 (Swarm 모드에서의 Leader 노드도 동시에 worker처럼 컨테이너를 돌릴 수 있다.) 클러스터에서 5를 지정하면 각 노드마다 하나씩의 컨테이너가 자동으로 자리잡게 된다. 그렇다고 한 노드에 하나의 컨테이너만 들어갈 수 있는 것은 아니라, 그 이상의 숫자도 얼마든지 지정 가능하다. 이 글에서는 편의를 위해 1노드 1컨테이너. 즉, 5개까지만 복제시켰다.

    docker service ls 명령어 등을 통해 모든 컨테이너가 정상적으로 구동되고 있는 것을 확인했다면, 다시한번 퍼포먼스 테스트를 해볼 차례다. 위 단일 컨테이너 테스트와 동일한 조건값으로 진행하였다.

    오호라. 확실히 평균 지연시간부터 최소 지연시간까지 모두 줄어든 것을 볼 수 있다. 위와 비교해 엄청나게 늘어난 초당 요청 횟수를 통해 여러 컨테이너로 부하분산이 되었다는 것을 확인할 수 있다. 조그만한 라즈베리 파이라도 클러스터링을 통해 확실한 퍼포먼스 향상을 꾀할 수 있다는 것을 직접 눈으로 봤다.

    마무리

    위에서 언급했던 것처럼, 이제는 대부분의 경우에서 물리적 서버 환경을 직접 구축하는 것보다 상용 클라우드 서비스를 사용하는 것이 훨씬 경재적이고 강력한 시대가 되었다. 더군다나 비 x86 아키텍처에 성능도 떨어지는 라즈베리 파이 놀음은 전혀 쓸모없는 짓처럼 보일지도 모른다.

    하지만, 아무리 훌륭하고 편한 솔루션들이 무수히 존재한다고 하더라도 이런 본질로 돌아가보는 행위가 가끔씩은 꼭 필요하다고 생각한다. 다 떠나서 손바닥 위의 작은 컴퓨터 보드 여러대가 네트워크를 타고 하모니를 이루는 광경을 직접 만들고 느끼는 건 정말로 황홀하지 않는가. 저렴한 가격과 적은 전기, 그리고 정말 적은 공간에서 분산 컴퓨팅을 직접 체험해본다는 취지는 훌륭하게 달성한 것 같다. 표면적인 데이터 측정은 끝났으니, 이제 더욱 Geek처럼 가지고 놀 일만 남았다.

  • 라즈베리 파이를 이용한 OpenVPN 환경 구축하기

    이제 VPN 기술은 일부 IT 종사자들의 전유물이 아니게 되었다. 당장 국내에서 가장 대중적으로 판매되는 대부분의 공유기에도 기본적으로 이 기능이 탑재되고 있고, 인터넷 검열국가 대한민국에서 ‘국민에게 해로운 자료를 거른다’ 라는 말 아래에 뭉텅뭉텅 잘려나가는 콘텐츠들을 보기 위해 선택하는 길이기도 하다. 이렇게 겉으로 보기에는 우리 삶에 깊숙히 다가운 VPN이지만, 과연 그 속은 어떨까?

    VPN 터널을 구성해주는 프로토콜은 여러가지가 있지만, 현재 세계에서 가장 대중적인 것은 PPTP다. VPN에 대해 평소 잘 모르는 분들도 이 이름은 한번쯤 들어봤을 거다. 당장 위에서 언급한 대부분의 공유기에 내장된 VPN 서버 기능이 바로 이 프로토콜만을 지원하기도 하고 말이다. 대중화된 만큼 설정법도 간단하고, 정보도 많다. 더 이상의 장점은… 언급하기 어렵다. 다른 문제는 일단 다 내려놓고, VPN의 생명인 보안 문제가 너무너무 크기 때문이다. 개인적으로 암호보안 쪽의 전문가는 아니지만, PPTP의 키 교환 알고리즘이 지금 시점에서는 너무나 간단해서 슝 뚫려버린다 라고 알고 있다. 심지어 애플의 최신 iOS와 macOS에서는 연결 지원 자체를 끊어버렸을 정도. 그러니 아직까지 PPTP를 사용 중인 분들, 또는 앞으로 개인 VPN 서버를 구성하고 싶으신 분들은 한시빨리 대체제를 찾아야 한다.

    L2TP/IPSEC이라는 좋은 선택지도 있고, 다른 훌륭한 프로토콜도 많이 존재하지만 이번에 필자가 꺼낼 것은 OpenVPN이다. 오픈소스에, 안전하고, 대부분의 현대 운영체제를 지원하며, 보안 인증도 상당히 간편하다. 필요할 때 작동시킬 수 있는 컴퓨터만 있다면 다른 준비물은 필요 없다. 다만 필자는 아무래도 설치되는 컴퓨터는 언제나 접속이 가능해야 하는 서버 역할을 해야 하고, 전력과 공간 부분에서 이득을 볼 수 있는 라즈베리 파이를 선택했다. 아래에 후술할 메뉴얼도 라즈베리 파이를 위해 설계된 자동화 도구를 사용할 것이다. 다른 OS나 장비를 사용하시는 분들은 개념 참고만 해주시면 감사하겠다.

    탈바꿈

    반복적인 단순 작업은 지루하고 재미없다. 중간에 정신 놓고 실수를 벌릴 확률도 커진다. 처음 라즈베리 파이에 VPN 서버를 구성하려 할 때 이런 걱정부터 앞섰는데, 다행히 누군가 PiVPN 이라는 자동화 프로젝트를 완성시켜 두었다. 아래 명령어를 통해 바로 내 라즈베리 파이에 다운로드받아 보자.

    curl -L https://install.pivpn.io | bash
    

    미리 PiVPN 측에서 인스톨 스크립트를 잘 만들어둔 덕에, 손가락 빨며 기다리면 된다.


    설치 과정 중 따로 스크린샷을 찍지 못해 이 문서의 자료를 일부 가져왔습니다.

    아마 조금 기다리면 위와 같은 설정 인터페이스가 출력될 것인데, 시키는데로만 하면 된다. 더 이상의 스크린샷은 첨부하지 않겠다. 사용할 네트워크 인터페이스 (유선의 경우 기본 eth0)을 선택하고, 연결에 사용될 네트워크 프로토콜 (UDP 권장)을 고르고, 연결 포트와 암호화 수준, 기본 DNS 서버 정도만 딸깍딸깍 선택해주면 순식간에 끝난다. 아 정확히 말하면 완전 순식간은 아니고, 라즈베리 파이의 불쌍한 연산처리 능력으로 키 암호화를 하느라 조금 걸릴 수는 있다.

    인스톨러를 따라 모든 설정 후 리부팅까지 마쳤다면, sudo apt-get upgrade를 통해 새로 설치된 패키지들이 제대로 최신 버전으로 설치되었는지 확인해 주자.

    이제 정말로 남은 것은 내 OpenVPN 서버에 연결할 수 있는 계정을 추가해주는 일이다. pivpn add 명령어를 통해 간단히 ID와 비밀번호를 집어넣고 계정이름.ovpn으로 끝나는 접속 암호화 키를 받을 수 있다. 이 과정까지 완료되었다면 생성된 ovpn 파일을 내가 사용하는 기기로 옮겨주자. (scp 파일전송을 가장 권장하고, 전통적인 ftp 등 선호하는 방법으로 옮기면 된다.) 만약 라즈베리 자체의 소프트웨어 방화벽 & 상단에 공유기가 존재한다면, 꼭 포트를 열어주는 작업도 잊지 말기 바란다.

    라즈비안의 기본 소프트웨어 방화벽 (iptables) 기준으로, 아래 명령어를 통해 방화벽 룰 포워딩이 가능하다.

    sudo /sbin/iptables -P FORWARD ACCEPT
    sudo /sbin/iptables --table nat -A POSTROUTING -o eth0 -j MASQUERADE
    

    작업을 마쳤다면, root 계정으로 전환 후 아래 명령어로 영구 저장하자. (저장하지 않으면 재부팅 시 방화벽 룰이 기본값으로 복구된다.)

    iptables-save > /etc/iptables/rules.v4
    

    연결

    OpenVPN이라는 이름답게 정말 다양한 플랫폼의 다양한 연결 클라이언트를 선택할 수 있다. 필자의 경우 iOS에서는 공식 OpenVPN 클라이언트 (앱스토어에서 내려받을 수 있다), macOS에서는 Tunnelblick를 애용하고 있다. 클라이언트는 이것 외에도 정말 다양하게 많이 존재하지만, 모두 공통적으로 준비한 ovpn 파일을 선택하고, 설정한 비밀번호만 입력해주면 된다. 본인 취향에 맞추어 원하는 클라이언트를 사용할 것.

  • SMB를 사용하는 macOS Time Machine 백업 서버 만들기


    애플의 macOS는 Time Machine 이라는 환상적인 백업 솔루션을 지원한다. ‘타임 머신’ 이라는 이름에 걸맞게, 각 백업 시점의 스냅샷을 찍어 나중에 언제라도 원하는 시점으로 슝 돌아갈 수 있는 놀라운 녀석이다. 문제는 또 애플 아니랄까봐, 본격적으로 기능 사용을 위해서는 요런 비싸고 성능 떨어지는 물건을 사야 한다는 거다. 애플의 Airport 라우터 시리즈는 정말 최악이다. 가격은 하늘을 찌르는데 유저 편의는 손톱만큼도 신경 쓰지 않는다. NAT 규칙 하나를 변경하기 위해 풀 리부팅이 필요하다고 하면 믿겠는가.

    저걸 살 돈이면 이름있는 브랜드의 새로운 4K 모니터를 마련할 수도 있다. 그럼 어떻게 할까? 백업을 하지 말아야 할까? 아니다. 모든 시스템에는 예외없이 백업이 필요하다. 지갑을 여는 대신, 공돌이 기질을 아낌없이 뽑아내 DIY 원격 백업 시스템을 만들어 보자.

    준비물

    필자는 RAID 5 디스크가 연결된 Ubuntu 16.04 LTS 로 동작하는 서버를 사용했다. 비슷한 사용 환경을 구축할 수 있는 어떤 Linux 배포판이나 디스크라도 상관 없다. 다만, 어디까지나 백업 데이터가 저장되는 서버인 만큼 안정성을 제 1순위로 생각하여 잘 준비하도록 하자.

    그리고 시작하기 전 “왜 애플 기기의 백업 데이터 전송인데 AFP가 아니라 SMB를 사용하지?” 라고 의문이 들 수도 있을 것인데, 애플은 이미 OS X 매버릭스 시절부터 기본 파일 전송 프로토콜을 AFP에서 SMB2로 변경했다. 프로토콜별 퍼포먼스 차이를 자세히 꿰고 있지는 않지만, 기존 AFP보다 SMB2가 의미 있을 정도로 빠르고 효율적이라는 판단이 나와 변경을 감행한 것 같다. 물론 아직 Time Machine 백업은 AFP를 계속 사용하고 있는 것 같고 SMB를 사용하면 여러모로 귀찮아 지는 건 사실이지만, AFP를 Linux에서 사용할 수 있게 해주는 최신 버전의 netatalk가 자체 이슈가 해가 넘어가도록 픽스되지 않고 있어 일종의 편법을 소개하려 한다. 애플이 직접 공인한 SMB2 프로토콜을 사용해 더 나은 속도로 백업을 진행할 수 있기도 하고 말이다.

    Samba 서버 세팅하기

    이미 유닉스 계열 OS들의 파일 공유 표준은 Samba가 자리를 차지하고 있다. 알고 있을수도 있지만, 윈도우에서 사용되던 SMB (Server Message Block)을 다시 구현해 오픈소스화 시킨 소프트웨어다. 위에서 파일 공유의 표준 자리를 차지하고 있다고 한 만큼 이미 많은 Linux 배포판의 패키지 관리 도구들에서 빠르게 설치할 수 있도록 준비를 마쳐뒀다.

    sudo apt-get install samba samba-common-bin
    

    그럼 바로 Ubuntu 배포판 기준으로, 위 명령어를 통해 필요한 소프트웨어를 먼저 설치하도록 하자.

    다음으로 SMB를 통한 접속에 사용할 계정을 만들 거다. 기존 유닉스 계정과는 별개로 취급해야 하니 나중에라도 햇갈리지 말 것.

    sudo smbpasswd -a 유저명
    

    위 명령어로 진행할 수 있다.

    이제 Samba 서버의 설정을 조금 만져주면 된다. 정말 별로 안 남았다. 설정 파일의 경로는 /etc/samba/smb.conf 다. 선호하는 에디터로 해당 파일을 열었으면, 아래를 참고해 주시길 바란다.

    #======================= Global Settings =======================
    
    [global]
    
    ## Browsing/Identification ###
    
    # Change this to the workgroup/NT-domain name your Samba server will part of
       workgroup = WORKGROUP
    
    # server string is the equivalent of the NT Description field
    	server string = %h server (Samba, Ubuntu)
    
    # Windows Internet Name Serving Support Section:
    # WINS Support - Tells the NMBD component of Samba to enable its WINS Server
    #   wins support = no
    
    # WINS Server - Tells the NMBD components of Samba to be a WINS Client
    # Note: Samba can be either a WINS Server, or a WINS Client, but NOT both
    ;   wins server = w.x.y.z
    
    # This will prevent nmbd to search for NetBIOS names through DNS.
       dns proxy = no
    
    ...
    
    

    아마 위와 같은 설정 스크립트가 쫘르륵 나올 것인데, 분량에 겁먹지 말고 찬찬히 읽어보면 전혀 어려울 건 없다. 나머지는 딱히 안 건들어도 되고, 아래의 내용만 [global] 태그 아래에 추가해주자.

    path = 내가_공유할_저장경로
    valid users = 유저명
    writable = yes
    

    공유 프로토콜을 수동 설정하고 싶을 경우 (SMB의 버전 등), 아래의 내용을 넣으면 된다.

    min protocol = SMB1
    max protocol = SMB3
    

    위는 최소 사용 프로토콜을 SMB1, 최대 프로토콜을 SMB3로 설정한 예시다. 본인의 입맛에 맞게 적당히 수정해서 사용하자.

    쉽다. 사실 이 설정 파일에서 공유 경로의 접근 퍼미션도 설정할 수 있긴 한데, 개인적으로는 chown 등의 명령어를 통해 따로 설정하는 것을 추천한다. 이런 중요한 설정은 특정 소프트웨어에 의존성이 생기면 영 좋지 않다.

    모두 저장하고 나왔으면, 이제 아래 명령어로 Samba 서버를 가동해보자.

    sudo systemctl enable smbd
    sudo systemctl start smbd
    

    방화벽을 사용중일 경우, SMB 프로토콜의 기본 포트인 445를 허용해주자. Ubuntu 기준 sudo ufw allow 445 명령어다. 추가적으로 서버 상단에 공유기 등이 달려있다면 알아서 허용해주도록 하자.

    이제 접속할 클라이언트 장비에서 우리 서버로 접속 테스트를 해보자. macOS 기준 아래 독 바의 Finder 아이콘 오른쪽 클릭 -> 서버에 연결 -> 나오는 주소창에 smb://서버주소 로 접속 가능하다. 아래 이미지를 참고하자.


    계정 정보를 물어볼 때는 처음에 설정했던 SMB 전용 계정을 입력하자. 유닉스 계정과 햇갈리지 말고.

    짠. 제대로 진행했다면 아마 정상적으로 접속이 될 것이다. 이제 SMB를 사용하는 파일 서버는 완성되었다. 그럼 Time Machine 백업은 어떻게 할까?

    Time Machine 백업 이미지 만들기

    사실 OS X 매버릭스 시절부터 기본 파일공유 프로토콜이 SMB2로 변경되었다고 해도, 그대로 SMB 파일 서버를 Time Machine 백업 서버로 지정할 수는 없다.(또는 어렵다. 구글링을 열심히 해 봐도 관련 정보가 정말 드물다.) 그래서 우리는 약간의 꼼수를 쓸 꺼다. 바로 별도의 백업 이미지를 만들어 SMB 서버에 담는 것. 이렇게 하면 비단 SMB뿐만 아니라 어떤 종류의 파일공유 프로토콜을 사용하는 서버에도 Time Machine 백업이 가능하다. 마음껏 응용해주면 좋겠다.

    이미지를 만들기 전, 아래 명령어로 지원하지 않는 네트워크 드라이브로의 Time Machine 백업을 허용해주자. 사실 ‘지원하지 않는 네트워크 드라이브’ 라는 말과 달리 여전히 AFP를 통한 파일 서버가 아니면 아무 설정 없이 Time Machine 유틸리티에 드라이브가 뜨지 않는다. 필자도 처음에 기대했었는데 그게 아니더라. 그래서 우리가 별도의 이미지를 만드는 것이다. 이 명령어를 입력해줘야 이미지를 통한 꼼수 백업이라도 가능해지니 눈물을 흘리며 엔터를 누르자.

    sudo defaults write com.apple.systempreferences TMShowUnsupportedNetworkVolumes 1
    

    이제 정말로 이미지를 생성하기 위해 아래의 명령어를 입력하자. 입력하기 전 cd 명령어로 생성을 원하는 경로로 이동 후 진행하면 더 좋다.

    sudo hdiutil create -size 300g -type SPARSEBUNDLE -fs "HFS+J" TimeMachine.sparsebundle
    

    명령어를 읽어보면 알겠지만, 직접 최대 용량과 파일 시스템 등을 지정해줄 수 있다. 적당히 본인에게 맞게 수정하도록 하자. 그리고 혹시라도 300GB의 이미지를 생성하면 바로 300GB를 떡하니 차지하고 있는 것은 아닐지 걱정하지 않아도 된다. macOS의 sparsebundle은 일종의 동적 디스크라, 용량이 들어올수록 점점 늘어난다. 다시 말해, 처음에는 작다는 말이니까 용량 걱정은 하지 말자.

    이제 이미지가 정상적으로 모습을 보일 것인데, 이걸 아까 연결해둔 SMB 서버에 올리기만 하면 끝이다. Finder 창을 연 후 쭉 끌어 놓아주자.

    전부 다 올라갔다면, 이제 서버 위에 있는 이미지를 더블클릭해 마운트해 보자. 약간의 시간이 지나면 둥 하는 소리와 함께 좌측에 내 이미지가 외장 디스크처럼 마운트되어 있는 것을 볼 수 있다.

    이제 백업할 시간이다. 다시 터미널을 열어, 아래 명령어로 Time Machine 백업 경로를 강제 지정해주자. 이렇게 안 해주면 인식을 못하더라. 슬프게.

    sudo tmutil setdestination /Volumes/TimeMachine
    

    이제 Time Machine 유틸리티를 실행하면 정상적으로 우리의 이미지가 안녕 하고 손을 흔들어줄 것이다. 남은 것은 백업 단추를 누르고 커피라도 한잔 마시고 오는 것. 백업이 끝나면 일반적인 외장 디스크를 마운트 해제하는 것처럼 추출 버튼을 누르면 된다. 나중에 백업을 할 때는 위와 마찬가지로 마운트만 해주면 되고.

    처음 Time Machine 백업을 돌릴 때는 저어어어엉말 느리다. 컴퓨터의 말 그대로의 모든 것을 백업해야 하니 이해는 가지만, 그래도 느리다. 이유는 애플이 백업 중에도 다른 작업에 지장이 가지 않게 일종의 리밋을 걸어뒀기 때문.

    느린 속도에 속이 터진다면 아래 명령어로 쓰로틀을 풀어주자. 만약 재부팅할 경우 자동 적용 해제되니 참고하시길.

    sudo sysctl debug.lowpri_throttle_enabled=0
    

    눈에 띄게 속도가 향상됬다면 씩 웃어주자.

  • GitHub 페이지에 웹 애플리케이션 배포하기

    알고보니 이미 필자가 블로그 용도로 애용하고 있는 GitHub 페이지에 DB같은 외부 의존성이 주렁주렁 안 달려있는 웹 애플리케이션 정도는 깔끔하게 올려버릴 수 있었다. 사실 아무리 필자가 서버 만지기를 좋아한다고 해도, 개인적인 작은 웹 서비스 하나를 위해 새로 물리적인 서버 (혹은 퍼블릭 클라우드)를 구축해 운영하는 것은 부담스럽다. 귀찮기도 하고, 비용 측면에서도 무시할 수 없기 때문이다. 이렇게 빛을 보지 못하는 코드들이 전세계 곳곳에 있을 터인데, GitHub 페이지 같은 서비스들이 정말 한줄기 빛을 내려주는 것 같다.

    본론으로 들어가서, 필자는 create-react-app으로 제작한 간단한 웹 애플리케이션을 GitHub 페이지에 업로드할 것이다. 다른 도구를 사용해 앱을 제작하신 분들, 또는 다른 기술을 사용하시는 분들은 본인의 상황에 맞게 적당히 참고만 해주길 바란다. 먼저 본인의 프로젝트를 올릴 수 있는 GitHub 상의 저장소를 준비해 주셔야 한다. 이미 프로젝트를 GitHub에 올려두고 있다면 다음 단계로 넘어가자.

    알맹이

    먼저 내 프로젝트의 package.json 파일에 들어가 homepage 값을 추가하자. 아래와 같은 형태로 집어넣으면 된다.

    "homepage": "https://<GitHub-유저명>.github.io/<프로젝트-저장소>"
    

    그 다음 npm run build 명령어를 콘솔에 입력해보자. 아마 아래와 같은 출력값이 나올 것이다.

    Creating an optimized production build...  
    Compiled successfully.
    
    File sizes after gzip:
    
     45.92 KB  build\static\js\main.bd9efe87.js
     289 B     build\static\css\main.9a0fe4f1.css
    
    The project was built assuming it is hosted at /SithJS/.  
    You can control this with the homepage field in your package.json.
    
    The build folder is ready to be deployed.  
    To publish it at https://<GitHub-유저명>.github.io/<프로젝트-저장소>, run:
    
     npm install --save-dev gh-pages
    
    Add the following script in your package.json.
    
       // ...
       "scripts": {
         // ...
         "deploy": "npm run build&&gh-pages -d build"
       }
    
    Then run:
    
     npm run deploy
    

    package.json에 GitHub 페이지를 홈페이지로 사용한다는 정보를 넣었더니, 친절하게도 알아서 앞으로 어떻게 해야 하는지 과정을 설명해준다. 그럼 저항 없이 컴퓨터님의 목소리를 따라 앞으로 나아가 보자.

    그런데 잠깐. gh-pages 명령어는 처음 보는데, 그냥 무시해도 되나? 당연히 무시하면 안된다. 컴퓨터님이 무리없이 명령어를 소화시킬 수 있도록, npm install --save-dev gh-pages 명령어를 얼른 콘솔에 입력해 미리 플러그인을 추가해 두도록 하자. (gh-pages는 웹 앱의 구동에 필수적인 플러그인이 아니니 --save-dev 명령어로 저장하면 프로덕션 빌드에서는 자동으로 빠져 편리하다.)

    플러그인 추가도 마쳤으니, 다시 package.json을 열고 아래 스크립트를 추가해 보자. 위에서 친절하게 설명받은 그것이 맞다.

    "deploy" : "npm run build&&gh-pages -d build"
    

    짠. 이제 남은 것은 실행하는 것밖에 없다. npm run deploy 명령어를 콘솔에 입력해보자. 아까와 비슷한 출력값이 나오다 Published 와 함께 명령이 종료되면 정상적으로 업로드 된 것이다. 이제 웹 브라우저에서 https://<GitHub-유저명>.github.io/<프로젝트-저장소> 주소로 접속해보자. 본인이 방금 업로드한 그것이 정상적으로 나온다면 성공.

    위 과정 후 내 GitHub 저장소에 들어가보면, 새로운 gh-pages라는 새로운 branch가 생겼고, 그 안에 구동 파일들이 잘 담겨 있을 것이다. 나중에 새로 deploy를 해도 이쪽으로 알아서 갱신되니 걱정하지 않아도 된다.

    필자는 얼마 전 만든 divergence라는 간단한 웹 애플리케이션을 업로드했다. 이렇게 작동하니 참고할 것.

  • 내 자리비움을 발산하라

    정말 말 그대로 모든 것들이 네트워크에 연결되기 시작하면서, 우리는 점점 전통적인 사무 공간에서 벗어날 수 있게 되었다. 개개인에 따라 크게 와닿지 않을 수는 있지만, 세상에는 디지털 노마드 라는 말이 유행할 정도로 건물숲을 뛰쳐나와 내가 원하는 공간에서 업무를 진행하는 사람들이 많이 늘어났다.

    사실 꼭 디지털 노마드 운운할 필요도 없이, 집 근처 카페에만 가 봐도 노트북을 들고 업무를 보는 사람들을 쉽게 발견할 수 있다. 필자도 그런 부류다. 개인적으로 휴식하는 공간인 집과 무언가 머리쓰는 일을 하는 일터(물론 아직 필자는 백수다…ㅠ) 가 한 공간에 있으면 도저히 집중을 못하는 스타일이라 꾸역꾸역 돈 써가며 노트북 들고 카페라도 나가고 있다.

    그런데 말이다. 카페 등의 공공장소에서 업무를 보고 있을 때, 단시간 자리를 비워야 할 경우 어떻게 할 것인가? 휴식이 되었던, 잠깐 전화를 받고 오던, 자리비움은 업무에 꼭 필요한 중요한 일이다. 그런데 카페나 도서관에서는 실행하기 영 어렵다. 내가 내 짐들을 두고 자리를 비웠을 때, 아무도 내가 언제 돌아오고 무엇 때문에 나갔는지 알 수가 없기 때문이다. 이는 곧 다른 이용객들의 눈치, 장소 관리인과의 불화, 심지어 개인 물품 도난으로까지 이어질 수 있다. 물론 카페나 도서관보다 사정이 낫다 뿐이지, 사무실에서도 머릿속을 텅 비우고 벌떡 일어나 룰루랄라 나갈 수는 없다. 언제 누가 나를 찾을지 모르기 때문에, 신경쓰이기는 마찬가지다.

    그럼 어떻게 해야 하는가. 좀 더 편하고 효과적으로 이런 일을 해결하기 위해, 약간의 시간을 투자하여 장난감을 하나 만들었다. 이름하여 divergence 다.

    divergence?


    divergence는 잠시 자리를 비울 때 다른 사람들에게 내가 왜 나갔고, 언제 돌아오는지 알려줄 수 있는 웹 애플리케이션이다. 샤워하고 있는데 갑자기 떠올라서 한시간 끄적거려 만들었다. 이름은 이 글의 제목과 같이 ‘내가 자리를 비웠다는 것을 다른 사람들에게 발산하라’ 정도로 알아주면 될 것 같다. 쓸데없이 거창한 것 같긴 한데 원래 소프트웨어 개발자의 본 업무는 이름 짓기니까 뭐 그렇다고 쳐 줘라.

    언제 있을지 모르는 자리비움 상태를 대비하기 위해 디바이스에 무언가 설치할 필요 없이, 필요가 있을 때 웹 브라우저로 접속하면 되니 편하고 깔끔하다. 같이 확보되는 기기 범용성은 덤이다.

    접속했을 때 출력되는 입력창에 내가 무엇을 위해 자리를 비우는지, 그리고 언제까지 돌아올 것이지 입력하면 창 가득 자리비움 이유와 시간이 출력된다. 이 상태로 밖에 나갔다 오면 끝.

    민감할 수 있는 데이터가 입력되는 만큼 애플리케이션 자체적으로 무언가 기록하고 저장하는 기능은 없다. 애초에 DB도 연결되어 있지 않고. 브라우저를 닫으면 그대로 세션도 닫힌다.

    요즘 관심 가지고 만져보고 있는 React.js 기반으로 디자인했고, 가운데의 타이머 구현을 위해 npm에서 react-countdown-clock이라는 모듈을 하나 받아 사용했다. 개발자님 고마워용.

    아직 누군가가 사용해줄지는 잘 모르겠다. 필자가 보기에는 괜찮은 것 같은데 남이 보면 또 어떨지 모르니까. 그래도 누군가는 좋아해주지 않을까 믿는다. 아무도 내 창작물을 사용해주지 않는다고 생각하면 앞으로 새로운 무언가를 만들 가능성도 0이 되버리니까 말이다.

    • 더 자세한 기술적 내용은 divergenceGitHub 저장소 에서 확인할 수 있다.