네트워크 격리 환경에서 Discourse HA 설정

미리 감사드립니다.
프로덕션 환경에서 고가용성(high availability)을 갖춘 Discourse를 설정할 계획입니다. 아래는 제 설계 계획과 일부 환경 조건입니다.

  1. 애플리케이션 서버 3대와 Postgres DB 서버 2대를 구성합니다. PG 서버 중 항상 1대는 쓰기 모드, 다른 1대는 읽기 전용 모드로 운영됩니다.

  2. 이 3대의 애플리케이션 서버는 동일한 DB 서버를 가리키게 됩니다.

  3. 각 DB 인스턴스는 각각 읽기 및 쓰기 전용 작업을 처리해야 합니다.

  4. 프로덕션 서버는 인터넷에 연결되어 있지 않지만, DockerHub 이미지를 가져올 수는 있습니다.

  5. 자체 GitLab 서버를 보유하고 있습니다.

  6. Docker 이미지를 부트스트랩(bootstrap)하여 해당 이미지를 여러 서버에 배포하는 것이 가능한가요?

이 설정을 진행하는 데 도움을 주실 분을 찾습니다. 관련 링크나 제안 사항이 있으시면 개인 메시지(PM)로 보내주세요.

어딘가에서 ./launcher bootstrap app를 실행한 후에는 생성된 컨테이너 이미지를 저장해야 합니다(보통 레지스트리에 푸시하는 방식으로 수행됩니다). 그런 다음 3개의 애플리케이션 서버에서 이미지를 다운로드하여 실행해야 합니다.

중앙 Redis 서버(그리고 잠재적으로 그 복제본)도 필요합니다. 또한 서로 다른 애플리케이션 서버로 요청을 분산하기 위한 로드 밸런서도 빠져 있습니다.

@Falco 답변해 주셔서 감사합니다.

HAProxy 로드 밸런서와 아티팩트 저장용 Nexus 리포지토리를 사용 중입니다.

안녕하세요 @Falco

제 프로덕션 환경에는 인터넷 접근 권한이 없습니다. 그래서 저는 인터넷에 접근할 수 있는 머신에서 부트스트래핑을 수행한 후, 해당 부트스트래프 이미지를 프로덕션 서버로 가져가려는 계획을 세우고 있습니다. 그러나 프로덕션 VM에서 컨테이너가 시작되지 않습니다. Unicorn 서버가 어떤 부모 프로세스 ID를 찾고 있기 때문에 실행되지 않는 것 같습니다.

여기서 도움을 부탁드립니다. 부트스트래핑을 수행한 /var/discourse 디렉토리를 프로덕션 서버로 복사해야 하는지 알려주시면 감사하겠습니다.

여기서 "이 작업"은 무엇을 의미하나요? 부트스트랩 자체를 말하는 건가요, 아니면 이전에 부트스트랩된 컨테이너 이미지를 실행하는 것을 말하는 건가요?

이전에 부트스트랩된 컨테이너 이미지를 실행할 때

이미지를 어떻게 저장하고 프로덕션 서버로 내보냈나요?

정확히 어떤 방식으로 이 저장된 이미지를 프로덕션에서 실행하려고 하는 건가요?

이전에는 Nexus 저장소에 부트스트랩된 이미지를 푸시하고, 프로덕션 서버에서는 Nexus 저장소에서 이미지를 풀링하는 방식을 사용했습니다.

./launcher start-cmd app 명령을 통해 docker run 명령을 생성하고, 동일한 명령을 프로덕션 서버에서 실행했습니다.

프로덕션 환경에서 시작할 때의 에러 로그를 공유해 주실 수 있나요?

