웹과 데이터 컨테이너를 분리하여 빠르게 마이그레이션하기

:warning: 경고: 리눅스 시스템 관리자로 일하는 데 익숙하지 않거나 Docker 컨테이너 사용 경험이 없다면, 멀티 컨테이너 배포로 전환하는 것이 어려울 수 있습니다. 이 곳의 스태프와 자원봉사자들도 적절하게 launcher 스크립트에 의해 완전히 관리되는 스탠드얼론 단일 컨테이너 배포로 되돌아가도록 요청할 것입니다.

멀티 컨테이너 배포로 전환한 후 시스템이 고장 나면, 고장 난 두 부분을 모두 보유하게 될 가능성이 큽니다. 아래 설명을 읽고 이것이 컨테이너 내부에서 실제로 어떻게 작동하는지 설명하는 것이 아니라 마법처럼 느껴진다면, 가장 가까운 기본 스탠드얼론 배포로 달려가세요(걷지 마세요). 그러면 당신 자신에게 도움이 될 것입니다.

단일 컨테이너 배포에서 멀티 컨테이너 배포로 마이그레이션하는 권장 방법은 기본적으로 다음과 같습니다:

  • Discourse 백업
  • 전체를 삭제
  • 멀티 컨테이너 배포로 처음부터 시작
  • 백업 복원

저처럼 복구에 시간이 수 시간 걸리는 큰 사이트를 운영 중이라면, 더 빠른 방법이 있을지 궁금해할 수 있습니다. 더 이상 궁금해하지 마세요! 저는 스탠드얼론 배포에서 웹, 데이터, 레디스 컨테이너 3개로 구성된 배포로 마이그레이션하는 데, 해당 사이트의 ./launcher rebuild app 실행에 일반적으로 걸리는 시간보다 더 짧은 시간이 걸렸습니다. (총 다운타임 12분. 앱 재구축에는 때로는 30분 이상 걸리기도 했습니다.) 제 경험을 바탕으로, 미래에는 Redis를 Postgres와 함께 단일 data 컨테이너에 유지할 것입니다.

이 작업을 수행하면 다른 컨테이너(데이터, 그리고 저처럼 멍청하게 Redis를 분리했다면 Redis도 포함)를 언제 재구축해야 하는지를 알아내는 책임은 당신에게 있습니다. 더 이상 ./launcher rebuild app으로 모든 것에 대한 무료 업그레이드를 받을 수 없습니다. 이 프로세스를 관리할 자원이 없다면 스탠드얼론 배포를 사용하거나 호스팅된 Discourse를 구매하세요.

테스트

이 프로세스를 읽은 후, 멀티 컨테이너에서 단일 컨테이너로 빠르게 마이그레이션하는 방법도 이해하게 되었다면, 이 프로세스를 사용하여 멀티 컨테이너로 마이그레이션하지 마십시오. 만약 이 글을 읽고 나서 그것이 명확하지 않다면, 이 게시물은 충분히 고급 기술(즉, 마법과 구별할 수 없는 수준)이며, 이 프로세스가 중간에 실패하는 경우를 인식하지 못할 수도 있으므로, 나중에야 깨닫게 될 수 있는 고장 난 Discourse를 보유하게 될 수 있습니다. 만약 그런 일이 발생하면, 고장 난 두 부분을 모두 보유하게 됩니다. 고장낸 사람은 그것을 사야 한다는 말처럼 말입니다!

백업

먼저 백업하고, 복원 시 모두 다시 구축하지 않도록 썸네일 백업을 먼저 활성화하세요. 여기서 실수를 하면, 복구하는 가장 쉬우면서 안전하고 빠른 방법이 정상적인 방법으로 전환하는 것이 되는 상황에 쉽게 빠질 수 있습니다. 문제가 발생하면 권장 방법으로 되돌아갈 준비를 하세요.

백업을 다운로드하세요. 아래 명령어는 Discourse 데이터 내에서 파일을 이동하는 것을 포함하며, 실수를 하면 백업을 삭제했을 수도 있습니다. 따라서 다운로드하세요. 그리고 업로드가 백업에 포함되지 않았다면, 그것도 백업하세요. 그것들도 파일을 이동할 위치에 있습니다.

진심으로, 백업하세요.

제가 이 작업을 수행했을 때, 먼저 백업을 하고, 더 이상 진행하기 전에 원격 시스템 백업을 수행했습니다.

새로운 멀티 컨테이너 구성 설정

최소 containers/web_only.yml과 containers/data.yml이 필요하며, Redis를 분리하고 싶다면 containers/redis.yml도 필요합니다. samples/data.yml(선택적으로 samples/redis.yml)을 containers/ 디렉토리로 복사하여 시작하세요.

