• Oracle Cloud로 무료 Wireguard 서버 구축하기

    평생 무료 클라우드 컴퓨팅 서비스라니. 도대체 그런 게 어떻게 가능할까 싶은데, 오라클이 그걸 해냈다. 기존의 AWS나 GCP 같은 전통적 (?) 퍼블릭 클라우드 서비스도 프리 티어나 무료 크레딧 등을 제공했었지만, 대부분 기간 제한이 있고 크레딧을 전부 사용하면 자동으로 과금이 시작되는 구조였다. 사실 그것만이라도 감지덕지하며 사용했던 것이 엇그제 같은데, 이제 그 “프리 티어”가 평생 유지되며 제한없이 사용할 수 있는 서비스까지 등장했다. AWS의 이야기는 아니고, GCP나 DigitalOcean의 이야기도 아닌, 바로 Oracle Cloud의 이야기다.

    AWS 같이 프리 티어라고 완전히 저사양 서비스만 제공하는 것이 아닌, ARM CPU를 사용해야 하는 제약이 있지만 Oracle Cloud는 무려 CPU 4 Core와 24GB RAM을 제공하는 인스터스까지 사용할 수 있다. 사실 ARM CPU를 사용하는 것이 딱히 제약이라고 말할 수도 없다. 요즘의 ARM 프로세서는 퍼포먼스와 에너지 사용량 측면에서 모두 기존 x64 CPU를 압도하고 있다. 애플리케이션을 ARM64 아키텍쳐로 새로 빌드해야 하는 것만 제외하면, 오히려 업그레이드라고 생각할 수도 있는 것이다.

    처음 이 평생 무료 클라우드 서비스에 대해 들었을 때, 바로 든 생각은 바로 상시 사용할 수 있는 VPN 서버를 구축하는 것이였다. 물론 기존에 다룬 라즈베리 파이로 OpenVPN 서버를 구축하는 글 과 같이 이미 개인용 VPN 서버를 구축해 집에서 사용하고 있긴 하지만, 어디까지나 개인 인터넷에 개인 IP를 사용해야 한다는 점은 변하지 않는다. 만약 VPN을 사용해 안전하지 않은 네트워크에서의 통신의 암호화를 넘어, 더 나은 익명화와 개인정보 보호를 생각하고 있다면 나와 직접 연관되지 않은 퍼블릭 IP를 사용할 필요가 있다. 더군다나 한국의 인터넷 검열을 미꾸라지처럼 빠져나가려면, 해외 IP를 사용할 수 있어야 한다.

    이런 점을 생각했을 때, 평생 무료 인스턴스를 제공하고 해외 여러곳에 데이터 센터가 존재하는 Oracle Cloud는 굉장히 매력적인 선택지가 될 수 밖에 없다. 한국에서 가까운 일본에도 2곳의 데이터 센터를 가지고 있으니, 더할 나위 없다.

    그럼, 빠르게 본론으로 넘어가 Oracle Cloud의 일본 데이터센터에 무료 인스턴스를 생성하고, OpenVPN 서버를 구축해 보자.

    Oracle Cloud에 인스턴스 생성하기

    Oracle Cloud에 빠르게 회원가입을 한 후, Compute - Instances 탭에서 새 가상 인스턴스를 생성할 수 있다.

    os_to_ubuntu

    먼저 OS부터 지정해 보자. “Always Free-eligible”에 해당되는 이미지 중 어떤 것을 골라도 비용은 청구되지 않지만, 우리는 빠른 VPN 서버의 구축을 위해 Ubuntu를 선택하자.

    instance_spec_configuration

    이제 가장 중요한 사양 설정이 남아있다. 기본 설정인 AMD 인스턴스를 사용하면 겨우 1vCore에 1GB 사양만을 제공받지만, ARM 기반 인스턴스를 선택하면 최대 4vCore와 24GB RAM까지 할당받을 수 있다.

    instance_free_spec_limit_screenshot

    평생 무료 조건으로 제공받기에는 실로 엄청난 사양이 아닐 수 없다. 우리는 그냥 입 꾹 다물고, 감사합니다 하면서 받으면 된다.

    한번에 4vCore와 24GB를 할당하지 않고, 작은 사양으로 쪼개서 여러 인스턴스를 생성할 수도 있는 것으로 안다. 2vCore와 12GB RAM을 가진 인스턴스 2개를 생성하는 식으로 말이다. 고로 필요에 맞게 사양을 지정해 주자. 필자는 오직 VPN 용도로만 Oracle Cloud를 사용할 예정이기에, 한번에 4vCore와 24GB RAM을 몰빵했다.

    instance_configuration_done

    설정을 마무리하고 인스턴스를 생성하면 위와 같이 접속에 필요한 공인 IP와 계정 이름 등이 보일 것이다. 인스턴스 생성 중 추가한 PEM 키와 함께 SSH 접속을 해보자.

    ssh -i <PEM_KEY_경로> ubuntu@<내_인스턴스_공인_IP>
    

    정상적으로 접속된다면 다음으로 진행해 보자.

    OpenVPN 서버 설정하기

    이제 인스턴스는 잘 생성되었고, WireGuard 서버만 구축하면 된다. WireGuard 서버를 구축하는 법은 여러가지가 있겠지만, 필자는 평소 애용하는 툴인 PiVPN을 사용할 예정이다.

    WireGuard는 기존의 VPN의 표준이였던 OpenVPN을 넘어서는, VPN 프로토콜의 신흥 강자로 떠오르는 기술이다. 더 작은 오버헤드로 인한 더 나은 속도, 덜 복잡한 코드베이스로 인한 쉬운 코드 취약점 파악과 디버깅, 그리고 모바일 환경에 유리한 더 나은 네트워크 전환 처리까지, 거의 모든 부분에서 OpenVPN의 상위 호환으로 기능하는 그 특정 덕분이다. 덕분에, 기존에 OpenVPN을 사용했거나 사용 예정이라면, 별 고민 없이 WireGuard로 기술만 다르게 선택하면 나머지는 OpenVPN을 사용할 때와 큰 차이 없이 더 나은 사용자 경험을 누릴 수 있어 유저 입장에서는 더할나위 없는 새로운 기술이다. 필자도 이번에는 WireGuard를 선택해서 글을 진행하고자 한다.

    이름만 들어서는 라즈베리 파이를 위한 VPN 구축 도구 같지만, 사실 Debian 기반 리눅스 배포판에서는 어떻게 실행해도 전부 잘 동작하는 유연한 도구다. 라즈베리 파이용으로 디자인된 만큼 ARMv7 / ARM64V8 아키텍쳐도 문제 없고, 일반 AMD64 인스턴스나 심지어 IBM Z 메인프레임 규격인 S390X에서도 너무나 쌩쌩하게 잘 동작한다. 개인적으로 Debian 환경에서 가장 쉽고 빠르게 WireGuard 구축할 수 있는 도구라고 생각한다. 개발자 분에게 압도적인 감사를 표한다.

    설치와 구축은 아래 명령어 한 줄로 시작할 수 있다.

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

    혹시 WireGuard가 아니라 OpenVPN의 사용을 원할 때는, 필자가 이전에 작성한 이 글을 참고해 보시기 바란다.

    설치 과정 중 복잡한 내용은 없다. OpenVPN과 WireGuard중 사용하고 싶은 걸 선택하고 (이 글에서는 WireGuard를 사용), 내가 VPN에 사용할 DNS 정보나, OpenVPN이 사용할 포트 등을 지정해 주면 끝난다.

    WireGuard-port-select

    Port는 기본으로 UDP 51820이 선택된다. 필요할 경우 변경해주자.

    pivpn-unattended-upgrade

    설치 중간에 Debian의 Unattended Upgrade를 사용할 것이냐 물어본다. 만약 약간의 다운타임은 크게 문제 없이 넘길 수 있고, 항상 최선 버전을 유지하는 걸 중요하게 생각한다면 Yes를 눌러 켜 주는 걸 추천하고, 그게 아닌 대부분의 유저에게는 No를 눌러 허용하지 않는 걸 추천한다. 이론만 생각한다면 언제나 모든 패키지를 항상 최신으로 유지하는 게 가장 좋지만, 그만큼 예상하지 못했던 호환성 문제 등을 경험할 수 있다. 특수한 경우가 아닌 이상 업데이트는 직접 관리해주는 걸 추천한다.

    이후, WireGuard에서 사용할 유저 정보를 생성해 주자.

    pivpn -a
    

    pivpn-wireguard-user-add

    간단히 사용할 유저네임만 입력하면 생성이 완료된다.

    pivpn-wireguard-qr-code

    재미있는 점은 계정이 생성된 이후에, QR코드를 통해 쉽게 모바일 기기에 추가할 수 있다는 점이다. 아래 명령어를 통해 QR코드를 생성해 보자.

    pivpn -qr
    

    pivpn-wireguard-mobile-connected

    QR코드를 스캔해 VPN 설정을 추가하고 나면 위와 같이 쉽게 연결할 수 있다.

    pivpn-wireguard-ip-changed

    마지막으로 내 IP 주소가 정상적으로 변경되었는지 확인 한번만 해주자.

    마치며

    이제 우리는 일상에서의 트래픽 암호화 + 한국 인터넷 검열 우회를 위해 유료 VPN 서비스를 찾아나서지 않아도 되게 되었다. 각종 제한이 걸린 상태로 설치되어 있던 무료 상업 VPN 서비스도 지워도 된다. 이제 안전하게, 또 확실하게 나만의 VPN 서버를 사용해서 걱정없이 인터넷을 자유롭게 날아다닐 차례다.

    이 글이 일상에서의 약간의 더 프라이버시를 원하는 많은 사람들에게 도움이 되었으면 좋겠다.

  • HollaEx로 나만의 암호화폐 거래소 만들기

    nyancoin

    글쎄 말이다. 사람들은 암호화폐가 보이지 않는 허상이라고 하는데, 그 말에 정면으로 반박하듯 관련 산업은 나날이 커지고 있다. 업계가 무르익고 기술이 무르익으며, 이제 클릭 몇 번, 키보드 타이밍 몇 번이면 나만의 암호화폐 거래소도 열 수 있는 시대가 되었다. 이게 무슨 소리냐고? 바로 HollaEx (홀라엑스) 얘기다.

    HollaEx는 필자가 몸담아 일하고 있는 bitHolla (비트홀라) 에서 만든 암호화폐 거래소 솔루션이다. 뭐, 기술적으로는 암호화폐 거래소 뿐만 아니라 거래를 필요로 하는 모든 분야에 사용할 수 있지만, 어쨋든 그렇다. HollaEx를 사용하면 암호화폐 거래소를 만들 기술이나 기반이 부족하더라도, 약간의 노력만 기울이면 나만의 거래소를 뚝딱 만들 수 있다는 말씀. HollaEx 자체는 수년 전에도 존재했고, 진작부터 HollaEx를 사용해 만들어진 실제 거래소도 있지만, 이번 리뉴얼을 거치며 그 접근성을 한껏 끌어올렸다.

    필자를 포함한 팀원들의 오랜 노력과 쌓인 경험을 기반으로, HollaEx는 거래소를 열기 위한 모든것이 들어있는 키트 형태로 탈바꿈했다. 생존 키트를 열면 깊은 지식이 없는 사람이라도 극한 환경에서 살아남을 수 있는 것처럼, HollaEx 키트를 열면 깊은 지식이 없어도 내 거래소를 만들 수 있다 (사실 비유가 아니라, 정말로 이름이 HollaEx Kit 인건 안비밀).

    사용 준비

    지금이라도 당장 누구나 GitHub에서 HollaEx Kit를 살펴보고 다운로드 받을 수 있다.

    hollaex_kit_main

    다운로드를 다 받았다면, 안에 들어있는 여러 파일들 중 install.sh 가 보일건데, 바로 귀염뽀짝한 HollaEx CLI를 설치하는 귀염뽀짝한 인스톨러다. 컴퓨터는 인간을 위해 존재하는 도구라 했던가, 이 CLI는 여러분이 어려워 할 거래소 초기 셋업부터 실제 실행, 이후의 유지보수까지 전부 도맡아서 도와줄 굉장히 엄청난 도구라고 하겠다. 절대 필자가 만들어서 띄워주는거 아니다

    지금 이 글을 Linux 혹은 macOS에서 읽고 있다면, 아래 명령어를 통해 인스톨러를 실행시켜 바로 HollaEx CLI를 설치할 수 있다.

    bash install.sh
    

    만약, 애석하게도 Windows라면, 이 문서를 참조하자. Windows 10 2004 빌드부터 정식으로 포함된 WSL 2를 사용해 HollaEx Kit을 실행시킬 수 있다.

    무언가 주르륵 뜨고 대충 설치가 된 것 같다면, hollaex version 명령어를 실행해 보자. 아래와 같이 이쁜 HollaEx 로고와 버전 넘버가 출력된다면, 제대로 HollaEx CLI가 설치된 것이다.

    hollaex_version

    여기까지 따라오셨다면 전체 과정의 30%는 끝낸 것이다. 정말이다. 남은 70%는 아래의 것들이 있다.

    • HollaEx 거래소 초기 설정 : 거래소의 관리에 사용할 관리자 계정과 거래소 이름 등을 HollaEx Network에 생성, 등록해야 한다.
    • SMTP 서버 설정 : HollaEx는 유저 회원가입 등의 인증 작업을 위해 표준 SMTP 기술을 사용한다. 만약 기존에 사용하던 SMTP 서버가 있다면 그것을 사용해도 되고, 새로 만들어야 한다면 어떤 SMTP 제공자의 서비스라도 사용할 수 있다. SMTP 서버 주소와 포트번호, 사용자 계정만 준비하면 된다.

    HollaEx 거래소 초기 설정하기

    가뜩이나 복잡할 것 같은 거래소인데 설정하는 건 얼마나 더 복잡할까 하셨던 분들이라면 걱정을 놓아도 되겠다. 방금 설치한 HollaEx CLI를 통해, 거래소 초기 설정과 실행을 한번해 해결할 수 있다. 채널 고정하고 잘 따라해보자.

    진행하기 전 내 컴퓨터에 Docker와 Docker-Compose, 그리고 JQ가 설치되어 있는 지 꼭 확인하자. 만약 Debian (Ubuntu 등) 환경을 사용한다면, 조금 전의 CLI 설치 단계에서 자동으로 인스톨러가 Docker와 같은 의존성 프로그램들을 설치해줬을 것이니 걱정하지 않아도 된다.

    hollaex server --setup
    

    hollaex_login

    hollaex server --setup을 먼저 CLI가 HollaEx Network를 선택하라고 한다. 여기서 HollaEx Network는, 내 HollaEx Kit 거래소가 연결되어 거래를 진행하고 거래 Liquidity 풀이 연동될, 일종의 중앙 집중 거래 풀이다. 모든 HollaEx Kit은 HollaEx Network에 연결되어 데이터를 주고받고 거래 작업을 처리한다.

    만약 프로덕션에서 사용할, 진짜 돈을 가지고 움직이는 거래소를 바로 생성하려면 기본 옵션인 1번, 테스트 목적의 거래소를 생성하려면 테스팅 전용 네트워크인 2번, 마지막으로 나만의 HollaEx Network를 가지고 있을 경우(일반 유저에게는 제공되지 않는 엔터프라이즈 서비스) 3번을 선택해 내 네트워크에 직접 연결할 수 있다.

    우리 예제에는 간 크게 프로덕션 네트워크인 1번을 선택해 진행해 보도록 하자.

    다음 단계로 CLI가 Docker 이미지를 하나 빌드할 것인데, 이건 내 HollaEx Kit의 모든 코드를 포함하는 나만의 커스텀 HollaEx 이미지가 되겠다. 코드는 완전한 오픈 소스로 공개되어 있어, 나의 입맛에 맞게 얼마든지 커스터마이즈가 가능하다. 물론 지금은 이대로 진행해도 무방하다.

    hollaex_setup_image_build_and_push

    빌드된 이미지는 원하는 이름을 입혀 자유롭게 Docker 레지스트리에 푸시할 수 있다. 푸시를 하지 않아도 무방하지만, 백업의 목적으로라도 어딘가에 사본을 남겨두는 걸 추천한다. 만약 쿠버네티스에 HollaEx를 배포하고 싶어 한다면, 레지스트리 푸시는 필수다.

    빌드가 끝나면 이제 HollaEx CLI가 알아서 필요한 컨테이너를 생성하고, 데이터베이스 작업을 하고, 필요한 모든 것을 구성한 후, 작업이 모두 끝났다고 알려주며 거래소를 종료할 것이다. 유저는 아무것도 안 하고 아래와 같은 메시지가 뜰 때까지 가만히 멍 때리면 된다.

    hollaex_setup_all_done

    거래소 시작하기

    이제 hollaex server --start 명령어를 입력해 완성된 거래소를 시작시킬 수 있다.

    hollaex_start

    음.. 일단 무언가 시작 되었다고는 떴는데, 이게 제대로 돌아가고 있는 건지 눈에 보이는 게 없다.

    걱정 말자. 지금부터 거래소가 제대로 돌고 있다고 찬찬히 확인해볼 것이다.

    hollaex status
    

    이 명령어는 현재 내 컴퓨터에서 실행되고 있는 HollaEx 서버 Docker 컨테이너 목록과, 거래소 상태를 체크하는 Health API를 호출해 터미널에 보여줄 것이다. 바로 요렇게.

    hollaex_status

    아예 직접 거래소 API를 호출해 볼 수도 있다. 브라우저를 띄우고 초기 설정에서 입력한 내 도메인 주소를 쳐보자. 만약 DNS를 설정하지 않았다면, 지금이라도 내 DNS 설정에서 내 컴퓨터 (또는 서버)의 IP를 가르켜 주자. 만약 기본값과 같이 localhost로 설정했다면, http://localhost 주소로 거래소 API에 접근 할 수 있다.

    http://<내_도메인>/v2/health 페이지에 접속해 거래소가 정상적으로 동작하는지, 활성화 상태는 어떤지 확인할 수 있다.

    hollaex_health_localhost

    http://<내_도메인>/v2/constants 주소로 접근하면 지금 내 거래소에 등록된 코인과 거래 페어 리스트를 볼 수 있다.

    hollaex_constant_localhost

    Constants 정보까지 제대로 출력된다면, 거래소 서버가 정상적으로 동작되고 있다는 소리다. 축하한다. 우리는 방금 거래소 서버를 뚝딱 만들었다. 거래 채결 엔진부터 REST API, 웹소켓까지 전부 말이다. 짝짝짝

    그런데, 뭔가 조금 부족하다. 분명 머릿속으로 거래소가 돌고 있다는 건 알지만, 눈에 보이지 않으니 아직 뭔가 빠진 것 같다. 그래서 준비했다. 거래소 웹 클라이언트.

    거래소 웹 서버 띄우기

    물론 REST API가 제공되니 원한다면 사용자가 처음부터 개발해 웹 클라이언트를 만들 수도 있겠지만, 우리한테 그럴 시간은 없다. 그렇다면? HollaEx Kit에 포함된 기본 웹 클라이언트를 사용하면 된다. 이미 다운로드 받은 HollaEx Kit 폴더의 /web 폴더가 바로 웹 소스가 들어있는 곳이다. 오픈 소스 프로젝트인 만큼 사용자가 코드를 보고 씹고 뜯고 맛보고 즐기며 마음대로 커스터마이징도 가능하다.

    다만, 지금은 일단 기본 코드 그대로 띄워보고 거래소가 제대로 동작하는지 느낌부터 받기로 하자.

    hollaex web --setup
    

    이 명령어로 /web 폴더의 소스를 빌드해 Docker 컨테이너로 만들고, 서버를 띄울 수도 있다.

    혹시라도 빌드 중 “Heap out of memory” 등의 에러가 발생한다면. 컴퓨터의 Docker 데몬에 할당된 메모리 상태를 체크하자. HollaEx 웹 클라이언트는 보기보다 꽤나 복잡한 과정을 거쳐 빌드된다. 이 과정에서 최소 4기가 이상의 메모리가 요구됨으로, 아래와 같이 메모리 할당량을 높혀주도록 하자.

    dockerd_memory_allocation_configure

    빌드가 끝나고 정상적으로 웹이 실행된다면, 이제 내가 설정한 도메인 혹은 localhost:8080 주소로 접근할 수 있다!

    hollaex_web_main

    처음 거래소에 접근하는 상황이라, 초기 설정을 진행할 수 있는 설정 마법사가 여러분을 반겨줄 것이다. 버튼을 눌러 차례차례 진행하면 된다.

    hollaex_web_main

    가장 먼저 생성할 것은 거래소에서 사용할 관리자 계정이다. 사용할 이메일 주소와 비밀번호를 집어넣고, 다음으로 진행하면 된다.

    hollaex_web_main

    계정을 생성했다면, 이제 거래소의 시스템 설정을 여기저기 만질 수 있다. 거래소의 시간대 (Timezone)부터, 언어나 기본 OTP 설정 등을 진행할 수 있다.

    다른 것들도 눈여겨 봐야 하지만, 여기서 가장 중요한 건 바로 이메일 설정이다. SMTP 이메일 설정이 일단 완료되어야 신규 유저가 가입했을 때 인증 이메일을 받을 수 있고, 여러가지 시스템 알림도 날아온다.

    hollaex_web_main

    미리 준비해둔 SMTP 서버 정보를 입력하고 다음으로 진행하면 끝!

    hollaex_signin

    가슴이 웅장해지는 로딩 애니메이션을 보고 있으면, 금방 모든 설정이 완료된다. ‘Enter your exchange’ 버튼을 눌러 거래소에 정말로 진입해보자!

    web_successful_login

    이제 정말로 완전한 거래소가 완성되었다. 만약 내가 생성한 코인 / 페어의 승인까지 완료되었을 경우, 위 스크린샷과 같이 메인 화면에 내 커스텀 코인과 페어도 함께 출력될 것이다.

    이제 HollaEx 웹을 커스터마이징 하거나, 거래 채결 기술만 API로 따와 다른 서비스에 사용하거나 하는 등 다양한 용도로 원하는 곳에 사용할 수 있다.

    Admin 페이지 둘러보기

    hollaex_admin_main

    최신 버전의 HollaEx Kit은 거래소 운영과 관련된 설정을 진행하거나, 유저 정보를 조회할 수 있는 어드민 패널 기능을 제공한다.

    hollaex_admin_plugins

    특히, Plugins 탭에서는 거래소를 위한 추가 기능을 활성화 할 수 있다. 유저를 위한 채팅방 기능부터, 공지 기능, KYC (개인정보 인증), SMS 인증 기능까지 많은 플러그인들을 기본적으로 제공하고 있다. 모두 첫 설치에는 비활성화 되어 있으니, 찬찬히 둘러보고 나에게 필요한 기능을 켜면 끝. 위 스크린샷에는 플러그인 목록이 비어 있지만, 정식 출시 버전에는 문제없이 여러 기본 플러그인들이 보일 것이다.

    hollaex_admin_plugins

    여기서 재미있는 건 HollaEx는 아주 강력한 커스텀 플러그인 기능을 지원한다는 것인데, 이렇게 ‘My plugins’ 메뉴에서 .json 형태로 된 플러그인 파일을 드롭하면 간단하게 거래소에 내가 원하는 기능을 추가할 수 있다.

    이를 잘 활용하면, 각 국가에 맞는 로컬라이징 앱 (대한민국 신용카드 결제 등)을 얼마든지 추가해 경쟁력 있는 거래소로 만들어 나갈 수 있을 것이다. 재미있는 건 덤이고 말이다 :)

    그 외 어드민 패널의 각 탭 모두 직관적인 인터페이스를 제공하고 있으니, 하나하나 눌러보며 무엇이 가능한지 살펴보는 시간을 가져보는 것을 추천한다.

    외부 접속을 위한 도메인 연결하기

    찬찬히 내 거래소를 둘러보며 별 문제 없는 것을 확인했다면, 이제 외부에 거래소를 공개해 다른 사람들도 접근할 수 있게 해보자. HollaEx CLI는 간편하게 거래소에 도메인을 연결하고, 원할 경우 SSL 인증서도 같이 발급할 수 있는 기능을 지원한다.

    내 HollaEx Kit 경로에서, 아래 명령어를 실행해 보자.

    hollaex prod
    

    hollaex_prod

    Y를 입력해 다음으로 진행하면, 내 도메인을 입력할 수 있는 창이 나온다. 예를 들어, 내가 mydomain.com 이라는 도메인을 소유하고 있고, 이걸 거래소 웹 페이지에 사용하고 싶다면 mydomain.com을 입력하자.

    입력하고 엔터를 누르면, CLI가 자동으로 내가 입력한 도메인을 바탕으로 거래소 API 서버의 접속 주소도 같이 추천해준다 (거래소 웹페이지가 서버와 통신할 때 사용된다). 대부분의 사용자가 api.mydomain.com / mydomain.com 과 같은 형태로 사용하나, 따로 원하는 API 도메인이 있을 경우 자유롭게 수정할 수 있다.

    검토 후 다시 Y를 입력해 진행한다.

    hollaex_prod_dns_configurartion

    위와 같은 안내를 맞닥뜨렸다면, 이제 DNS 설정이 필요한 때다. 내 도메인의 DNS 설정해 조금 전 입력한 거래소 웹사이트 도메인과 거래소 API 서버 도메인을 내 서버 (컴퓨터)의 IP 주소와 연결시키자. DNS 설정은 주로 내가 도메인을 구입한 사이트에서 진행할 수 있다.

    모든 DNS 설정이 완료되었다면 CLI에서 엔터 키를 눌러 진행하자. DNS 설정은 정보가 인터넷 전체로 전파되어야 하는 특성 상 반영에 약간의 지연이 있을 수 있으니, 만약 엔터 키를 눌러도 CLI가 DNS를 감지하지 못한다면 약간의 시간을 들인 후 다시 시도하면 된다.

    hollaex_prod_successfully_detected_dns_configuration

    CLI가 DNS 설정을 정상적으로 감지했다면, 위와 같은 모습이 될 것이다.

    여기서 원할 경우 SSL 인증서도 같이 발급을 할 수 있는데, 원할 경우 Y, 아닐 경우 N 을 입력해주자. 만약 AWS ELB 등 외부 로드밸런서를 통해 SSL을 사용할 경우, CLI를 통해 인증서를 발급받을 필요가 없다. 혹시라도 나중에 마음이 바뀌면, hollaex toolbox --issue_ssl 명령어를 통해 SSL 인증서만 따로 발급받을 수 있으니 걱정은 말고.

    hollaex_prod_issue_ssl

    위와 같은 모습으로 내 도메인 2개에 SSL 인증서를 각각 발급받을 수 있다. 아쉽게도 SSL 인증서 발급에 사용하는 certbot 도구의 한계로, 한번에 하나의 인증서만 발급받을 수 있어 같은 화면이 2번 반복될 것이다. 당황하지 않고 처음에는 1번, 두번째에는 2번을 선택해 인증서를 모두 발급받으면 된다.

    이제 웹 브라우저를 켜고 내 API 서버에 접속해보며 설정이 정말 잘 되었는지 체크하자. 만약 외부 접근이 안될 경우, 서버나 컴퓨터 자체의 방화벽도 꼭 체크하길 바란다. 접근이 잘 될 경우, 도메인과 SSL 설정은 모두 완료된 것이다!

    아, 잠깐만 기다리자. 거래소 웹 사이트의 경우 도메인이 변경되거나 SSL 적용 여부가 달라지면 재빌드가 요구된다. 당황하지 않고 아래 명령어를 실행해 웹 이미지를 다시 빌드하자. 어렵지 않다. 만약 이 과정을 빠트릴 경우 웹 사이트가 거래소 API에 제대로 접근하지 못하게 된다. 중요하니까 느낌표 두개!!

    hollaex web --build
    

    위 명령어로 새롭게 웹 이미지를 빌드한 후,

    hollaex web --apply --tag <MY_IMAGE_TAG>
    

    명령어로 이미지를 적용하면 된다. 입력해야 할 --tag는 빌드 작업 직후에 CLI에 출력되니 참고하길 바란다.

    추가 정보

    HollaEx Kit와 HollaEx CLI를 다루는 더 자세한 방법, 모든 명령어 목록 등은 HollaEx 공식 Docs를 참고하면 된다. 내용은 실시간으로 업데이트 되니 참고할 것.

    만약 진행 중 막히는 부분이 있거나, 추가 질문이 있다면, HollaEx 포럼에서 자유롭게 정보를 탐색하고 질문을 올릴 수 있다. 아무래도 다양한 곳에서 온 사람들이 사용하는 솔루션인 만큼, 더 양질의 정보를 위해 영어로 질문을 남겨야 하는 점은 기억하시라.

    마치며

    coinpongpong

    여기까지 따라오신 분들, 모두 수고하셨다. 이제 다들 거래소 하나씩은 끼고 다닐 수 있게 되었다. 그저 흔하디 흔한 미들웨어 설치 가이드 하나 따라온 것 같은 기분이 들겠지만, 그 결과가 내포하는 의미는 사실 완전히 다르다. 이전까지, 아니 지금까지도 금융이라는 것은 돈 있고 빽 있는 사람들의 체스판이였다. 은행, 주식판, 각종 거래소, 모든 것이 말이다. 우리는 그저 이미 다 짜여진 시스템 속에서 허우적거리고 있었을 뿐이다.

    그런데, 암호화폐가 등장하면서 이런 당연한 것 같은 로직이 조금씩 깨지기 시작했다. 발행 주체가 없는 화폐. 그러면서도 누구도 무결성을 손댈 수 없는 화폐. 이 SF같은 이야기가 지난 10여넌 사이 우리에게는 현실이 되었다. 다만, 한가지 아킬레스 건이 있다. 이 자유로울 것 같은 화폐는 범용적으로 사용하기 위해 원화와 같은 기성 통화로 환전할 때 모든 자유가 사라진다. 자유가 사라지는 수준을 넘어 억압을 받고 있다 하는게 맞겠다. 각 국가의 법률, 메이저 거래소들의 정책 등 다양한 이유가 존재하겠지.

    기껏 암호화폐라는 지푸라기는 잡았지만 다시금 허우적거리려는 우리에게, HollaEx는 한 줄기 지푸가리를 밧줄 정도로 바꿔줄 수 있는 솔루션이다. 더 쉬운 암호화폐 시장으로의 진입. 이전에는 존재하지 않았을 다양한 비즈니스가 생겨나고, 다양한 거래소도 생겨난다. 이는 곧 우리같은 유저들에게는 더 많은 선택권을 의미한다. 더 많은 거래소, 더 많은 암호화폐 비즈니스. 이로 인해 처음 우리가 암호화폐를 마주했을 때 꿈꿨던 그 자유로움에 한 발자국 더 다가가지 않을까. 지금처럼 논란의 대상이 아닌, 무한한 미래를 가지고 있는 하나의 화폐로서 말이다.

  • Homebridge로 샤오미 공기청정기 HomeKit 제어하기

    이전에 Homebridge를 사용해 미지원 IoT 기기를 애플 HomeKit을 통해 제어하는 법에 대해 다룬 적 있다. 당시에는 필자에게 있는 IoT 기기가 Yeelight 전구밖에 없었는데, 이후 샤오미에서 나온 공기청정기 (Mi Air 2s)도 추가로 들여 사용하고 있다.

    Yeelight와 똑같이 샤오미 브랜딩을 달고 출시한 제품답게, 와이파이를 통한 원격 제어와 프로그래밍이 가능한 모델이다. 혹시나 싶어 웹을 조금 찾아보니, Homebridge에서 Mi Air 모델도 제어할 수 있게 해주는 서드파티 플러그인이 존재했다. 이미 HomeKit의 마법같은 편리함을 맛 본 몸인데, 어떻게 더 망설일 수 있으랴. 바로 적용해보기로 했다.

    어떤 플러그인을 사용해야 하나요?

    서드파티로 기능을 구현한 만큼 플러그인이 딱 하나만 존재하는 것은 아니다. 몇 개의 Mi Air 지원 플러그인이 온라인 상에 존재하는 것은 알지만, 필자는 seikan/homebridge-mi-air-purifier 플러그인을 사용했다.

    설치 방법

    만약 Homebridge 서버를 미리 설정하지 않았다면, 필자의 이전 글을 참조해 설정부터 진행하길 바란다.

    Homebridge 서버를 사용할 준비를 마쳤다면, 아래의 명령어를 통해 homebridge-mi-air-purifier 플러그인을 컨테이너에 설치하자.

    docker exec homebridge npm install -g homebridge-mi-air-purifier
    

    설치가 완료되었다면, 이제 Homebridge의 config.json 파일에 아래와 같이 Mi Air를 위한 설정을 집어넣어야 한다.

    아래의 탬플릿을 config.jsonplatforms array에 넣으면 된다.

    {
        "platform": "MiAirPurifierPlatform",
        "deviceCfgs": [{
            "type": "MiAirPurifier2S",
            "ip": "<MY_MI_AIR_IP>",
            "token": "<MY_TOKEN>",
            "airPurifierDisable": false,
            "airPurifierName": "MiAir2S",
            "silentModeSwitchDisable": false,
            "silentModeSwitchName": "MiAir2S Silent Mode Switch",
            "temperatureDisable": false,
            "temperatureName": "MiAir2S Temperature",
            "humidityDisable": false,
            "humidityName": "MiAir2S Humidity",
            "buzzerSwitchDisable": true,
            "buzzerSwitchName": "MiAir2S Buzzer Switch",
            "ledBulbDisable": true,
            "ledBulbName": "MiAir2S LED Switch",
            "airQualityDisable": false,
            "airQualityName": "MiAir2S AirQuality"
        }]
    }
    

    이 설정을 통해 내 Mi Air의 종류, 커스텀 이름, LED 작동 여부 등 세부적인 사항을 모두 조종할 수 있다.

    그런데, deviceCfgs.ipdeviceCfgs.token 2개 값이 비어있는 것이 보인다.

    그렇다. 예상하는 것과 같이 위 2 값은 내가 가지고 있는 Mi Air의 내부 IP와 고유 토큰을 집어 넣어야 한다.

    Mi Air의 내부 IP는 내 공유기 설정 페이지 등에 접속해 쉽게 확인할 수 있을 것인데, 문제는 저 토큰이겠다. 도대체 어디서 기기 토큰을 얻어야 할까?

    Mi Air 제어 토큰 얻기

    본래는 miio와 같은 라이브러리를 통해 토큰값을 쉽게 얻을 수 있었지만, 최근에는 모종의 보안 패치가 진행됨에 따라 더 이상 그 방법을 사용할 수 없게 되었다.

    이를 대신하는 일종의 편법으로, 보안 문제가 있는 구 버전의 안드로이드 Mi Home 앱을 사용함으로서 토큰을 추출할 수 있다.

    사실 이렇게까지 해야 하나 싶지만… 티끌만큼 더 윤택해질 우리의 삶을 위해 잠깐만 눈 딱 감자.

    토큰을 추천할 수 있는 Mi Home의 버전은 v5.4.49다. 이 버전 이후의 Mi Home은 보안 문제가 패치되어 더 이상 토큰을 인할 수 없으니 기억하자.

    Apkmirror 같은 APK 덤프 사이트에서 설치 파일을 구해 안드로이드 기기에 설치한 후, 평소 Mi Home 앱을 사용하는 것과 같이 로그인을 진행하면 된다. 성공적으로 로그인이 된 후 내 기기 목록을 확인할 수 있으면 준비 완료.

    이제 안드로이드의 파일 관리자 앱을 열어, 아래의 경로로 이동하자.

    ~/SmartHome/logs/plug_DeviceManager
    

    상위 경로는 기기마다 차이가 있을 수 있으니, 검색 기능 등을 통해 SmartHome 이라는 폴더를 찾아보자.

    경로로 이동했다면 아래 스크린샷과 같이 텍스트 파일이 보일 것이다. 열어보자.

    필자는 해당 작업을 올해 초에 진행했기에, 파일 이름이 1월 30일 날짜로 태깅되어 있으니 참고하자.

    mi_home_path_screenshot.png

    파일을 열어보면 json 형태로 되어 있는 내 기기 목록 정보가 담겨있을 것이다. 검색 기능을 통해 token 키워드를 검색하자. 아래와 같이 토큰 정보를 확인할 수 있을 것이다.

    mi_home_token_screenshot.png

    위에서 Mi Air의 내부 IP를 아직 확인하지 않았다면, 같은 파일에서 IP까지 같이 확인할 수 있으니 긁어가자.

    서버에 토큰 적용하기

    이제 다시 서버의 config.json 파일을 열어, 아까 공란으로 남겨준 Mi Air IP와 토큰을 집어넣자. 완성된 형태는 아래와 비슷할 것이다.

    **’ 부분은 필자가 임의로 마스킹 처리한 민감 정보다.

    
    {
        "bridge": {
            "name": "Homebridge ******",
            "username": "******",
            "port": ******,
            "pin": "******"
        },
        "accessories": [],
        "platforms": [
            {
                "platform" : "yeelight",
                "name" : "yeelight"
            },
            {
                "platform": "MiAirPurifierPlatform",
                "deviceCfgs": [{
                    "type": "MiAirPurifier2S",
                    "ip": "192.168.******",
                    "token": "******",
                    "airPurifierDisable": false,
                    "airPurifierName": "MiAir2S",
                    "silentModeSwitchDisable": false,
                    "silentModeSwitchName": "MiAir2S Silent Mode Switch",
                    "temperatureDisable": false,
                    "temperatureName": "MiAir2S Temperature",
                    "humidityDisable": false,
                    "humidityName": "MiAir2S Humidity",
                    "buzzerSwitchDisable": true,
                    "buzzerSwitchName": "MiAir2S Buzzer Switch",
                    "ledBulbDisable": true,
                    "ledBulbName": "MiAir2S LED Switch",
                    "airQualityDisable": false,
                    "airQualityName": "MiAir2S AirQuality"
                    }]
            }
        ]
    }
    
    

    이제 살포시 저장해주고, 적용을 위해 Homebridge 서버를 재시작하자.

    docker restart homebridge
    

    이제 조금만 기다리면 내 애플 Home 앱에 공기청정기가 빰 하고 머리를 내밀 것이다. 아래 스크린샷처럼 말이다!

    mi_air_on_apple_home_screenshot

    단순한 공기청정기 전원 제어 뿐만 아니라, 온습도계와 연동되어 집 안의 온도와 습도까지 확인할 수 있다. 이제보니 따로 온도계 습도계 설치할 비용도 아꼈네.

    만약 Homebridge 서버에 정상적으로 연결되지 않는다면 서버 로그를 꼭 살펴보자.

    docker logs homebridge
    

    무언가 디버깅할 수 있는 단서를 줄 것이다. 굿 럭.

    마치며

    10년, 20년 전만 해도 공상과학 영화 속의 일이였던 홈 오토메이션이 이제 몇만원도 하지 않는 저렴한 중국산 기기를 통해서까지 이루어질 수 있다는 건 분명한 격세지감이다.

    더군다나 애플 HomeKit에 연동해 통합까지 할 수 있다니! 분명 우리는 좋은 시대에 살고 있다. 코로나니 뭐니 하며 전 세계가 전래없는 재난 상황에 빠져있는 2020년이지만, 이런 작은 것들에 감탄하고 행복을 느끼면서 앞으로 나아갈 수 있는 해도 2020년이다.

    생각해보니 이 글이 올해 처음으로 블로그에 작성한 글이 되었다. 바쁘다는 핑계, 정신 없는 한 해여서 그랬다는 핑계를 대고 싶지만 그냥 심적 여유가 없었다. 일상 생활조차도 심적으로 고갈되어서 허덕이는 삶을 살았는데 한가롭게 글 쓸 여유가 어디서 나올까.

    다행히 요즘은 개선이 있다. 항우울제가 도움이 되는 건지 단순히 시간이 약이라 그런 건진 모르겠지만, 분명 한 발자국씩 앞으로 나아가고 있다. 앞으로 글도 조금 더 쓸 수 있으리라.

  • Helm V2 에서 V3 로 마이그레이션 하기

    helm-v2-deprecated-announce-at-kubecon

    Helm 릴리즈 매니저는 쿠버네티스에 애플리케이션을 배포할 때 더할나위 없이 편리하고 표준적인 방법으로 많은 유저들에게 사랑받고 있다. 현재 가장 대중적으로 쓰이는 버전은 v2 인데, 한달 전 미국 샌디에고에서 진행한 Kubecon에 참가했을 때, 이 v2 버전이 앞으로 약 1년에 걸쳐 서서히 지원 중단되고, 최신 버전인 v3로 세대 교체를 한다는 발표를 보았다.

    helm-v2-lifecycle

    Helm v3 출시가 처음 공표된 것이 필자가 참가한 11월 Kubecon의 약 일주일 전이였고, 1년의 사후 지원 기간이 있어 그리 서두를 필요는 없지만, 미리 Helm v2와 v3의 차이점을 이해하고, 어떻게 하면 서비스 영향을 최소화하며 안전히 마이그레이션 할 수 있을지 알아보는 과정이 필요할 것 같아 시간이 남는 크리스마스 (…) 에 글을 끄적여본다. 내년 크리스마스는 시간이 남지 않길

    Helm v2와 v3의 차이점

    Helm이 버전의 앞자리까지 바꿀 정도의 업그레이드를 거치며 기존 버전과 몇가지 큰 차이점들이 생겨났는데, 다행히 주로 Helm v2에서 사람들이 문제점으로 지적하는 것들, 불편한 것들이 수정된 “개선점” 이다.

    아래 내용 작성에는 Helm 공식 문서를 참고했습니다. 원문을 보고 싶으신 분, 혹은 자잘한 변경점까지 모두 확인하고 싶으신 분은 이 링크를 확인해주세요.

    Tiller의 완전한 삭제

    Helm v2에서는 클러스터에서 Helm Chart들의 통합 관리와 설치를 위해 Tiller라는 특별한 Pod를 사용했다. Tiller가 설치된 Chart를 통합 관리해주는 덕에, 누가 그 쿠버네티스 클러스터에 접속하더라도 같은 버전의 Helm Chart를 볼 수 있었다.

    그래, 다 좋아 보이지만 언제나 문제는 보안이다. 쿠버네티스의 RBAC가 기본으로 활성화되고부터, Helm은 Tiller Pod에 cluster-admin 권한을 부여했다. 시스템 관리자가 자잘한 보안 문제에 직면하지 않고 애플리케이션 배포에 집중할 수 있게 해준 배려였겠지만, 프로덕션 환경까지 생각할 경우 이는 큰 보안 구멍이 될 수 있다.

    대표적으로, 사용자의 PC에 설치된 Helm 클라이언트와 쿠버네티스의 Tiller는 gRPC를 사용해서 통신을 하게 되는데, 기본 설정으로는 이 gRPC 포트가 보안 없이 열려있게 된다! 물론 이 포트가 직접적으로 외부에 열려있지는 않지만, 만약 공격자가 작정하고 쿠버네티스에 악성 프로그램을 구동하는데 성공했다면, 내부 네트워크를 타고 이 gRPC 포트에 요청을 보내 아무런 인증 과정 없이 cluster-admin 권한을 사용할 수 있게 되는 거다.

    이런 잠재적인 문제를 방지하기 위해, Helm v3부터는 Tiller가 아닌 쿠버네티스 API를 사용해 설치된 Helm Chart들을 쿠버네티스 그 자체에 저장하게 된다. 그 Chart를 설치하는 RBAC 권한은 사용자가 사용한 kubeconfig 파일을 따라가게 된다.

    이처럼 Helm 작동 구조가 조금 더 직관적으로 변하면서, 프로덕션 환경에서도 조금 더 안심하고 Helm을 사용할 수 있게 되었다.

    Helm으로 설치된 릴리즈의 수정 감지와 반영

    제목만 보고 이게 무슨 소린가 할 거다. 필자가 공돌이랑 문돌이 그 사이 어딘가에 있는 어중간한 성향의 사람이라 그럴 수도 있다. 각설하고, 이제 Helm으로 설치된 릴리즈가 (Chart 등) kubectl 등의 외부 도구를 사용해 수정되어도 Helm이 감지하고 rollback이나 upgrade 등에 자연스럽게 반영한다는 말이다.

    예를 들어보자, 만약 Helm v2에서 1개의 Nginx를 실행하는 Chart를 설치했을 때, 이후 kubectl을 사용해 replicas를 1개에서 0개로 만든다면 Helm은 이를 감지하지 못한다. 만약 이 상태에서 helm rollback을 실행했을 때, Helm 입장에서는 자신을 통해 수정된 부분이 없으니 모든 설정이 최신이라고 생각해 아무런 일이 벌어지지 않는다. Nginx Pod의 갯수는 계속 0개로 남아있을 거다. Helm 공식 문서의 말 맞다나 “Panic ensues” 다.

    Helm v3는 이런 외부 도구를 사용해 수정된 리소스의 차이도 감지할 수 있게 된다. 같은 상황에서 helm rollback을 실행하면, Helm v3는 최초 설치된 Helm Chart의 정보와, 현재의 수정된 정보를 비교해 최초의 Chart 정보로 덮어씌운다. Pod의 갯수도 당연히 1개로 돌아간다. 진정한 의미의 Rollback이 가능해진 것이다.

    또 다른 에시로, Helm v2를 통해 설치한 Deployment에 이후 kubectl edit등을 사용해 Sidecar 컨테이너를 하나 추가했다고 생각해 보자. 이후 helm upgrade로 해당 릴리즈를 업그레이드 할 경우, Helm Chart에는 당연히 아무런 Sidecar 설정이 되어있지 않으니 업그레이드 된 릴리즈에는 Sidecar는 흔적도 없이 사라져 있을꺼다. 물론 정석적인 방법은 Sidecar를 Helm Chart 단계에서 추가해, upgrade를 돌리는 거지만, 만약 급하게 Helm을 통하지 않고 Sidecar를 추가한 후, upgrade를 실행해 버렸다면 또다시 패닉이겠다.

    Helm v3에서는 이 같은 차이도 감지해서 upgrade에 반영하게 된다. 즉, Chart에 Sidecar가 설정되어 있지 않다고 해도 upgrade를 돌렸을 때 Sidecar가 남아있다는 말씀. 오오. 이 얼마나 편리한가.

    Release Name의 중복 허용

    Helm Chart를 설치할 때는 Release Name을 필수적으로 정해야 하는데, Helm v2에서는 이 이름은 Unique Name이 되었다. 한번 사용한 이름은 다른 Chart를 설치할 때 다시 사용할 수 없었다는 뜻이다.

    지금까지는 Tiller가 모든 설치된 Chart들을 관리하면서 Tiller가 위치한 Namespace에 모든 설치 정보도 저장되었다. 그래서 같은 Release Name을 사용하면 충돌이 발생했는데, 이제 각 Chart의 설치 정보는 그 Chart가 설치된 Namespace에 개별적으로 저장되게 되면서, 다른 Namespace에 무언가를 설치하며 동일한 Release Name을 사용한다고 해도 충돌이 벌어질 건덕지가 없어졌다.

    이제 같은 이름 여러번 써도 된다! 개발자의 가장 큰 직무, 이름 짓기의 부담이 티끌만큼 덜어지는 순간이다.

    자잘한 명령어 변경

    설치된 릴리즈를 지울 때 흔히 사용되는 helm delete 명령어가 helm uninstall 로 대체되었다. 정획하 밀하면 helm deletehelm uninstall의 대체 명령어로 남아있어 둘 중 아무거나 사용해도 되지만, helm uninstall이라는 명령어를 새로 만든 만큼 나중에는 helm delete라는 명령어 자체가 사라질 수도 있을 것 같으니 미리미리 helm uninstall을 사용하는 습관을 길러보자.

    추가적으로, helm delete--purge 라는 플래그를 추가적으로 사용해야 설치된 릴리즈 정보를 완전히 삭제할 수 있었는데, helm uninstall을 사용하면 이제 기본적으로 --purge까지 같이 수행된다. 만약 --purge 기능을 사용하고 싶지 않다면, helm uninstall--keep-history 플래그를 같이 사용하면 된다.

    그 외

    • helm inspect -> helm show
    • helm fetch -> helm pull

    Helm v2에서 v3로의 마이그레이션

    테스트 환경 구성

    우선, Helm v2가 설치된 쿠버네티스 환경을 준비하자. 필자는 Helm v2를 사용하는 프로덕션 쿠버네티스를 여러대 운용하고 있지만, 안전한 테스트를 위해 로컬 환경에 새로운 쿠버네티스를 기동했다. macOS 환경을 사용한다면 Docker for Mac에서 원클릭 쿠버네티스 구축 기능을 지원하니 간편하고 안전한 테스트를 원하는 분들은 참고하시길.

    helm-v2-setup-on-local

    helm init --service-account=tiller
    

    위 명령어로 Helm v2의 Tiller Pod를 initialize 시킬 수 있다. 위의 tiller Service Account는 아래를 참고해 본인이 원하는 이름으로 생성하면 된다.

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: tiller
      namespace: kube-system
    ---
    apiVersion: rbac.authorization.k8s.io/v1beta1
    kind: ClusterRoleBinding
    metadata:
      name: tiller
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: cluster-admin
    subjects:
      - kind: ServiceAccount
        name: tiller
        namespace: kube-system
    
    

    helm version 명령어를 통해 정상적으로 Tiller Pod가 사용 준비가 되었는지 체크하자. 아래와 같이 클라이언트, 서버 버전이 잘 출력된다면 사용 준비 끝.

    kycfeel-MBP:~ kycfeel$ helm version
    Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
    Server: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"}
    

    Helm v3로 마이그레이션 하기 전, Helm v2인 상태로 Helm Chart 하나를 설치해보자. 이전에 설치된 릴리즈가 신 버전에서도 정상적으로 동작해야 마이그레이션의 의미가 있다. 이미 Helm v2를 사용중이고, Helm으로 설치한 릴리즈가 존재한다면 다음 단게로 넘어가도 무방하다.

    만약 없다면, 아래 명령어를 통해 간단히 Redis 서버를 설치해 보자.

    간단한 테스트 애플리케이션 구성을 위해 Persistet Volume Claim 생성은 비활성화 했다.

    helm install --name test-redis stable/redis -set master.persistence.enabled=false --set slave.persistence.enabled=flase stable/redis
    

    이후 kubectl get pods 명령어로 정상적으로 Redis가 설치되어 구동되는지 꼭 확인하자.

    Helm v3와 2to3 플러그인 설치하기

    아래의 메뉴얼은 Helm 공식 블로그를 참고해 작성되었습니다.

    우선, 최신 버전의 Helm v3를 Helm 공식 GitHub에서 다운로드하자. 우리의 목적은 Helm v3로의 클린 재설치가 아닌, 부드러운 마이그레이션이므로 기존 설치된 Helm을 생각없이 덮어쓸 수는 없다. 일단, 다운로드 받은 바이너리의 이름을 helm에서 helm3로 바꿔, 시스템의 /usr/local/bin 폴더에 넣어주자. 사용하는 OS에 따라 경로가 약간 다를 수는 있지만, 비슷한 역할을 하는 곳에 넣어주면 된다.

    이제, helm3 plugin install https://github.com/helm/helm-2to3 명령어로 Helm v2를 v3로 마이그레이션 할 수 있게 도와주는 2to3 플러그인을 설치하자. 아래처럼 helm 2to3 명령어를 입력했을 때, 사용 방법이 출력되면 정상적으로 설치된 것이다.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 2to3
    Migrate and Cleanup Helm v2 configuration and releases in-place to Helm v3
    
    Usage:
      2to3 [command]
    
    Available Commands:
      cleanup     cleanup Helm v2 configuration, release data and Tiller deployment
      convert     migrate Helm v2 release in-place to Helm v3
      help        Help about any command
      move        migrate Helm v2 configuration in-place to Helm v3
    
    Flags:
      -h, --help   help for 2to3
    
    Use "2to3 [command] --help" for more information about a command.
    

    Helm v2의 설정 마이그레이션

    helm3 2to3 move config 명령어로 기존 Helm v2를 통해 설치한 Chart들의 Repository, 플러그인 등을 Helm v3로 안전하게 옮길 수 있다.

    잠깐 진행하기 전, helm repo list 명령어를 통해 기존 Helm v2의 Repository list와, helm3 repo list 명령어로 Helm v3의 Repository list를 비교해 보자. Helm v2는 stable을 위시한 local 등의 list들의 보일 것인데, Helm v3는 기본 설정이라면 아무런 Repo도 보이지 않을 것이다. 마이그레이션이 성공한다면, 이 Helm v2의 Repository들이 Helm v3에도 그대로 옮겨질 것이다. 지금부터 한번 확인해 보자.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 2to3 move config
    2019/12/28 17:08:11 WARNING: Helm v3 configuration maybe overwritten during this operation.
    2019/12/28 17:08:11
    [Move Config/confirm] Are you sure you want to move the v2 configration? [y/N]: y
    2019/12/28 17:08:12
    Helm v2 configuration will be moved to Helm v3 configration.
    2019/12/28 17:08:12 [Helm 2] Home directory: /Users/kycfeel/.helm
    2019/12/28 17:08:12 [Helm 3] Config directory: /Users/kycfeel/Library/Preferences/helm
    2019/12/28 17:08:12 [Helm 3] Data directory: /Users/kycfeel/Library/helm
    2019/12/28 17:08:12 [Helm 3] Cache directory: /Users/kycfeel/Library/Caches/helm
    2019/12/28 17:08:12 [Helm 3] Create config folder "/Users/kycfeel/Library/Preferences/helm" .
    2019/12/28 17:08:12 [Helm 3] Config folder "/Users/kycfeel/Library/Preferences/helm" created.
    2019/12/28 17:08:12 [Helm 2] repositories file "/Users/kycfeel/.helm/repository/repositories.yaml" will copy to [Helm 3] config folder "/Users/kycfeel/Library/Preferences/helm/repositories.yaml" .
    2019/12/28 17:08:12 [Helm 2] repositories file "/Users/kycfeel/.helm/repository/repositories.yaml" copied successfully to [Helm 3] config folder "/Users/kycfeel/Library/Preferences/helm/repositories.yaml" .
    2019/12/28 17:08:12 [Helm 3] Create cache folder "/Users/kycfeel/Library/Caches/helm" .
    2019/12/28 17:08:12 [Helm 3] cache folder "/Users/kycfeel/Library/Caches/helm" created.
    2019/12/28 17:08:12 [Helm 3] Create data folder "/Users/kycfeel/Library/helm" .
    2019/12/28 17:08:12 [Helm 3] data folder "/Users/kycfeel/Library/helm" created.
    2019/12/28 17:08:12 [Helm 2] starters "/Users/kycfeel/.helm/starters" will copy to [Helm 3] data folder "/Users/kycfeel/Library/helm/starters" .
    2019/12/28 17:08:12 [Helm 2] starters "/Users/kycfeel/.helm/starters" copied successfully to [Helm 3] data folder "/Users/kycfeel/Library/helm/starters" .
    2019/12/28 17:08:12 Helm v2 configuration was moved successfully to Helm v3 configration.
    

    명령어를 실행하면, 내 기존 Helm v2 폴더의 여러 설정 데이터들이 Helm v3에서 사용하는 폴더들로 옮겨진 걸 확인할 수 있다. 필자는 macOS에서 마이그레이션을 진행했는데, Helm v3부터는 더 macOS-Native한 설치 경로를 사용하는 게 보인다. 기존 Unix 스타일과 macOS-Only 스타일. 뭐가 더 효율적일지는 나도 모르겠다 🤔.

    이제 helm3 repo list 명령어를 한번 실행해 보자. 별다른 문제가 없었다면 아래와 같이 Repository들이 정상적으로 보일 것이다. 필자의 경우 이미 테스트 전부터 Helm v2에 이것저것 추가해둔 덕에, 독자의 환경과 표시되는 리스트 목록이 조금 다를 수 있다. 신경쓰지 말고 넘어가자.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 repo list
    NAME           	URL
    stable         	https://kubernetes-charts.storage.googleapis.com
    local          	http://127.0.0.1:8879/charts
    coreos         	https://s3-eu-west-1.amazonaws.com/coreos-charts/stable/
    (...)
    
    

    Helm v2의 Release 마이그레이션

    설정값들을 옮겼으니, 이제 진짜배기를 옮길 차례다. 설치된 Helm 릴리즈들을 Helm v3로 승계하는 것을 말하는 거다. 우리는 조금 전 test-redis라는 이름의 Redis 릴리즈를 만들었으니, 그 릴리즈를 v3으로 옮겨보자.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm ls
    NAME      	REVISION	UPDATED                 	STATUS  	CHART      	NAMESPACE
    test-redis	1       	Sat Dec 28 16:35:52 2019	DEPLOYED	redis-5.1.0	default
    

    helm ls 명령어로 릴리즈 이름과 목록을 다시한번 확인한 후, 아래 명령어로 릴리즈를 v3로 승계해보자.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 2to3 convert test-redis
    2019/12/28 17:26:27 Release "test-redis" will be converted from Helm v2 to Helm v3.
    2019/12/28 17:26:27 [Helm 3] Release "test-redis" will be created.
    2019/12/28 17:26:27 [Helm 3] ReleaseVersion "test-redis.v1" will be created.
    2019/12/28 17:26:27 [Helm 3] ReleaseVersion "test-redis.v1" created.
    2019/12/28 17:26:27 [Helm 3] Release "test-redis" created.
    2019/12/28 17:26:27 Release "test-redis" was converted successfully from Helm v2 to Helm v3.
    2019/12/28 17:26:27 Note: The v2 release information still remains and should be removed to avoid conflicts with the migrated v3 release.
    2019/12/28 17:26:27 v2 release information should only be removed using `helm 2to3` cleanup and when all releases have been migrated over.
    

    뭔가 정상적으로 진행된 것 같다. 이제 helm3 ls 명령어로 선택한 릴리즈가 정상적으로 옮겨졌는지 확인해 보자.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 ls
    NAME      	NAMESPACE	REVISION	UPDATED                              	STATUS  	CHART      	APP VERSION
    test-redis	default  	1       	2019-12-28 07:35:52.6889687 +0000 UTC	deployed	redis-5.1.0	4.0.11
    

    완벽하다 😄.

    Helm v2 정리하기

    필요한 모든 설정값과 릴리즈를 Helm v3로 옮겼다면, 이제 정든 Helm v2와 작별을 고해야겠지. 아쉽지만 어쩌하리. 인간은 결국 앞으로 나아가야만 하는 존재니.

    아래 명령어로 Helm v2를 깔끔하게 삭제할 수 있다.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm3 2to3 cleanup
    WARNING: "Helm v2 Configuration" "Release Data" "Release Data" will be removed.
    This will clean up all releases managed by Helm v2. It will not be possible to restore them if you haven't made a backup of the releases.
    Helm v2 may not be usable afterwards.
    
    [Cleanup/confirm] Are you sure you want to cleanup Helm v2 data? [y/N]: y
    2019/12/28 17:29:41
    Helm v2 data will be cleaned up.
    2019/12/28 17:29:41 [Helm 2] Releases will be deleted.
    2019/12/28 17:29:42 [Helm 2] ReleaseVersion "test-redis.v1" will be deleted.
    2019/12/28 17:29:42 [Helm 2] ReleaseVersion "test-redis.v1" deleted.
    2019/12/28 17:29:42 [Helm 2] Releases deleted.
    2019/12/28 17:29:42 [Helm 2] Tiller in "kube-system" namespace will be removed.
    2019/12/28 17:29:42 [Helm 2] Tiller "deploy" in "kube-system" namespace will be removed.
    2019/12/28 17:29:43 [Helm 2] Tiller "deploy" in "kube-system" namespace was removed successfully.
    2019/12/28 17:29:43 [Helm 2] Tiller "service" in "kube-system" namespace will be removed.
    2019/12/28 17:29:43 [Helm 2] Tiller "service" in "kube-system" namespace was removed successfully.
    2019/12/28 17:29:43 [Helm 2] Tiller in "kube-system" namespace was removed.
    2019/12/28 17:29:43 [Helm 2] Home folder "/Users/kycfeel/.helm" will be deleted.
    2019/12/28 17:29:43 [Helm 2] Home folder "/Users/kycfeel/.helm" deleted.
    2019/12/28 17:29:43 Helm v2 data was cleaned up successfully.
    

    그렇게 님은 가셨다.

    만약 다시 Helm v2 명령어를 실행한다면, 아래와 같이 Tiller Pod를 찾을 수 없다는 메시지가 뜰 것이다.

    kycfeel-MBP:darwin-amd64 kycfeel$ helm ls
    Error: could not find tiller
    

    더 이상 흔적을 찾지 말자. 나한테만 남은 미련은 곧 비극이다.

    마무리

    지금까지 위의 과정을 통해 Helm v2를 v3로 별다른 어려움 없이 마이그레이션 했다. Helm에서 잘 만들어진 플러그인을 제공해주는 덕에, 서버에 깊게 얽혀있는 메이저 버전 업그레이드 치고 아주 손쉽게 마이그레이션을 마칠 수 있었다.

    이제 기존에 사용하던 helm install이나 helm upgrade` 등을 테스트해보며 모든 기능이 원하는데로 작동하는지도 꼭 확인하자.

    하나 더, 위에도 언급했지만 Helm v3는 출시된지 이제 약 한달밖에 지나지 않은 말 그대로의 신생 버전이다. 나름 stable 릴리즈인 만큼 큰 문제는 없을 것으로 예상하지만, 아주 크리티컬한 프로덕션에서 Helm을 사용해야 한다면 앞으로 최소 몇개월은 Helm v2를 사용하며 v3의 동향을 보는 것을 추천한다. Helm같은 로우 레벨 유틸리티의 버그는 시스템 관리자의 흰머리 생성에 아주 큰 기여를 하니까 말이다 😉.

    마지막으로, helm3보다 helm 으로 명령어를 호출하는 것이 더 익숙하다면 /usr/local/binhelm3helm으로 리네이밍 해주자.

    끗.

  • Pi Hole로 광고 뿌리뽑기

    자본주의 시대의 광고는 경제의 허파이자 세상이 움직이는 동기요, 곧 자본주의 그 자체이다. 사람들은 광고를 보고 내 돈을 어디에, 어떻게 소비할 지 결정하고, 이는 곧 사회에 자본을 흐르게 한다. 어떻게 보면 우리 시대에 없어서는 안될 필연적인 존재지만, 종종 눈엣가시처럼 거슬리는 건 어쩔 수 없다. 광고가 나의 소비를 위한 참고 정보 수준을 뛰어넘어 우리 눈앞을 뒤덮어 버리는 테러 수준에 다달아서 그런 것인지, AdBlock 같은 온라인 광고 차단 플러그인의 인기는 날이 갈수록 하늘로 치솟는다. 오프라인에서는 눈을 가리고 살 수 없으니 온라인 에서라도 가리겠다는 사람들의 발버둥 아닐까.

    더 확실히 온라인에서의 눈을 가리고 싶다는 분들을 위해, 네트워크 레벨에서 광고를 걸러 주는 Pi-hole 이라는 녀석을 들고 왔다. 내 로컬 네트워크의 DNS 브릿지가 되어 트래픽이 브릿지를 건너는 순간 광고 DB와 비교해 얄짤없이 광고는 모조리 잘라버린다나 뭐라나. 암튼, Pi-hole이라는 이름에 맞게 라즈베리 파이, 그리고 우리의 친구 Docker를 가지고 내 인터넷으로 들어오는 광고를 학살해 보자.

    설치하기

    기본적으로 Pi-hole이 권장하는 설치 방식은 호스트 OS에 바로 설치되는 쉘 스크립트지만, 우리는 조금 더 깔끔한 설치와 실행을 위해 Docker를 사용하자. 다행히 Pi-hole 에서는 Docker화 시킨 프로젝트도 함께 제공하고 있다. Pi-hole만을 위한 폴더를 하나 생성한 후, 그 안에 docker-compose.yml 파일을 만들어보자. 내용은 아래 것을 복사하면 된다. 아래의 샘플 docker-compose 파일을 포함한 전체 프로젝트 자료는 이 링크에서 확인할 수 있다.

    version: "3"
    
    # More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/
    services:
      pihole:
        container_name: pihole
        image: pihole/pihole:latest
        ports:
          - "53:53/tcp"
          - "53:53/udp"
          - "67:67/udp"
          - "80:80/tcp"
          - "443:443/tcp"
        environment:
          TZ: 'Asia/Seoul'
          WEBPASSWORD: '<MY_PASSWORD>'
        # Volumes store your data between container upgrades
        volumes:
          - './etc-pihole/:/etc/pihole/'
          - './etc-dnsmasq.d/:/etc/dnsmasq.d/'
        dns:
          - 127.0.0.1
          - 1.1.1.1
          - 1.0.0.1
        # Recommended but not required (DHCP needs NET_ADMIN)
        #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
        cap_add:
          - NET_ADMIN
        restart: unless-stopped
    

    파일이 실행될 경우, docker-composepihole 이라는 컨테이너를 최신의 pihole/pihole 이미지를 사용해서 생성하고, 53 (DNS), 67 (DHCP 서버), 80/443 (HTTP, HTTPS) 포트를 할당해준다. Timezone은 Asia/Seoul 로 env에 명시해두고, docker-compose 가 존재하는 폴더에 etc-piholeetc-dnsmasq.d 라는 폴더를 생성해 pihole 컨테이너의 실제 /etc/pihole 경로와 /etc/dnsmasq.d 경로를 마운트한다. 이를 통해서 추후 컨테이너가 재시작 될 경우에도 설정 정보를 지킬 수 있다. cap_addNET_ADMIN 권한은 pihole 로 DHCP 서버 기능을 같이 사용할 경우 필요해 추가하였다.

    딱 하나 유저가 커스터마이징 해야할 부분은, 웹 대시보드의 비밀번호를 변경하는 WEBPASSWORD env다. 위 ㅍ일의 <MY_PASSWORD> 부분을 내가 원하는 비밀번호로 설정하자.

    자, 설정에 문제가 없는 것을 확인했으면, 아래 명령어로 컨테이너를 올려볼 차례다.

    docker-compose up -d  
    

    아래의 명령어를 통해 로그를 불러올 수 있다.

    docker logs pihole
    

    실행이 완료되었다면, 이제 내 라즈베리 파이는 광고를 걸러주는 DNS 서버가 된 것이다! 컴퓨터나 공유기의 DNS 설정에서 내 라즈베리 파이의 로컬 IP를 서버로 설정해준다면, 바로 기본 설정의 광고제거 DNS 기능을 사용할 수 있다. 조금 더 둘러보고 싶다면, 브라우저를 켜고 라즈베리 파이의 로컬 IP로 접속해보자. 아래와 같은 대시보드가 독자를 환영해줄 것이다.

    dashboardmain

    대시보드는 생각보다 많은 정보와 기능을 제공한다. DNS를 통한 웹 접속이 얼만큼 어떻게 어디로 이뤄졌는지 등을 깔끔한 차트로 보여준다. 설정에 들어가면 아래와 같이 차단할 광고의 목록도 직접 커스터마이징이 가능하다. 기본 리스트로 차단되지 않는 광고가 보인다면 직접 리스트에 해당 광고 서버 주소를 추가할 수 있다.

    piholeadlist

    기본 설정에서 한가지 찝찝한 부분이 있는데, 바로 내가 어떤 사이트를 얼만큼 접속했는지 쿼리 기록이 모조리 남는다는 것. 다행히 설정의 하단에 내려가면 Danger Zone에서 쿼리 기록을 모조리 지우고 비활성화 할 수 있는 기능을 제공한다. 내 접속기록이 어딘가에 남는 것이 찝집하다면 Disable query logging and flush logs 버튼을 눌러 살포시 막아주자.

    piholedisablelogging

    컴퓨터의 DNS 설정을 라즈베리 파이의 IP로 바꿔 DNS 기능이 제대로 동작하는 걸 확인했다면, 아예 공유기 레벨의 DNS를 라즈베리 파이로 고정해 공유기에 연결되는 모든 기기가 광고 제거 효과를 받게 만드는 걸 추천한다. 아래와 같이 설정하면 된다 (기본 DNS에 라즈베리 파이의 로컬 IP 주소를 집어넣자).

    piholednsaddtorouter

    필요한 설정은 모두 끝났다. 이제 광고 없는 클린한 웹 환경을 즐겨보자 :)

    마무리하며

    Pi-hole을 비롯한 광고 차단 도구는 분명 강력하고 스팸 수준의 온라인 광고들을 원천적으로 차단해 쾌적한 웹 이용 환경을 만들어 주지만, 가끔은 광고 차단 기능을 꺼 주어야 할 때도 존재한다.

    우리가 온라인에서 무료로 만나는 수많은 양질의 콘텐츠들은 광고 수익이 전적으로 의지하는 경우가 많다. 일부 사이트에 따라 광고 차단이 감지되면 광고 차단을 꺼 주라는 메시지를 출력시키는 것도 같은 이유다. 더 많은 사람들이 광고를 차단할수록 많은 크리에이터들의 잠재적인 수익도 적어진다.

    나의 쾌적한 웹 이용 환경도 중요하지만 어느 정도의 광고는 납득해주며 양질의 온라인 콘텐츠가 지속적으로 공급될 수 있게 하는 것도 아주 중요하다. Pi-hole로 쾌적한 인터넷을 누리되, 가끔 생각이 날 땐 잠깐 Pi-hole의 전원을 꺼 보는 것은 어떨까. Pi-hole 대시보드의 메뉴에서 기능 정지 버튼을 누르면 간단하다.