run-parts: /etc/runit/1.d/00-ensure-links 실행 중
run-parts: /etc/runit/1.d/00-fix-var-logs 실행 중
run-parts: /etc/runit/1.d/01-cleanup-web-pids 실행 중
run-parts: /etc/runit/1.d/anacron 실행 중
run-parts: /etc/runit/1.d/cleanup-pids 실행 중
오래된 PID 파일 정리 중
runsvdir 시작됨, PID는 42입니다
chgrp: 잘못된 그룹: ‘syslog’
ok: run: redis: (pid 51) 0s
ok: run: postgres: (pid 56) 0s
supervisor pid: 53 unicorn pid: 75
config/unicorn_launcher: 71번째 줄: kill: (75) - 해당 프로세스 없음
config/unicorn_launcher: 15번째 줄: kill: (75) - 해당 프로세스 없음
(53) 종료됨
ok: run: redis: (pid 51) 7s
ok: run: postgres: (pid 101) 0s
supervisor pid: 96 unicorn pid: 103
config/unicorn_launcher: 71번째 줄: kill: (103) - 해당 프로세스 없음
config/unicorn_launcher: 15번째 줄: kill: (103) - 해당 프로세스 없음
(96) 종료됨
ok: run: redis: (pid 51) 14s
ok: run: postgres: (pid 127) 0s
supervisor pid: 120 unicorn pid: 129
config/unicorn_launcher: 71번째 줄: kill: (129) - 해당 프로세스 없음
config/unicorn_launcher: 15번째 줄: kill: (129) - 해당 프로세스 없음
(120) 종료됨
ok: run: redis: (pid 51) 22s
timeout: down: postgres: 0s, normally up, want up
ok: run: redis: (pid 51) 30s
timeout: down: postgres: 1s, normally up, want up
ok: run: redis: (pid 51) 37s
ok: run: postgres: (pid 174) 0s
supervisor pid: 165 unicorn pid: 176
config/unicorn_launcher: 71번째 줄: kill: (176) - 해당 프로세스 없음
config/unicorn_launcher: 15번째 줄: kill: (176) - 해당 프로세스 없음
(165) 종료됨
ok: run: redis: (pid 51) 48s
ok: run: postgres: (pid 196) 1s
supervisor pid: 191 unicorn pid: 198
config/unicorn_launcher: 71번째 줄: kill: (198) - 해당 프로세스 없음
config/unicorn_launcher: 15번째 줄: kill: (198) - 해당 프로세스 없음
(191) 종료됨
ok: run: redis: (pid 51) 54s
timeout: down: postgres: 1s, normally up, want up

외부 PostgreSQL, Redis 및 Object Storage를 사용하고 계신가요? HA를 구성할 경우 이러한 구성은 예상되는 것이며, 프로덕션 서버와 빌드 서버 모두 해당 외부 서비스에 액세스할 수 있어야 합니다.

시나리오를 테스트 중입니다. 한 서버에서 부트스트랩을 수행하고, 다른 서버에서는 스탠드얼론 구성으로 부트스트랩된 컨테이너 이미지를 실행하는 방식입니다.

그건 분명히 안 되는 방법입니다.

오브젝트 스토리지에 대해 언급한 특별한 이유가 있나요? 서버 내부 스토리지로 충분하지 않나요?

HA 구성에서 모든 앱 서버에 discourse 디렉토리를 복사해야 하나요?

여러 앱 서버와 사용자 업로드를 어떻게 처리할 계획인가요? 모든 서버를 연결하는 공유 네트워크 드라이브를 사용할까요? 그것도 가능할 수 있지만, 저희 공식 솔루션은 S3 API를 사용하는 오브젝트 스토리지입니다.

아래와 같은 조건이 충족되는 한 그럴 필요가 없습니다.

네, 외부 Postgres 서버와 Redis 클러스터를 사용하고 있습니다.

Redis 클러스터와 애플리케이션을 함께 실행하기 위해 3대의 앱 서버를 사용하고 있습니다.

discourse 빌드 디렉토리를 위해 공유 디렉토리/스토리지 사용을 사용해야 한다는 점을 알게 되었습니다. @Falco 님, 이제 명확해졌습니다. 감사합니다.

@Falco님, 번거롭게 해서 죄송합니다. 마지막 질문 하나만 더 드릴게요.

리빌드 단계를 수행할 때 기존 Postgres DB의 데이터에 영향을 미치나요? 영향을 미친다면 어떻게 처리해야 하나요?

네, 재빌드 과정에서 실행되는 마이그레이션이 데이터와 구조 모두를 변경합니다.

HA 환경에서는 다음 가이드라인을 따르셔야 합니다: Introducing Post Deployment Migration