Redis를 별도로 배포하는 경우, containers/data.yml 파일 상단의 Redis 템플릿을 제거하세요. (하지만 좋은 이유 없이 그렇게 하지 마세요. 그냥 추가적인 작업일 뿐입니다.)

web_only.yml을 만드는 방법은 두 가지가 있습니다.

  1. samples/web_only.yml을 containers/로 복사한 후, 둘 다 containers/app.yml과 비교하여 새로운 containers/data.yml의 params:에 있는 Postgres 구성을 유지하세요.
  • containers/app.yml의 Postgres용 params:를 containers/data.yml로 복사
  • SOME_SECRET을 대체할 고유한 비밀번호 생성
  1. 또는 containers/app.yml을 containers/web_only.yml로 복사하고 samples/web_only.yml과 비교하세요.
  • Postgres 및 Redis 템플릿에 대한 모든 참조 제거
  • Postgres 설정만 있었던 전체 params: 섹션 제거
  • samples/web_only.yml에서 그대로 가져오거나, Redis를 별도의 컨테이너로 배포하는 경우 수정된 links: 섹션 추가 (아래 참조)
  • samples/web_only.yml에서 데이터베이스 섹션을 추가하고 SOME_SECRET을 대체할 고유한 비밀번호 생성
  • 볼륨 정의에서 standalone을 web_only로 변경

Redis를 데이터 컨테이너의 Postgres와 묶는 합리적인 기본값 대신 자체 컨테이너로 분리하는 경우 사용할 links: 섹션은 다음과 같습니다:

# 컨테이너를 함께 연결하기 위해 'links' 키를 사용하세요. 즉, Docker --link 플래그를 사용하는 것입니다.
links:
  - link:
      name: data
      alias: data
  - link:
      name: redis
      alias: redis

Redis와 Postgres 컨테이너를 단일 데이터 컨테이너로 결합하는 경우 redis 링크는 필요하지 않습니다. 이는 수행할 내용을 보여주는 것입니다.

samples/data.yml의 env에 있는 현재 Postgres 설정의 사본이며, 여기서 SOME_SECRET을 변경해야 합니다:

  ## TODO: 데이터베이스 연결 구성
  DISCOURSE_DB_SOCKET: ''
  #DISCOURSE_DB_USERNAME: discourse
  DISCOURSE_DB_PASSWORD: SOME_SECRET
  DISCOURSE_DB_HOST: data
  ## 단일 데이터+레디스 컨테이너를 사용하는 경우, 다음 값은 "data"가 됩니다.
  DISCOURSE_REDIS_HOST: redis

정상적인 배포(멀티사이트가 아닌)의 경우, 다른 행을 수정할 필요가 없습니다. DISCOURSE_DB_SOCKET은 Postgres용 유닉스 도메인 소켓이며, 포트 번호가 아닙니다.

app.yml에서 samples/web_only.yml 대신 복사한 경우 web_only.yml 끝의 볼륨 정의에 필요한 변경 사항의 예는 다음과 같습니다:

@@ -75,10 +80,10 @@
 ## Docker 컨테이너는 무상태(stateless)입니다. 모든 데이터는 /shared에 저장됩니다.
volumes:
   - volume:
-      host: /var/discourse/shared/standalone
+      host: /var/discourse/shared/web_only
       guest: /shared
   - volume:
-      host: /var/discourse/shared/standalone/log/var-log
+      host: /var/discourse/shared/web_only/log/var-log
       guest: /var/log

이제 containers/web_only.yml에서 사용한 것과 동일한 비밀 비밀번호를 containers/data.yml의 SOME_SECRET 대신 설정하세요.

이제 마이그레이션을 준비할 수 있습니다.

지금, 빠른 마이그레이션을 시도하기 전에 최종 백업을 수행하고 다운로드하는 시점입니다. 기억하세요, 여기서 문제가 발생하면 즉시 권장 방법으로 전환해야 합니다. 이것을 아무리 강조해도 부족합니다.

데이터(Postgres)와 Redis 컨테이너 분리:

cd /var/discourse

./launcher stop app
cd  shared
mkdir data
mkdir redis
mv standalone/postgres_* data/
mv standalone/redis_data/ redis/
mv standalone web_only
mkdir -p data/log/var-log
mkdir -p redis/log/var-log

cd ..

./launcher destroy app

./launcher bootstrap data
./launcher bootstrap redis
./launcher start redis
./launcher start data

./launcher bootstrap web_only
./launcher start web_only

Postgres+Redis 통합 데이터 컨테이너:

