마스토돈을 온프레미스 환경으로 이전
매니지드 서비스에서 운영하던 마스토돈 서버를 온프레미스 환경으로 옮겨 왔습니다. 비용은 줄었고 운영 부담은 늘었지만 결과적으로 영속성은 증가했습니다.

일론님이 당시 트위터를 인수한다는 소문이 들릴 무렵 이를 대신할 서비스가 이미 오래 전부터 존재해 왔다는 사실을 알게 되었습니다. 처음 이 서비스를 알았을 때는 이 서비스를 그냥 마스토돈이라고 부르는 줄 알았는데 서비스에 대해 알아보니 마스토돈은 액티비티펍 프로토콜 호환 소프트웨어 중 하나였고 액티비티펍 프로토콜을 공유하며 동작하는 여러 소프트웨어로 구동되는 서비스의 집합을 페디버스라고 부르고 있었습니다. 소셜 네트워크 서비스 또는 마이크로블로그는 사실 그 서비스를 누가 운영하든 말든 그냥 아무말을 할 수 있고 다른 사람들의 아무말을 읽을 수 있기만 하면 된다고 생각했기에 서비스를 누가 인수하든 별로 신경 쓸 일은 아니라고 생각했습니다. 이 때 알게 된 액티비티펍 프로토콜 호환 서비스들을 사용해 다른 누군가가 운영하는 서비스를 사용하는 것과 비교해 훨씬 영속적으로 아무말 할 수 있는 인프라를 유지할 수 있다는 점은 흥미로웠습니다. 뭐 잘은 모르겠지만 일단 마스토돈이라는 액티비티펍 프로토콜 호환 소프트웨어를 사용해 페디버스에 접근해 보기로 했지만 대충 봐도 마스토돈 서비스를 직접 구축하기는 쉽지 않아 보였습니다. 이 당시에는 여전히 AWS에 가장 싼 인스턴스에 온갖 소프트웨어를 설치해 구동하고 있었는데 마스토돈은 딱 봐도 이 사양과 그 시점의 환경에 설치하다가는 기존 서비스를 모두 망가뜨릴 것 같아 겁도 났습니다. 그래서 masto.host라는 매니지드 서비스에 월 6달러를 내고 마스토돈을 사용해 보기 시작합니다.
처음 접한 마스토돈은 당시 트위터와 비교할 때 가본. 적 없는 상상 속의 수도원 같은 느낌이었는데 트위터에서 하던 대로 정말 아무말을 마구 했다가는 순식간에 주변 모든 서버들로부터 차단되기 딱 좋다는 느낌을 받습니다. 하지만 다른 한 편으로는 다른 사람들도 저에게 그렇게 말하지 않으려고 노력할 가능성이 있으므로 조금 조심하고 그 상태가 습관으로 굳어진다면 나쁘지 않을 수 있겠다는 쪽으로 생각을 바꿉니다. 마스토돈을 사용하기 시작하면서 가장 재미있었던 점은 핸들에 서버 이름이 포함된다는 점입니다. 어지간한 다른 사람들은 이미 작동하고 있는 다른 서버를 골라 그 서버 이름이 핸들에 포함되었지만 저는 처음부터 제 도메인의 서브도메인에 마스토돈 매니지드 서비스를 연결했기 때문에 핸들에 제 서버 이름이 포함되었습니다. 제 도메인인 제 이름이기 때문에 굳이 핸들에 제 이름을 포함할 필요가 없었기 때문에 제 이메일 주소와 비슷하게 핸들을 ‘me'라고 정합니다. 처음에는 이 핸들이 재미있다고 생각했지만 시간이 지나며 여러 번 다른 사람이 저에게 멘션을 보낼 때 서버 이름이 생략되면서 ’@me'라고 표시되었는데 이를 자기 자신에게 글을 쓰는 착각을 일으켜 이 핸들이 썩 좋지는 않다는 사실을 인정했습니다.하지만 마스토돈을 포함한 액티비티펍 호환 서비스 상당수는 핸들을 변경할 수 없기 때문에 일단 잘못 만든 핸들을 계속해서 사용하게 됩니다. 핸들을 바꿀 수 없는 서비스가 세상에 어디 있나 싶지만 생각해보면 어린 시절 아무렇게나 만든 이메일 핸들을 이후 평생에 걸쳐 사용하는 것과 별로 다르지 않다고 생각합니다.
액티비티펍 네트워크의 동작을 잘 모를 때는 여러 서버 사이에 글을 전달하는 소위 릴레이 서버에 반드시 등록되어야 한다고 생각했는데 릴레이 서버에 등록하는 일은 문턱이 있는 경우가 많았습니다. 깃헙에 이슈 모양으로 등록하거나 관리자에게 이메일을 보내야 했고 또 서버의 가입 조건이 그들의 요구사항에 일치해야 했습니다. 사실 이런 점들은 앞서 저 자신에게 제핝이 가해지는 만큼 다른 사람들에게도 같은 제한이 가해지기에 시간이 지나 익숙해지면 훨씬 바람직한 모양이 될 것이 분명하지만 이 때의 제 입장에선 좀 갑갑하다는 느낌을 받기도 합니다. 릴레이 서비스는 그냥 존재하는 것 만으로는 서로 연결되지 않는 액티비티펍 호환 서비스 사이에 사용자들끼리 서로 팔로잉 하지 않아도 글을 배달했고 아무도 팔로우 하지 않더라도 알아서 나타나는 여러 서버의 사용자들로부터 배달되어 온 타임라인을 읽는 것은 무척 재미있었습니다. 한국 액티비티펍 네트워크에 널리 퍼진 규칙을 잘 이해하지 못한 채 사용하다가 저에게 들어온 신고를 제 스스로 처리하며 마스토돈에서 아무말을 계속할 수 있을지 고민하기도 하고 불가능하지는 않지만 검색을 위해 별도 서비스를 구동해야 하는 점 때문에 장기적으로 이 서비스를 사용하는 것이 올바른지 의구심을 가지기도 했습니다. 비슷한 문제의식을 가지고 계신 분들은 자신의 글을 자동으로 구글 스프레드시트에 기록하는 식으로 검색의 부재에 어느 정도 대응하고 계셨는데 근본적으로 지속 가능한 방법은 아니라고 생각합니다. 또 몇 번인가 여러 서버에 걸친 트래픽이 릴레이를 통해 등록된 서버 전체에 퍼져 여러 서버를 손쉽게 망가뜨리는 모습을 보며 이 네트워크의 결함 내구성이 생각보다 떨어진다는 점을 깨닫습니다. 하지만 이런 단점들에도 불구하고 누가 서비스를 운영하든 상관 않고 제 아무말을 계속할 수 있고 이 환경이 영속적일 가능성이 높다는 점 때문에 마스토돈을 계속해서 사용하기로 합니다.
한편 가장 싼 매니지드 서비스라도 릴레이로 연결된 액티비티펍 네트워크에 대량의 트래픽이 갑자기 쏟아지지 않는 이상 저 혼자 사용하기에는 사양이 충분했기 때문에 당시 항상 가입 가능하지 않던 서버들이 많아 가입할 수 있는 곳을 찾는 분들께 자리를 낼 수 있지 않을까 싶었지만 핸들에 서버 이름이 포함되는 마당에 서버 이름에 제 이름이 박혀 있는 도메인을 권할 수는 없었습니다. 대신 다른 사라들도 가입할 만한 너무 이상하지 않은 - 사람 이름이 도메인에 박혀 있지는 않은 - 서버를 만들어 둘 수 있지 않을까 싶은 생각이 들어 조금은 충동적으로 kono.pub이라는 서버를 운영하기 시작합니다. 누군가 코인노래방의 줄임말이냐고 물었지만 실은 개인적으로 인생에 큰 영향을 준 영화인 ‘Lord of War'라는 영화 초반부에 등장하는 배 이름입니다. 극중에서 주인공은 불법 무기 밀매상인데 배에 무기를 싣고 가던 도중 인터폴의 추격을 받고 있다는 사실을 미리 연락 받게 됩니다. 이 배의 원래 이름은 ’Kristol’이었고 인터폴은 이 배의 이름을 정확히 알고 있습니다. 체포를 피해야만 하는 주인공은 재빨리 이미 등록되어 있는 가장 짧은 이름인 네달란드 선적의 ‘Kono'라는 이름으로 배 이름을 변경합니다. 이전 이름을 지우고 새 이름을 칠하는 동안 네덜란드 국기가 없어 잠깐 위기에 처하지만 벨기애 국기를 돌려 네덜란드 국기라고 주장해 인터폴의 수색을 무사히 넘깁니다. 개인적으로 이 장면을 좋아하는 이유는 우리들이 세상을 살아가는 모습이 이와 별로 다르지 않다고 생각했기 때문입니다. 벨기애 국기를 돌려 네덜란드 국기라고 주장하며 대충 문제를 때우며 살아가는 것과 비슷합니다.
다른 서버에 비해 가입을 열어 놓는 것 외에는 아무 것도 하지 않았기 때문에 사용자는 적었지만 그 상태면 충분합니다. 서버에 따라 서버 관리자가 캐릭터성을 가진 채 활동하거나 모더레이터를 설정하기도 하고 또 서버만의 특별한 주제나 역할을 주장하기도 하며 즐길 거리를 만들기도 했고 이런 서버들의 인기가 훨씬 높았지만 결국 아무말 하기 위한 인프라에 뭐 그런 활동이 필요한가 싶어 아무 것도 하지 않았습니다. 또 처음에는 반드시 필요한 줄 알았던 릴레이는 사실 사용자 각각의 팔로잉에 기반해 다른 서버의 존재를 알 수 있고 이를 기반으로 타임라인을 채울 수 있었기에 릴레이가 반드시 필요한 것은 아니라는 사실을 깨달았고 굳이 사용자들이 팔로잉 하지 않는 서버들로부터 글을 가져와 사양을 점유할 필요는 별로 없다고 생각해 아무 릴레이도 붙이지 않았습니다. 덕분에 아주 낮은 비용으로도 서비스를 지탱할 수 있게 됩니다. 시간이 지나며 굳이 제 이름의 도메인에 기반한 서버와 동시에 운영할 필요가 없다는 생각이 들어 맨 처음 만들었던 마스토돈 서버 운영을 중단하고 나중에 만든 ‘kono.pub'으로 계정을 옮겨 서버를 하나만 남깁니다. 이 때 계정을 옮기면 소셜그래프 이외에는 아무 것도 유지되지 않는다는 사실을 직접 체험했습니다. 이미 액티비티펍 호환 서비스 대부분이 핸들 변경을 지원하지 않지만 다른 핸들로 전환할 수는 있다는 것을 알고 있었습니다. 그런데 계정 사이에 글을 옮겨 주지는 않으며 오직 소셜그래프만 유지해 준다는 것을 알고는 있었습니다. 마스토돈은 설정 화면에서 글 목록, 블록한 사람 목록, 북마크 따위를 내보내 별도 파일로 가지고 있을 수 있지만 이를 복원할 방법은 전혀 제공하지 않는데 이럴 거면 이 내보내기 기능은 왜 존재하는지 모르겠습니다. 블로그 전체를 복원할 수 있을 것처럼 행동하지만 실상 글 이외에는 아무 정보도 포함하지 않아 복원에 쓸모가 없는 고스트 익스포트 파일과 비슷한 것 같기도 합니다.
한편 한국 액티비티펍 네트워크에는 여러 서버가 나타났다 사라지곤 했는데 무료로 사용할 수 있는 VPS를 사용하는 서버들이 나타났다가 버전 업데이트나 마이그레이션에 기술적인 문제를 겪다가 사라지기도 하고 또 장기간에 걸친 비용 문제로 사라지기도 합니다. 근본적으로 액티비티펍 프로토콜 호환 서비스를 운영해 돈을 벌 방법이 거의 없기에 서비스 제공자들은 대부분 자원봉사에 가깝게 서비스를 운영하고 있었기에 서비스가 나타나고 사라지는 것은 어쩔 수 없는 현상인 것 같습니다. 저 역시 매달 완전관리 서비스에 비용을 내고 있었기에 그 비용이 적다 하더라도 지속적으로 아무말 인프라에 비용을 지출하고 있는 것은 사실입니다. 오래 전 AWS의 가장 작은 인스턴스를 사용하던 서비스들을 온프레미스로 옮겨 비용을 크게 줄이기 시작했는데 장기적으로 마스토돈 서비스 역시 이쪽으로 옮길 수 있지 않을까 하는 생각을 하기 시작합니다. 특히 매니지드 서비스의 스토리지와 데이터베이스 사용량이 가장 싼 요금제의 한계를 넘어서기 시작해 비용이 증가할 위기에 처했는데 그냥 한 단계 높은 요금제로 바꾸면 간단히 해결할 수 있었지만 이 비용이 늘어남에 따라 장기적으로 서비스를 유지할 여력이 줄어들 수 있지 않을까 하는 생각을 했습니다. 또 얼마 전부터 액티비티펍 네트워크를 통한 아무말 인프라에 hollo라는 작고 단순하고 가벼운 소프트웨어를 도커를 사용해 온프레미스 환경에 구축하고 운영하기 시작하면서 더더욱 매니지드 서비스에서 돌고 있는 마스토돈 서비스의 유지비용을 낮추고 또 넉넉한 온프레미스 사양에서 구동하게 만드는 편이 낫지 않을까 싶어집니다. 마침 좀 전부터 블로그를 매니지드 서비스에서 온프레미스로 옮겨 와 30일 기준 99% 이상의 업타임을 기록하고 있었기에 어떻게든 해볼 수 있지 않을까 싶어 마스토돈을 온프레미스로 옮겨 오기로 결정했습니다.
하지만 마스토돈에 처음 관심을 가질 때 직접 구축하지 않고 매니지드 서비스를 사용했단 가장 큰 이유가 바로 비 엔지니어 입장에서 마스토돈이 요구하는 기술 스택이 복잡하다고 느꼈기 때문입니다. 웹 서버 구동에 여러 가지 스택을 요구했고 또 익숙한 관계형 데이터베이스 뿐 아니라 메모리 데이터베이스도 요구합니다. 여기에 아직도 정확한 용도를 잘 모르는 사이드킥 서비스와 스트리밍 서비스를 별도로 요구했고 만약 제한적인 검색을 필요로 한다면 엘라스틱서치를 별도로 사용해야 했습니다. 하지만 시간이 지나며 웹, 사이드킥, 스트리밍은 같은 도커 이미지로 구동할 수 있게 바뀌어 이미 온프레미스에서 구동되는 서비스 대부분을 도커로 구동하는 마당에 어떻게 비벼볼 수 있는 수준까지 난이도가 낮아졌습니다. 하지만 도커 기반으로 마스토돈을 구동하는 일은 이전에 다른 서비스를 도커 기반으로 구동하는 것과는 상당히 다른 어려움이 있었는데 가장 갑갑했던 점은 모든 설정이 개발자의 예상대로 완벽하게 만들어져 있지 않으면 비 엔지니어 입장에서 별 도움이 안되는 스택 트레이스를 뿜어내며 구동을 멈춰 버리는 점입니다. 밑도 끝도 없이 익숙하지 않은 라이브러리로부터 뿜어져 나온 에러메시지와 함께 구동이 중단되지만 그 메시지만으로는 문제 해결에 거의 아무런 도움을 받지 못합니다. 심지어 설정에 계속 실패하다가 인터랙티브 셋업 스크립트가 있다는 것을 나중에서야 알게 되어 이걸 사용하면 그나마 서비스를 구동은 되도록 만들 수 있지 않을까 싶어 실행했는데 설정을 기록할 파일을 미리 만들어 놓지 않았다는 이유로 스크립트가 크래시되는 것을 보고 이게 과연 서비스를 구축하라고 만든 것이 맞기는 한지 의심스럽기까지 했습니다.
하도 어이가 없어 얼마 동안 마스토돈을 온프레미스로 옮겨 오려는 계획 자체를 중단했다가 다시 기력을 충전한 다음 이번에야말로 개발자가 의도했을 모든 설정을 모든 올바른 위치에 준비한 끝에 테스트 도메인에서 마스토돈 웹 서비스를 띄우는데 성공합니다. 핵심은 정말 그 모든 설정이 개발자가 예상한 정확한 위치에 정확한 모양으로 준비되어 있는 것입니다. 이들 중 어느 하나라도 빠지면 이 설정과는 별 관련이 없어 보이는 엉뚱한 곳에서 엉뚱한 메시지를 뿜으며 크래시되기에 정말 정말 그 모든 설정을 절대 빠뜨리지 않고 정확히 준비해야 했습니다. 이어서 매니지드 서비스로부터 데이터베이스를 받아 복구해보니 마스토돈 웹에 기존 글들이 모두 제대로 표시되는 것을 보고 옮겨올 수 있겠다는 생각을 하게 됩니다. 다만 이 서비스 역시 지난번 고스트 매니지드에서 온프레미스로 옮겨올 때와 마찬가지로 데이터베이스를 받기는 쉬웠지만 파일을 쉽게 받을 수는 없었습니다. 데이터베이스 덤프는 매 24시간마다 자동으로 업데이트 되어 이를 받아 온프레미스 환경에 복원해보고 실제 복원 시나리오를 준비하고 미리 연습해볼 수 있었지만 파일을 받으려면 서비스를 중단해야만 했기 때문입니다. 세 번 정도 예행연습을 한 끝에 실제 서비스를 옮겨올 수 있겠다고 판단하고 어느 주말에 서비스를 중단하고 데이터베이스를 덤프하고 또 업로드된 파일의 다운로드를 요청합니다. 사실 전체 다운타임을 30분 정도로 예상했는데 서비스를 중단한 다음 데이터베이스 덤프, 파일 압축, 다운로드에 예상보다 시간이 더 걸리며 다운로드에만 30분 이상을 소요했습니다.
가장 걱정한 점은 ‘masto.host’는 미디어를 별도 CDN을 통해 서비스하고 있었는데 이를 그냥 가져다가 복원하면 온프레미스 환경에서 잘 돌아갈까 하는 것입니다. 다행히도 마스토돈 웹서비스 경로에 미디어 파일을 복원하자 아무 문제 없이 파일이 나타나 걱정을 덜었습니다. 다만 백업을 요청할 때 캐시를 포함해 요청했는데 여기에 시간이 많이 걸렸습니다. 캐시는 재구축 할 수 있으니 포함하지 않는 편이 낫지 않았을까 싶습니다. 데이터베이스 복원은 이전에도 여러 차례 실험해봤던 터라 아무 문제 없이 진행되었습니다. 데이터베이스와 미디어를 복원한 다음 마지막으로 한 일은 도메인 설정을 테스트 도메인에서 실제 도메인으로 변경하고 테스트 도메인에서 외부에 서비스가 노출될 경우 혹시 다른 액티비티펍 서비스에 문제를 일으킬 수 있지 않을까 싶어 서비스를 클라우드플레어 액세스 뒤에 배치한 상태에서 클라우드플레어 액세스를 제거하는 것입니다. 사실 클라우드플레어 액세스는 외부로부터 접근을 막아 주지만 내부에서 외부로 나가는 트래픽을 막지 않아 혹시 테스트 도메인에 복원된 마스토돈이 다른 서버에 문제를 일으키지 않을까 걱정했는데 다행히도 다른 서버와 인터랙션은 양방향 모두 접근 가능한 상태에서만 일어나는 것 같습니다. 지난 블로그 이전 때와 마찬가지로 DNS를 클라우드플레어 터널 주소로 변경하자 몇 분 안에 트래픽이 온프레미스 서버로 들어오기 시작합니다. 사실 다른 서버와 글 교환이 잘 일어나는지는 실제 복원 이전까지 미리 테스트 할 수 없었기 때문에 만약 클라우드플레어 액세스를 제거하고 DNS를 변경한 시점에 뭔가 문제가 생기면 해결 방법이 없다는 점이 굉장히 걱정스러웠는데 클라우드플레어 액세스를 제거해 양방향 통신이 가능해지자마자 바로 다른 서버로부터 글을 받아오는 것을 보고서야 안심했습니다.
그렇게 매니지드 서비스 섭스크립션을 중단하고 마스토돈 서비스를 완전히 온프레미스로 옮겨 왔습니다. 온프레미스 환경에서는 스토리지도, 데이터베이스 용량도 거의 제한이 없기에 이전에는 컨텐츠와 캐시 리텐션 설정을 꽤 타이트하게 했었지만 그럴 필요가 전혀 없어집니다. 데이터베이스는 아무리 커져도 전체 스토리지의 아주 작은 부분만을 차지할 뿐이고 이는 로컬 미디어와 리모트 미디어 캐시도 마찬가지입니다. 이들의 용량이 아무리 늘어난다 하더라도 지금 수준의 사용량이라면 사용에 아무 제한을 안 둬도 아무 문제가 없을 것 같습니다. 다만 지난 30일 동안의 가동률은 99.12%인데 여전히 720시간 기준 매달 여섯 시간 이상의 다운타임이 발생한다는 의미이기에 개선의 여지가 있습니다. 고스트 블로그와 마찬가지로 가동률을 떨어뜨리는 가장 큰 원인은 클라우드플레어 터널의 모든 연결이 유실된 다음 복원되지 않는다는 점인데 이건 개인 수준에서 해결할 수 있는 문제가 아닌 것 같아 보입니다. 리버스 프록시를 직접 통제할 수 있는 다른 소프트웨어로 교체할 생각을 안 해본 것은 아니지만 암만 생각해도 클라우드플레어 터널 같은 보안 서비스는 이를 잘 하는 회사에 맡겨 놓는 편이 더 낫다고 판단했습니다. 당장의 문제는 일정 시간마다 cloudflared를 재시작해서 회피하고 있습니다.
결국 이렇게 마스토돈을 온프레미스로 옮겨올 줄 미리 알았다면 맨 처음 만들었던 마스토돈 서버를 없애지 말 걸 그랬다는 생각이 들기도 하지만 덕분에 훨씬 가볍고 단순하게 동작하는 hollo라는 서비스를 사용하게 됐고 또 액티브 유저가 있는 마스토돈 서비스를 온프레미스 환경으로 옮겨 오는 경험도 해 봤으니 아쉬움이 없지는 않지만 결과적으로 나쁘지 않다고 생각하기로 합니다. 이 과정을 통해 기존 매달 매니지드 서비스에 지출이 사라져 온프레미스 환경을 기존과 똑같이 유자하기만 하면 추가 비용이 거의 없이 마스토돈 서비스를 유지할 수 있게 되어 이전에 비해 좀 더 나은 영속성을 갖출 수 있게 되었습니다. 또 이번 이전은 작업을 최대한 단순하게 만들기 위해 할 수 있었지만 엘라스틱서치를 포함하지 않았는데 이것도 적당한 시점에 서비스에 포함하면 매니지드 서비스에서는 별도로 비용을 지불해야 사용할 수 있었던 검색을 추가 비용 없이 제공할 수 있을 것 같습니다. 남은 과제는 현재 환경에서 월간 가동률을 99% 수준에서 99.5% 이상으로 올리는 것입니다.
지금은 masto.host를 사용하고 있지 않지만 여전히 저처럼 비 엔지니어가 마스토돈 서버를 구축하고 운영에 일절 신경 쓰고 싶지 않을 때 이 서비스를 개인적으로 여전히 추천합니다. 일단 제가 운영하는데 비해 가동률이 훨씬 높을 뿐 아니라 크리티컬한 보안 문제에 굉장히 빠르게 대응합니다. 특히 보안 문제가 발생했지만 아직 공식 버전 업데이트가 나오기 전에 먼저 소스코드 수준에서 대응해 배포하고 나중에 공식 버전 업데이트가 나오면 이쪽으로 대체하는 점은 무척 인상적이었습니다. 또 기본적으로 데이터베이스를 암호화 하고 있습니다. 물론 암호화 키를 함께 가지고 있기 때문에 사용자들의 우려를 완전히 해소할 수는 없지만 일반적인 데이터베이스 브라우징 도구로 편안하게 데이터베이스를 열어볼 수는 없습니다. 불가능하지 않지만 대단히 귀찮은 과정을 거쳐야만 하기에 나쁘지 않다고 생각하기 때문에 데이터베이스 수준의 암호화를 수행하고 있다는 점은 관리자 입장이나 사용자 입장 양쪽 모두에서 이 서비스를 신뢰할 만 하게 만들어 줍니다. 만약 미래에 다시 매니지드 서비스를 사용해야 하는 상황이 생긴다면 다시 이 서비스를 고려할 겁니다.