• 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으로 리네이밍 해주자.

    끗.

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

    nyancoin

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

    HollaEx는 필자가 몸담아 일하고 있는 bitHolla (비트홀라) 에서 만든 암호화폐 거래소 솔루션이다. 뭐, 기술적으로는 암호화폐 거래소 뿐만 아니라 거래를 필요로 하는 모든 분야에 사용할 수 있지만, 어쨋든 그렇다. HollaEx를 사용하면 암호화폐 거래소를 만들 기술이나 기반이 부족하더라도, 약간의 노력만 기울이면 나만의 거래소를 뚝딱 만들 수 있다는 말씀. HollaEx 자체는 1~2년 전에도 존재했고, 진작부터 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

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

    • HollaEx 거래소 초기 설정 : 거래소의 로고나 URL, 지원할 코인을 지정하는 것처럼 거래소를 위한 전체 설정 과정을 bitHolla 대시보드에서 진행할 수 있다.

      • 활성화 키 받기 : 마치 Windows의 정품 키처럼, HollaEx 거래소를 활성화하기 위해서는 활성화 키가 필요하다. 다행히 bitHolla는 HollaEx를 맛보고 싶은 사람들을 위해 15일의 무료체험 키를 제공하고 있다. bitHolla 대시보드에 거래서 설정을 진행하면 자동으로 무료체험 키가 입혀지니 걱정 말고 살펴보자.
    • Vault 지갑 연결용 API 키 (생략 가능) : Vault는 HollaEx와 마찬가지로 bitHolla에서 만든 비즈니스용 암호화폐 지갑 서비스다. REST API를 제공하고 있어 누구나 자신의 서비스에 암호화폐 연동이 필요하다면 Vault를 가져다 사용할 수 있다. HollaEx도 물론 Vault를 암호화폐 연동에 사용한다. 이 얼마나 좋은 조합인가. 공식적으로 Vault는 무료 체험 기간을 제공하지 않지만, 글을 쓰는 현재 시점으로는 bitHolla에 따로 연락을 남길 경우 유연하게 무료 체험 기간을 주고 있으니 걱정하지 않아도 된다. 또한, HollaEx는 Vault의 연결이 없어도 구동 자체에는 문제가 없으니 암호화폐 네트워크와의 연결이 필요하지 않다면 의무 사항이 아니다.

    • SMTP 서버 설정 : HollaEx는 유저 회원가입 등의 인증 작업을 위해 표준 SMTP 기술을 사용한다. 만약 기존에 사용하던 SMTP 서버가 있다면 그것을 사용해도 되고, 새로 만들어야 한다면 어떤 SMTP 제공자의 서비스라도 사용할 수 있다. SMTP 서버 주소와 포트번호, 사용자 계정만 준비하면 된다. 개인적으로는 위의 AWS 설정과 연계해, AWS SES를 통해 SMTP 설정을 진행하는 것을 추천한다. 일을 하나 줄여준다!

    • 거래소 실행하기 : 위의 과정들은 전부 완벽히 작동하는 거래소를 실행하기 위한 도움닫기다. 모든 준비가 끝났다면, 최소한 거래소 얼굴이라도 보고 집에 들어가야지 않겠나?

    HollaEx 거래소 초기 설정하기

    가뜩이나 복잡할 것 같은 거래소인데 설정하는 건 얼마나 더 복잡할까 하셨던 분들이라면 걱정을 놓아도 되겠다. 다행히 bitHolla에서는 웹 대시보드를 통해 HollaEx Kit 설정을 위한 깔-끔한 인터페이스를 제공한다.

    HollaDash_main

    바로 앞에 보이는 Create Exchange 버튼을 누르면 거래소 세팅을 진행할 수 있다. 파란 버튼이 자기를 눌러달라고 애원하는데 안 누를 수는 없을 거다.

    holladash_setup

    총 6단계로 나누어지는 거래소 세팅 과정은 거래소 이름이나 시간대 같은 기본적인 정보부터 내 거래소의 로고, 테마, 지원하는 화폐와 거래장 등 필요한 모든 정보를 수집한다. 차근차근 진행하면 어려운 부분은 없을 것이다. 진행하다 막히는 부분이 생길 경우, 화면 우측 하단의 파란 채팅 버튼을 누르면 실시간으로 채팅 상담도 받을 수 있으니 참고하자.

    자, 세팅 과정 중 가장 주의해야 할 건 아래 설명된 거래소에서 사용할 코인과 거래 페어 (비트코인과 미국 달러의 거래장, 이더리움과 한국 원화의 거래장 등)를 추가하는 메뉴다. 거래소의 생명은 바로 거래에 있으니, 중요하지 않을래야 않을 수가 없다.

    새 코인 (화폐) 추가하기

    hollaedash_coin_list_defaults

    일단 기본으로 제공되는 BTCUSDT를 추가해 둔 스크린샷이다. 저기서 Add Asset 을 누르면 기본적으로 지원하는 코인들을 추가로 살펴볼 수 있고, 심지어 내가 원할 경우 나만의 코인을 직접 추가하는 것도 가능하다. Add Asset 에서 Create New Asset 메뉴로 들어가보자. 벌써부터 우리의 쓸데없는 상상력이 끓어오른다.

    hollaedash_custom_coin_add

    여기서 새로 추가할 나만의 코인 이름이나 심볼 (KRW, USD 같은), 기타 코인의 최소 단위 (Increment Amount), 출금 최소와 최대금액 (Minimum Withdrawal Amount, Maximum Withdrawal Amount) 입력이나, 유저의 티어 별 출금과 입금 가능 여부 & 수수료 제어 등이 가능하다.

    입력된 코인 정보는 추후 내 거래소 웹사이트의 어드민 페이지에서 편집할 수 있지만, 두번 일은 언제나 귀찮으니 잘 확인하도록.

    holladash_coin_umbokdong

    이런 엄복동 코인같은 괴상망측한 것도 만들 수 있다. 인터넷 밈이 진짜 화폐가 되는 순간이다.

    새 거래 페어 (거래장) 추가하기

    holladash_trading_pair_umbokdong

    새 코인 추가를 모두 마쳤다면, 다음으로는 새 거래 페어를 추가할지 선택할 수 있다.

    거래 페어는 당연하겠지만 이미 거래소에 존재하는 코인들만 사용해서 만들 수 있다. Add Trading Pair 버튼을 누르면 아래와 같이 두 코인을 묶어 새로운 거래 페어를 만들 수 있는데, 유저의 티어 별 거래 수수료 설정 (Account Taker Fee, Account Maker Limit), 최대 / 최소 거래 가능한 금액 설정 (Maximum Tradable Amount, Minimum Tradable Price) 등이 포함된다.

    holladash_add_new_trading_pair

    Technical Setup 까지 모두 마쳤다면, 아래와 같은 팝업이 뜰 것인데, 우리는 이미 Kit과 CLI를 설치했으니까 “Okay”를 눌러 밖으로 빠져나오면 된다.

    holladash_setup_done

    이전 버전에서는 이 창에서 설정 파일을 직접 다운받아야 했지만, 최근 업데이트로 더 이상 수동으로 파일을 다운받고 집어넣을 필요가 없어졌다. 다음으로 넘어가보자.

    Vault 지갑 준비하기 (생략 가능)

    현재 Vault의 공식적인 무료 체험 프로그램은 존재하지 않으나, bitHolla 측으로 따로 연락을 남길 시 유연하게 무료 체험 기간을 제공하고 있다. Vault가 없어도 HollaEx 구동 자체에는 문제가 없으니 의무 사항은 아니다.

    먼저 HollaEx와 Vault 지갑의 연결을 위한 API 키를 발급받아야 한다.

    bitHolla 대시보드의 상단바에서 Wallets 메뉴 - 그리고 사이드바에서 API Keys 메뉴를 선택하자. 그리고 아래 스크린샷과 같이 보이는 Generate API Key 를 선택하면 된다.

    vault_generate_api_key_button

    여기서 Vault Business Wallet 유저가 아닐 경우, 업그레이드 하라는 메시지가 보일 것이다.

    이미 비용을 지불하고 Business로 업그레이드 한 유저나, bitHolla 측으로부터 무료체험 권한을 받은 유저라면, API 키 이름 등을 집어넣고 키를 생성할 수 있다. 키가 생성되면 아래와 같이 목록에 표시될 것이다.

    vault_generated_api_keys_list

    마지막으로, 생성한 API 키 등을 HollaEx Kit의 설정 파일에 넣어줘야 하는데, 이 부분은 아래 거래소 세팅 과정을 진행하며 같이 언급하겠다. 일단은 여기까지!

    거래소 초기 설정하기

    아래의 내용은 bitHolla 공식 문서를 통해 더 자세히 확인할 수 있다. 블로그의 내용이 부족하면 꼭 공식 문서를 함께 참조하자.

    자. 정말 수고하셨다. 간단할 것 같은데 간단하지 않았던 위 과정들을 모두 마친 당신은 이제 거래소를 마주볼 자격이 충분히 있다. 터미널을 하나 띄워서 아까 다운로드 받은 HollaEx Kit 경로로 이동하자.

    이제 아래 명령어를 통해 거래소의 초기 설정을 진행할 수 있다.

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

    hollaex setup
    

    hollaex_login

    hollaex setup을 입력하면 CLI가 내 bitHolla Dashboard의 계정을 물어본다. 잘 채워 넣어주면 곧 내 계정에 연동된 모든 거래소 리스트가 표출될 것인데, 내가 실행하기 원하는 거래소의 번호를 골라 입력하면 된다. 이제 CLI가 자동으로 방금 전 Dashboard에서 설정한 모든 거래소 설정값들을 자동으로 다운로드받아, 내 Kit에 저장해줄 것이다. 위에서도 언급했지만, 이전 버전에서는 이 과정이 수동이였다 (!). 작은 개선점이지만 삶의 질이 팍 올라가는 걸 느낄 수 있다.

    hollaex_setup_import_confirmation

    다음 단계로 CLI가 Docker 이미지를 하나 빌드할 것인데, 이건 내 HollaEx Kit의 /mail/plugins 폴더를 포함하는 나만의 커스텀 HollaEx Core 이미지가 되겠다. 이름에서 에상할 수 있다시피, /mail 폴더는 HollaEx 거래소의 이메일 발송을 담당하는 코드 부분이고, /plugins는 추후 기능 확장에 사용할 수 있는 플러그인이 추가되는 폴더다.

    둘 다 완전한 오픈소스 형태로 저장되어 있고, 유저가 원한다면 얼마든지 커스텀이 가능하니 참고할 것. 지금은 그냥 이대로 진행해도 상관 없다.

    hollaex_setup_image_build_and_push

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

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

    hollaex_setup_all_done

    거래소 시작하기

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

    hollaex_start

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

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

    hollaex status
    

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

    hollaex_status

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

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

    hollaex_health_localhost

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

    hollaex_constant_localhost

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

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

    거래소 웹 서버 띄우기

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

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

    hollaex web --start
    

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

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

    dockerd_memory_allocation_configure

    빌드가 끝나고 정상적으로 웹이 실행된다면, 이제 내가 설정한 도메인 혹은 localhost:8080 주소로 접근할 수 있다! 이쁜 웹 클라이언트가 여러분을 기다린다.

    hollaex_web_main

    물론 지금부터 로그인도 할 수 있는데, 테스트 로그인은 별도의 추가 회원가입 없이 거래소 초기 설정 과정에서 생성한 Admin 계정으로 진행하면 편하다.

    hollaex_signin

    짠. 정상적으로 로그인이 되었다면 아래와 같은 메인 페이지가 독자를 반겨줄 것이다.

    web_successful_login

    이제 정말로 완전한 거래소가 완성되었다. 만약 Vault 연결이나 AWS 연결을 하지 않았다면, 블록체인 네트워크에 암호화폐 지갑 생성, 혹은 유저 인증 SMS 발송 등은 제한되겠지만, Admin 페이지에서 내 계정에 잔액을 채운 후, 거래 페이지에서 자유롭게 내가 생성한 화폐와 거레 페어를 통해 테스트 거래가 가능하다.

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

    Admin 페이지 둘러보기

    HollaEx Kit v1.3부터 대부분의 거래소 관련 설정을 웹 브라우저를 통해 진행할 수 있는 어드민 패널 기능을 제공한다.

    hollaex_admin_main

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

    hollaex_admin_plugins

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

    vault_plugins_input_box

    혹시 위쪽에서 Vault를 위한 API 키를 생성했었다면, 여기 Plugins 탭에서 Vault를 활성화하고 키를 집어넣을 수 있다. 키가 정상적으로 활성화 된다면 현재 내 거래소에 추가된 모든 화폐들이 나열되는데, 그 중 Vault가 지원하는 화폐 이름 옆에 ‘Connect’ 버튼이 생기게 된다. Connect 를 누르면 그 즉시 Vault와 연결되어 추가 과정 없이 암호화폐 입/출금이 가능해진다! 편리해도 너무 편리하다. 연결할 수 있는 화폐를 모두 연결했을 시에는 아래와 같은 모습을 보인다.

    vault_connected_all_currencies

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

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

    찬찬히 내 거래소를 둘러보며 별 문제 없는 것을 확인했다면, 이제 외부에 거래소를 공개해 다른 사람들도 접근할 수 있게 해보자. 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 --restart
    

    추가 정보

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

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

    마치며

    coinpongpong

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

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

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

  • 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 대시보드의 메뉴에서 기능 정지 버튼을 누르면 간단하다.

  • Docker로 쉽게 올리는 나만의 Apt 미러 서버

    gif

    안녕 독자들. 문득 그런 생각이 들었다. 흔히 apt-get 명령어를 통해 필요한 패키지를 쉽게 다운로드 받고, 그게 익숙한 것이 되다 보니 마치 수도꼭지에서 물 틀어 마시듯 당연하게 사용하고 있는데, 만약 무슨 일이 생겨 APT 패키지를 제공하는 서버가 내려간다면?

    사실 그래서 존재하는 것이 미러 (Mirror) 서버다. 원본 서버가 제공하는 정보들을 복제해 다른 경로를 통해 다시 제공하는 것. 꼭 APT가 아니더라도 음악 미러, 동영상 미러 사이트 등의 이름으로 일반인에게도 나름 친숙한 개념이 되었다.

    이미 국내외 다양한 개인, 단체가 제공하는 APT 미러 서버가 있어 한두곳이 내려간다고 해도 사실 행복한 리눅스 라이프에는 큰 지장이 없지만, 그 미러 서버, 우리도 돌려볼 수 있지 않을까?

    직접 미러를 운영한다면 나에게는 언제나 믿고 접근할 수 있는 든든한 APT 백업이 생기는 것이고, 다른 유저들에게는 APT를 사용할 때 선택 폭이 넓어지는 선순환이 될 수 있다. 꼭 퍼블릭하게 공유하지 않더라도, 예를 들어 사내 폐쇄 망에 붙어 돌아가는 서버가 APT를 통한 패키지 설치, 업데이트가 필요할 경우 자체 미러 서버를 운영해 폐쇄 망과 연동시키는 등 활용도는 무궁무진하다. 극단적으로 생각하면 재난 상황 등 인터넷 망이 날아간 상황에서도 리눅스 서버를 세팅하겠다는 뼈브옵스, 뼈발자 분들에게도 도움이 될 수 있겠고.

    깊게 생각하지 않아도, 커뮤니티의 일원이 된다는 것은 언제나 매력적인 일이다. 그 커뮤니티의 일부로서 스스로가 기여한 무언가가 훗날 많은 사람들에게 도움이 된다면 더할 나위 없지 않을까.

    내 컴퓨터에서 APT는 어떻게 동작할까?

    백문이 불여일견이라고, 아리송한 것도 일단 해보면 감이 잡히겠지만, 그 ‘아리송’ 한 상태부터 되기 위해서는 약간의 이론 지식이 필요하다.

    지금 데비안 계열 OS를 사용하고 있다면, /etc/apt/sources.list 파일을 열어 보자. 아래와 같은 내용이 담겨 있을 것이다.

    # See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to
    # newer versions of the distribution.
    deb http://archive.ubuntu.com/ubuntu/ bionic main restricted
    # deb-src http://archive.ubuntu.com/ubuntu/ bionic main restricted
    
    ## Major bug fix updates produced after the final release of the
    ## distribution.
    deb http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
    # deb-src http://archive.ubuntu.com/ubuntu/ bionic-updates main restricted
    
    (...)
    

    빼곡하게 적혀있는 URL의 앞에 적혀있는 deb 는, .deb 확장자로 만들어진 데비안 애플리케이션 패키지를 뜻한다. deb-src 는 패키징이 이루어지지 않은 애플리케이션 소스, 그리고 추후의 패키징을 위해 패키지명 정보 등을 담은 dsc (데비안 컨트롤 파일) 이 되시겠다. 즉, 위 예시 파일은 저장소에서 이미 패키징이 된 deb 파일만 다운로드 받겠다라는 뜻이 된다.

    저장소 URL - http://archive.ubuntu.com/ubuntu/ 은 우분투에서 자체적으로 제공하는 1차 아카이브 (우분투 직속) 저장소에 연결하는 링크다. 일반적으로 사용되는 것은 http 지만, APT는 ftp 등 파일 전송이 가능한 다양한 프로토콜을 함께 지원한다.

    그 뒤에 따라오는 bionic 은 우분투의 버전 코드네임 (18.04 LTS), main, restricted, universe, multiverse 는 저장소에 올라와 있는 애플리케이션이 무료인지, 코드가 완전히 공개되어 있는지, 유료 라이센스가 필요한지 등에 따라 정리해둔 일종의 카테고리라 생각할 수 있겠다. 관련하여 자세히 알고 싶다면 이 링크를 참조하자.

    우리가 APT를 사용하기 위해 apt-get update 명령어를 사용하게 되면, APT는 방금 위에서 살펴본 /etc/apt/sources.list 파일을 기반으로 저장소를 읽어 다운로드 받을 수 있는 프로그램들의 리스트를 만들게 된다. 해당 리스트는 /var/lib/apt/lists 에서 확인할 수 있다.

    리스트를 갱신한 후 apt-get install 명령어를 사용하면 해당 리스트에서 내가 원하는 애플리케이션이 존재하는지 확인한 후, sources.list 에 명시된 원격 저장소에서 패키지를 다운로드해 와 로컬 머신에 설치하게 된다.

    그리고 예상했겠지만, 우리의 APT 미러 서버가 완성될 경우 이 sources.list 에 적혀있는 원격 저장소 URL을 우리 것으로 바꿔줄 것이다.

    대충 내 컴퓨터에 설치된 APT가 무엇을 담고 있는지 살펴봤으니, 본격적으로 미러를 구성해보자.

    미러 서버 올리기

    구조부터 살펴볼까?

    APT 미러는 기본적으로 debdeb-src 가 잔뜩 담겨있는 보따리에 불과하기에, 이론적으로는 온라인에서 파일을 끌어올 수 있는 어떤 도구를 사용하더라도 구축할 수 있지만, 최근에는 [apt-mirror](https://apt-mirror.github.io/) 라는 도구가 마치 표준처럼 널리 사용되고 있다. 언제나 미리 갈려나간고생해준 개발자에게 묵념.

    널리 사용되는 도구인 만큼 APT 리스트에도 올라가 있어 당장 우분투 등의 OS에서 apt-get install apt-mirror 명령어를 통해 설치할 수도 있지만, 조금 더 편리하고 깔끔한 구성을 위해 필자가 도커화시켜 명령어 한 줄이면 모든 것을 실행할 수 있게 이미 다 준비해 두었다. kycfeel/dockerized-apt-mirror 에서 전체 구조를 살펴볼 수 있다.

    Git 저장소를 다운로드 받은 후, mirror.list 파일을 먼저 살펴보자. 마치 조금 전 확인했던 /etc/apt/sources.list 파일처럼, 원격 APT 저장소에 대한 링크와 카테고리 등이 명시되어 있다.

    APT 서버를 직접 구동한다고 해도, 결국 그 안에 들어갈 패키지들은 이미 구비되어 있는 어딘가에서 끌어와야 한다. apt-mirror 는 바로 이 파일에 명시된 원격 저장소에서 각 OS 혹은 버전별 패키지들을 다운로드 (미러링) 한다. 글 작성 시점 (2019년 7월 16일) 기준으로, Git에 올려둔 mirror.list 에는 우분투 공식 저장소 에서 16.04 LTS, 18.04 LTS, 19.04 LTS, 그리고 19.10의 패키지들을 미러링 하도록 명시해 두었다. 물론 필요에 따라 얼마든지 다른 저장소나 버전을 추가할 수 있겠다.

    파일에 문제가 없다면, 이제 crontab/apt-mirror 을 열어보자. 이곳에는 어느 주기로 원격 저장소에서 파일을 다시 받아올 지 명시하는 crontab 규칙이 담겨 있다. 중요한 부분은 파일 맨 앞에 있는 cron 주기 표시다. 기본은 0 4 * * *, 매일 오전 4시에 (UTC) apt-mirror 명령어를 다시 실행하도록 설정해 두었다. 본인의 필요에 따라 수정을 권장하고, cron 규칙이 영 무섭게 생겼다면 crontab.guru 사이트가 도움의 손길을 내밀어줄 것이다.

    마지막으로 postmirror.sh 다. apt-mirror 는 매번 원격 저장소에서 파일을 다운로드 한 후 이 스크립트를 실행해 마무리 작업을 한다. 의무적으로 무언가 요구되는 작업은 없어 이 파일을 공백으로 내비 둬도 상관 없지만, Git 저장소에 올린 파일에는 이 곳에 apt-mirror 의 내부 /var/spool/apt-mirror/var/clean.sh 스크립트를 명시해 둬 다운로드 후 더 이상 필요 없는 찌꺼기를 알아서 지울 수 있게 해뒀다.

    docker-compose.yaml 을 열어보면 방금 확인했던 파일들을 볼륨의 형태로 마운트해 apt-mirror 컨테이너 사용한다는 것을 알 수 있다.

    volumes:
          - ./apt-mirror-volume:/var/spool/apt-mirror
          - ./postmirror.sh:/var/spool/apt-mirror/var/postmirror.sh
          - ./mirror.list:/etc/apt/mirror.list
          - ./crontab:/etc/cron.d
    

    추가적으로, volumes 단락의 맨 위, apt-mirror-volumeapt-mirror 도커 컨테이너가 다운로드 받은 APT 미러 데이터를 저장하는 경로다. Git 폴더에 있는 그 apt-mirror-volume 맞다. 만약 Git 문제 (변경사항을 초기화 한다던지)로 다운로드 받은 APT 데이터의 손상이 걱정된다면 Git 폴더 외부에 따로 저장용 경로를 만든 후 apt-mirror-volume 으로 심볼릭 링크를 걸어주는 것을 추천한다. 아니면 docker-compose 파일 자체를 편집해도 되고. Up to you.

    진짜로 실행하기

    구조를 하나하나 찬찬히 모두 살펴봤으니, 이제 정말 서버를 실행할 때가 왔다. 아래 명령어 한 줄 이면 충분하다. 괜히 도커가 있는게 아니다.

    docker-compose up -d
    

    기본 옵션으로는, 첫 실행 시 로컬 머신에서 직접 도커 이미지를 빌드한다. 만약 이 과정을 생략하고 싶다면, Docker Hub의 kycfeel/dockerized-apt-mirror 저장소에서 언제나 최신 이미지를 다운로드 받을 수 있다. 원하는 버전 태그를 잘 확인하고 사용할 것.

    컨테이너가 올라갔다면, docker logs <apt-mirror-컨테이너-이름> 으로 정상적으로 apt-mirror 가 실행되고 있는지 확인하자. 처음 실행이라면, 약 500GB ~ 600GB 정도의 파일이 다운로드 될 것이다. 다운로드에는 수 시간이 소요될 수 있다. 만약 용량이 너무 부담스럽다면, 상단의 mirror.list 를 수정해 필요없는 저장소를 제외하도록 하자.

    (...)
    
    Running the Post Mirror script ...
    stdout
    03:27:49
    (/var/spool/apt-mirror/var/postmirror.sh)
    stdout
    03:27:49
    stdout
    03:27:53
    Removing 309 unnecessary files [239.2 MiB]...
    stdout
    03:27:56
    [0%]...............................done.
    stdout
    03:27:56
    stdout
    03:27:56
    Removing 0 unnecessary directories...
    stdout
    03:27:56
    done.
    stdout
    03:27:56
    stdout
    03:27:56
    stdout
    03:27:56
    Post Mirror script has completed. See above output for any possible errors.
    
    (...)
    

    위와 같은 로그와 함께 모든 다운로드가 완료되었다면, http://<나의_도메인>/ubuntu 주소를 통해 미러에 접근할 수 있다. 아래와 같은 파일 구조가 보인다면 정상적으로 설치된 것이다.

    screenshot

    이제, 미러가 정말 제대로 동작하는지 확인할 차례다. 우분투 OS의 /etc/apt/sources.list 에 들어가 이미 적혀있는 저장소의 주소 (http://archive.ubuntu.com, http://security.ubuntu.com) 를 http://<나의_도메인>/ubuntu 로 변경한 후, apt-get update 명령어를 실행해 정상적으로 데이터를 받아오는지 확인하자.

    어떠한 오류도 없었다면, 축하한다. 내 미러가 정상적으로 동작한다는 소리다. 이제부터 apt-get 명령어를 통해 설치하는 모든 패키지는 내 미러에서 직접 날아올 것이다. apt-get install -y curl 명령어를 통해 시범으로 curl 을 설치해보자. 로그에 내 미러 도메인이 보이는가? 무언가 뿌듯한 느낌이 든다.

    정리하며

    “인프라”를 구축한다는 것은 다른 것에서는 느끼지 못할 짜릿함이 있다. 평소에는 받아만 쓰던 무언가를 직접 손대고 일으킨다는 것이 종종 짜증으로 느껴질 때는 있지만, 완성된 뒤 많은 사람들이 내가 세운 이것을 발판삼아 상상치도 못했던 멋진 일들을 펼칠 수 있다는 건 무엇도 대체하지 못하는 뿌듯함을 나에게 돌려준다.

    방금 우리가 만든 APT 미러도 “인프라” 의 정의에 명확하게 부합한다. 이 미러가 존재하기에, 사람들은 필요한 패키지를 설치할 때 더 많은 선택권을 가질 수 있고, 이를 적절하게 사용함으로써 빠르게 설치된 패키지를 가지고 멋진 무언가를 조금이나마 수월하게 만들어나갈 수 있다. 여러분은 방금 전 지구적 IT 커뮤니티에 지대한 기여를 하셨습니다. 짝짝. 정말이예요.

    필자가 구축한 APT 미러 서버는 아래의 정보를 참고해 접근할 수 있다. 별다른 일이 없다면 24시간 365일 구동되며, 매일매일 새로운 패키지를 받아온다. 많은 혹사를 기대하겠습니다. 꾸벅.

    (http | https)://mirror.dokupe.xyz/ubuntu

    • Ubuntu 16.04 LTS
    • Ubuntu 18.04 LTS
    • Ubuntu 19.04
    • Ubuntu 19.10 (Latest!)