cd /var/discourse

./launcher stop app
cd  shared
mkdir data
mv standalone/postgres_* data/
mv standalone/redis_data/ data/
mv standalone web_only
mkdir -p data/log/var-log

cd ..

./launcher destroy app

./launcher bootstrap data
./launcher start data

./launcher bootstrap web_only
./launcher start web_only

또한 이전에 외부 nginx를 설정했다면, proxy_pass 경로를 새로운 web_only 소켓 위치와 일치하도록 변경해야 합니다. 예를 들어 http://unix:/var/discourse/shared/standalone/nginx.http.sock:에서 http://unix:/var/discourse/shared/web_only/nginx.http.sock:으로 변경합니다.

저의 경우, 2코어 VM과 4GB RAM, 다운로드를 제외한 600MB 백업이 있는 사이트에서 이 프로세스는 12분의 다운타임으로 이어졌습니다. 결과는 개인차가 있을 수 있습니다.

아직까지 이 중 어느 것도 launcher를 업데이트하지 않는다는 점에 유의하세요. 최신 버전이 아닐 수 있습니다. (예를 들어, 저는 Postgres 12 업데이트가 사용 가능해진 후에, 적용하기 전에 이 작업을 수행했습니다. 이 프로세스는 저를 Postgres 10에 머물게 했습니다. 그리고 제가 다음으로 한 일은 데이터 앱을 재구축하여 launcher를 업데이트하고 Postgres 12 업데이트 프로세스를 성공적으로 거치는 것이었습니다.)

향후 업데이트 시 수행할 작업

이 마이그레이션 후, Redis 또는 데이터를 업데이트해야 하는 경우, 먼저 웹 앱을 중지해야 합니다. 이는 다음과 같을 것입니다:

./launcher stop web_only
./launcher rebuild data # 그리고/또는 redis
./launcher rebuild web_only

data(또는 postgres, 또는 redis) 컨테이너를 재구축하면, 새로운 데이터 컨테이너와 다시 연결하기 위해 새로운 웹 컨테이너를 생성해야 합니다. web_only를 재구축하거나, 재구축이 필요하지 않다고 생각한다면 ./launcher destroy web_only; ./launcher start web_only로 처리할 수 있습니다 (그리고 “missing data container” 또는 유사한 오류가 발생하면, 이것이 수행해야 할 작업입니다).

그러나 Postgres나 Redis 모두 업데이트가 필요하지 않은 경우, 해당 컨테이너를 재구축할 필요가 없으므로 훨씬 빠릅니다. 대부분의 앱 재구축은 단순히 ./launcher rebuild web_only입니다.

또는, 더 적은 다운타임(보고된 바에 따르면 15초에서 2분 사이)을 위해:

./launcher bootstrap web_only
./launcher destroy web_only && ./launcher start web_only

다시 말하지만, 멀티 컨테이너 배포로 전환함으로써, 그것이 적절한 시점을 추적하는 것은 이제 당신의 일입니다. 업데이트에 대한 알림은 관리자 콘솔에서 받게 되지만, 그것들은 web_only 컨테이너에만 적용됩니다. Postgres나 Redis를 업데이트해야 할 시점에 대해 알려주는 것은 없습니다. 이렇게 한다면, 수행하는 모든 버전 업그레이드 전에 Announcements 카테고리를 읽고, 업그레이드하는 모든 새로운 버전의 릴리스 노트를 읽으세요. 즉, 버전 업데이트를 건너뛰는 경우, 업데이트를 건너뛴 버전의 릴리스 노트를 읽지 마세요. (최신 상태를 유지하기 위해 릴리스 노트에 감시(watch)를 설정하거나 피드 리더를 https://meta.discourse.org/tag/release-notes.rss에 구독하는 것을 고려해 보세요.)

web_only 컨테이너 재구축에는 데이터베이스가 실행 중이어야 하므로, 두 개 또는 세 개의 컨테이너를 병렬로 재구축하여 속도를 높일 수 없습니다. 매번 모두 재구축할 계획이라면, 표준 권장 스탠드얼론 배포를 유지하세요. 여러 컨테이너를 다루는 것보다 빠를 것입니다.

백업 검토

업로드를 데이터베이스와 별도로 백업하는 경우, 재해 시 복원을 위해 업로드가 파일 기반 원격 백업 체제로 백업되고 있기를 바랍니다.

원격 백업 구현을 검토하여, 업로드가 /var/discourse/shared/standalone 대신 /var/discourse/shared/web_only에 백업되도록 확인하고, 새로운 멀티 컨테이너 구현에서 백업이 최신 상태를 유지하도록 하세요.

22개의 좋아요