운영·확장·보안
📍 현재 위치: Part VI · 규모에 맞춘 운영 — 스택은 동작한다. 이제 그것을 살아 있게 유지하고, 단단히 잠그고, 새벽 3시에 무언가 망가졌을 때 복구 가능하게 만들 차례다.
주방을 짓는 것은 즐거운 일이다. 위생 점검을 10년 동안 매일같이 통과하는 식당을 운영하는 것은 어려운 일이다. 이 장은 둘째 날(day two)에 관한 이야기다. 디스크가 가득 차는 밤, 새 CVE가 떨어지는 아침, "지난 화요일 시점으로 복구할 수 있다는 걸 보여 달라"고 묻는 감사. 오픈소스는 당신에게 아름다운 주방을 지어 준다. 하지만 화재 진압 설비, 출입문 자물쇠, 점검관이 읽는 점검 일지 — 그런 것들은 당신이 직접 설치하고 유지해야 하고, 그중 몇 가지는 결국 돈을 주고 사게 된다.
이 장에서 다루는 내용
우리는 스물네 개 장에 걸쳐 플랫폼이 어떤 일을 하게 만들어 왔다. 이 장은 그 플랫폼이 어떤 일을 견디게 만든다. 오픈소스가 정직하게 시험받는 네 가지 둘째 날의 현실을 차례로 살펴본다.
- 고가용성(high availability, HA): "그냥 클러스터링하면 되잖아"가 들리는 것보다 왜 더 어려운지, 그리고 무료 MQTT 브로커 클러스터링이라는 이야기가 2025년에 어떻게 쪼그라들었는지.
- 백업과 시점 복구(point-in-time recovery, PITR): 규제 당국이 반드시 시연을 요구할 단 하나의 것, 그리고 그것을 PostgreSQL에서 일상으로 만들어 주는 도구.
- 네트워크 분리(network segmentation), TLS, 인증서, 시크릿: 플랜트 현장과 데이터 스택을 별개의 방어된 구역으로 유지하기.
- CVE 대응과 자가 관측성(self-observability): 패치 주기, 어느 가벼운 브로커에 관한 교훈적 사례, 그리고 VictoriaMetrics로 감시자를 감시하기.
이 모든 과정에서 cGMP(current Good Manufacturing Practice — 의약품 제조를 구속하는 품질 규제)와 EU GMP 부속서 11(Annex 11)이 기준선을 정하며, 순수 오픈소스가 그 기준선에 못 미치는 지점들을 우리는 정직하게 밝힌다.
둘째 날이 진짜 시험이다
이 장 이전의 모든 것은 행복한 경로(happy path)를 가정했다. 서비스가 시작되고, 데이터가 흐르고, 대시보드가 그려진다. 둘째 날 운영(day-two operations)은 불행한 경로를 가정하는, 화려하지 않은 규율이다. 배치 도중 노드 하나가 죽는다. 일요일에 인증서가 조용히 만료된다. 들어 본 적도 없는 의존성(dependency)에 치명적 권고가 뜬다. 규제 당국은 데모로 당신을 평가하지 않는다. 그들은 복구로 당신을 평가한다.
이것은 대부분의 분야보다 우리 세계에서 더 중요하다. EU GMP 부속서 11은 가용성, 백업, 사업 연속성을 명시적인 의무로 만든다. §7은 데이터의 정기적이고 검증된 백업과 복구된 데이터가 정확한지에 대한 점검을 요구하고, §16은 중요 시스템 장애가 의약품을 만들거나 출하하는 일을 멈추게 하지 않도록 문서화된 사업 연속성 계획을 요구한다 [1]. 당신은 회복력(resilience)을 있으면 좋은 것 정도로 취급할 수 없다. 그것은 점검관이 당신에게 그대로 되읽어 주는 항목이다.
고가용성, 그리고 쪼그라드는 무료 클러스터링 이야기
HA란 이런 뜻이다. 구성 요소 하나가 고장 나도 시스템이 계속 서비스를 제공한다. 데이터베이스에서는 인계받을 준비가 된 복제본(replica)이고, 메시지 브로커에서는 부하와 상태를 나눠 갖는 브로커 클러스터다.
여기 정직한 부분이 있다. 우리가 코어 스택에 싣는 오픈소스 브로커인 Eclipse Mosquitto는 의도적인 단일 브로커(single-broker) 설계다. 작고, 빠르고, 바위처럼 단단하며, 우리 compose 파일에서 안정 버전인 eclipse-mosquitto:2.0.22 라인에 고정(pin)되어 있다. 그것이 아닌 것은 클러스터링이다. 여러 브로커를 가로지르는 문제에 대한 Mosquitto의 답은 브리지(bridge) 기능인데, 독립된 브로커들을 연결하고 선택한 토픽(topic)을 그들 사이에서 전달한다. 여러 사이트를 연합하는 데는 유용하지만, 공유 세션 상태와 자동 장애 조치(failover)를 갖춘 네이티브 클러스터링은 아니다 [2]. 그 하나뿐인 Mosquitto 프로세스가 죽으면, 클라이언트들은 그것이 돌아올 때까지 재접속할 곳이 없다.
명백한 업그레이드는 한때 EMQX였다. 무료 다중 노드 클러스터링을 제공했기 때문이다. 2025년에 그 문이 좁아졌다. EMQX 5.9부터 프로젝트는 Apache 2.0에서 Business Source License(BSL 1.1)로 옮겨 갔고, 이제 운영용 다중 노드 클러스터를 돌리려면 상용 라이선스가 필요하다 [3]. 이것은 2026년에 반복되는 라이선스 함정의 축소판이다. HA를 위해 당신이 가장 원하는 바로 그 기능이 더 이상 무료가 아닌 그 기능이다. 그래서 이 장은 단도직입적이다. 규제받는 단일 사이트 mAb 라인에서는, 잘 모니터링되는 단일 Mosquitto에 빠른 재시작과 문서화된 장애 조치 SOP를 더한 것이 방어 가능하고 정직한 자세다. 규모에 맞는 진정한 브로커 HA는 EMQX에 돈을 내거나, HiveMQ를 돌리거나, 하이브리드 상용 구성 요소를 받아들이는 지점이다. Mosquitto 브리지를 클러스터인 척하지 마라.
데이터베이스 쪽은 더 우호적이다. 우리 postgres 서비스는 timescale/timescaledb:2.17.2-pg17이다. TimescaleDB 확장(extension)을 얹은 PostgreSQL이라서, 히스토리안 하이퍼테이블(hypertable)과 ISA-88/95 배치 모델이 조인 가능한(joinable) 하나의 데이터베이스 안에 살고, 이는 examples/platform/compose/compose.yaml에서 단 한 번 정의된다.
# examples/platform/compose/compose.yaml
services:
# --- core --------------------------------------------------------------
postgres:
# timescale/timescaledb IS PostgreSQL + TimescaleDB, so the historian
# hypertable and the ISA-88/95 batch model live in one joinable database.
image: timescale/timescaledb:2.17.2-pg17
profiles: ["core"]
<<: *restart
environment:
POSTGRES_USER: ${POSTGRES_USER:-bioproc}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-bioproc}
POSTGRES_DB: ${POSTGRES_DB:-bioproc}
ports: ["5432:5432"]
volumes:
- pgdata:/var/lib/postgresql/data
- ../db:/docker-entrypoint-initdb.d:ro # 00-60 schema files run on first init
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-bioproc} -d ${POSTGRES_DB:-bioproc}"]
interval: 5s
timeout: 5s
retries: 20
그 블록에 새겨진 세 가지 운영 습관에 주목하자. 이미지는 태그로 고정되어 있어서, 조용한 마이너 버전 상승이 인덱스를 손상시키는 Debian/glibc 점프를 몰래 들여올 수 없다. 그리고 compose 헤더는 일치하는 매니페스트 다이제스트(manifest digest)를 versions.lock 동반 파일에 기록하도록 의도되어 있다고 적고 있다(공급망 장에서 우리가 만드는 다이제스트 고정 산출물이다. 저장소는 오늘 태그 고정을 싣고 있고, 락 파일은 그 장의 결과물이다). 데이터는 컨테이너의 임시(ephemeral) 계층이 아니라 이름 있는 볼륨(named volume)(pgdata)에 산다. 그래서 컨테이너는 버려도 되지만 데이터는 그렇지 않다. 그리고 실제 healthcheck가 있어서, 오케스트레이터 — 그리고 make up 폴러(poller) — 가 "프로세스가 시작됐다"와 "실제로 서비스할 준비가 됐다"의 차이를 안다.
PostgreSQL은 또한 진짜 스트리밍 복제(streaming replication)를 준다. 프라이머리(primary)가 자신의 미리 쓰기 로그(write-ahead log)를 하나 이상의 핫 스탠바이(hot standby)로 스트리밍하고, 이들은 몇 초 안에 승격(promote)될 수 있다. 그것은 진짜이고, 무료이며, 운영 등급의 데이터베이스 HA로, 우리 스택 전체에서 가장 강력한 HA 이야기다. 비대칭이 바로 교훈이다. 관계형 코어는 오픈에서 잘 클러스터링되지만, 브로커는 그렇지 않다.
백업과 시점 복구
이 책에서 운영상의 의무 하나만 기억한다면, 바로 이것으로 하라. 한 번도 복구해 본 적 없는 백업은 소문일 뿐이다. PITR은 "우리가 데이터를 잃었다"를 "우리는 어제 14시 32분, 잘못된 마이그레이션 직전으로 되감았다"로 바꿔 준다.
PostgreSQL의 PITR은 두 가지를 결합해서 작동한다. 베이스 백업(base backup)(데이터 디렉터리의 전체 물리 복사본)과 연속적으로 보관된 WAL — 그 베이스 이후 모든 변경을 기록하는 미리 쓰기 로그 세그먼트의 흐름이다. 복구하려면 베이스를 복원한 다음 당신이 고른 임의의 순간까지 WAL을 앞으로 재생(replay)한다 [4]. 그 마지막 구절이 마법이다. 당신은 마지막 야간 스냅샷에 묶이지 않는다. 특정 트랜잭션이나 타임스탬프에 착지할 수 있다.
WAL 배관을 손으로 다루는 것은 번거롭기 때문에, 선택받는 오픈소스 도구는 pgBackRest(PostgreSQL License — 관대하고, 무료)다. 이것은 전체(full), 차등(differential), 증분(incremental) 백업을 관리하고, 호스트 외부(off-host)이며 암호화된 저장소를 지원해서 당신의 백업이 보호하려는 대상 바로 옆에 놓이지 않게 하며, 시간 또는 트랜잭션을 표적으로 한 PITR 복구를 수행한다 [5]. 아래는 이 장이 권장하는 형태의 대표적인 ops/pgbackrest.conf다. 예시용 구성이며, 아직 저장소에서 실행 가능한 서비스는 아니다. 운영자가 무엇을 배선하는지 정확히 볼 수 있도록 여기 보인다.
# ops/pgbackrest.conf (illustrative — the operator's day-two artifact)
[global]
repo1-path=/var/lib/pgbackrest
repo1-retention-full=4 # keep 4 weekly full backups
repo1-cipher-type=aes-256-cbc # encrypt the repository at rest
repo1-cipher-pass=<from-secrets-manager>
start-fast=y
process-max=2
[bioproc]
pg1-path=/var/lib/postgresql/data
주간 전체 백업에 일간 차등 백업을 더하고, 그 사이에 연속 WAL 보관을 두는 것이 합리적인 출발 주기다. 감사자가 신경 쓰는 지점은 구성이 아니다. 바로 **복구 런북(restore runbook)**이다. 데이터베이스를 선택한 시점으로 재구축할 수 있고 복구된 데이터가 검증된다는 것을 입증하는, 글로 쓰이고 시험된 절차 말이다. 부속서 11 §7은 단지 백업을 원하는 것이 아니다. 점검된 백업을 원한다. 그리고 §16은 그것을 사용하는 연속성 계획을 원한다 [1]. 분기마다 한 번씩 복구 훈련을 하고 그것을 기록으로 남기는 것이, "우리는 백업이 있다"를 증거로 바꾸는 방법이다.
히스토리안도 똑같은 보살핌이 필요하다. TimescaleDB가 곧 PostgreSQL이기 때문에, 우리 ts 스키마의 하이퍼테이블은 바로 그 동일한 물리 백업과 WAL 스트림으로 보호된다 — 하나의 PITR 전략이 배치 모델과 고속 센서 데이터를 모두 지킨다. 우리는 의도적으로 Apache-2 OSS 기능 집합만 사용하므로, 복구를 복잡하게 만들 독점 압축이나 데이터 계층화(data-tiering) 레이어가 없다.
OT/IT 선 긋기: 분리, TLS, 그리고 시크릿
mAb 라인은 함께 꿰매진 두 세계다. 운영 기술(operational technology, OT) 쪽에는 PLC, DCS, 바이오리액터 스키드(skid)의 OPC UA 서버가 있다 — 수명이 길고, 취약하며, 캠페인 도중에는 좀처럼 패치되지 않는다. 정보 기술(information technology, IT) 쪽에는 우리의 브로커, 데이터베이스, 대시보드가 있다. 플랜트 현장 보안의 가장 중요한 규칙은 이 두 세계가 평평한(flat) 네트워크를 공유하지 않는다는 것이다.
여기서의 프레임워크는 IEC 62443, 구체적으로는 Part 3-3이다. 이것은 *구역과 도관(zones and conduits)*을 형식화한다. 플랜트를 보안 구역(security zone)으로 나누고, 그 사이의 도관(conduit, 유일하게 승인된 경로)을 정의하며, 각각에 목표 보안 수준(Security Level)을 부여한다 [6]. 우리에게 이것은 OPC UA 서버와 엣지 게이트웨이(edge gateway)가 OT 구역에 있고, 히스토리안과 브로커가 IT/DMZ 구역에 있으며, 둘 사이의 유일한 도관이 컬렉터(collector)로서 방화벽이 쳐지고 인증되며 암호화된 링크를 통한다는 뜻이다. 비즈니스 네트워크상의 어떤 것도 PLC에 직접 닿지 않는다.
저 읽기 위주(read-mostly) 화살표는 장식이 아니다. 그것은 1장에서 우리가 기반으로 삼은 NAMUR 개방형 아키텍처(NAMUR Open Architecture)의 본능이다. 모니터링과 분석은 두 번째 채널을 두드릴 뿐, 검증된 제어로 되돌아가 쓰지 않는다.
이제 이 책 전체를 관통하는 불편한 고백이다. 우리가 실은 개발용 브로커 구성은 의도적으로 활짝 열려 있고, examples/platform/mosquitto/mosquitto.conf에서 그렇다고 말해 준다.
# examples/platform/mosquitto/mosquitto.conf
# Mosquitto broker config for the local dev stack (Chapter 5).
# Dev-only: anonymous access on the plain 1883 listener. Chapter 25 (operating &
# securing) replaces this with TLS + per-client ACLs; never ship anonymous in
# a real plant.
listener 1883
allow_anonymous true
# enable the $SYS topic tree so the healthcheck can confirm the broker is alive
sys_interval 10
persistence true
persistence_location /mosquitto/data/
log_dest stdout
평문 1883 리스너에서의 allow_anonymous true는 노트북에는 완벽하고 플랜트에는 재앙이다. 이 장이 바로 그 약속이 만기가 되는 지점이다. 강화된 버전은 8883의 TLS로 옮기고, 클라이언트 인증서를 요구하며, 클라이언트별 ACL을 강제해서 탈취된 센서 계정이 모든 것을 구독하지 못하게 한다.
# ops/mosquitto.tls.conf (illustrative hardening for production)
listener 8883
allow_anonymous false
cafile /mosquitto/certs/ca.crt
certfile /mosquitto/certs/server.crt
keyfile /mosquitto/certs/server.key
require_certificate true
acl_file /mosquitto/config/acl
그 인증서들은 그 자체로 운영의 부담이다. 그것들은 만료되고, 만료된 브로커나 OPC UA 인증서는 늘 휴일에 떨어지는 듯한 자초한 장애다. 모든 인증서의 만료일을 추적하는 인벤토리, 가능한 곳에서의 자동 갱신(rotation), 그리고 그것들을 발급할 OpenSSL이나 작은 내부 CA가 필요하다. 그리고 개인 키, repo1-cipher-pass, 데이터베이스 비밀번호 — 그 어느 것도 compose 파일이나 Git 저장소에 속하지 않는다. 그것들은 런타임에 주입되는, 시크릿 매니저(secrets manager)에 속한다. 위에서 본 ${POSTGRES_PASSWORD:-bioproc} 기본값은 개발 편의다. 운영에서 그 변수는 볼트(vault)에서 가져오는 것이지, 결코 타이핑되는 것이 아니다.
OSS 바이오공정 스택을 위한 둘째 날 운영의 네 기둥 — 가용성, 복구 가능성, 방어된 구역, 그리고 감시되고 패치되는 스택 — 각각이 그것을 선택 불가능으로 만드는 규제나 표준에 묶여 있다. Original diagram by the authors, created with AI assistance.
CVE 대응: NanoMQ의 교훈적 사례
가벼운 오픈소스 구성 요소를 고른다고 해서 그것을 유지보수할 의무가 면제되지는 않는다. 오히려 판돈이 올라간다. 이제 그 유지보수가 당신의 일이기 때문이다. 당신이 고르지 않은 브로커를 생각해 보자. NanoMQ는 매력적으로 작은 MQTT 브로커이고, 바로 작기 때문에 패치를 받아야만 했다. 2026년에 권고가 떨어졌다. MQTT v5 가변 바이트 정수(Variable Byte Integer) 파서인 get_var_integer()에서의 범위 밖 읽기(out-of-bounds read)로, 0.24.6 버전 이하에 조작된 패킷으로 원격에서 유발될 수 있었다 [7]. 국가 취약점 데이터베이스(National Vulnerability Database)는 이를 CVE-2026-21888로 목록화했고, CWE-125(범위 밖 읽기)로 분류했으며, CVSS 3.1 기준점수 7.5로 High 등급을 매겼다 [8].
그 점수는 감(感)이 아니다. 그것은 정의된 모델에서 나온다. 공통 취약점 점수 체계(Common Vulnerability Scoring System)는 취약점의 특성을 벡터 문자열과 0–10 숫자로 바꾼다. 이 특정 CVE는 CVSS 3.1로 점수가 매겨졌지만, 같은 원칙이 나중의 CVSS v4.0 명세에서 명시적으로 드러난다 — 기준점수(base score)는 기술적 심각도를 측정하는 것이지 당신의 리스크를 측정하는 것이 아니다 [9]. 인터넷에 노출된 브로커에서의 7.5는 비상 훈련이지만, 인바운드 노출이 없는 IEC 62443 OT 구역 안에 잠긴 브로커에서의 똑같은 7.5는 다음 유지보수 창에 일정으로 잡아 두는 무언가다. 심각도는 입력이고, 당신의 분리와 노출이 그것을 분류(triage) 결정으로 바꾼다. 이것이 앞 절이 여기서 보답하는 이유다 — 좋은 구역화는 말 그대로 주어진 CVE의 실제 리스크를 낮춘다.
그래서 둘째 날 루프는 이렇다. 인벤토리 → 감시 → 분류 → 패치 → 재검증. 인벤토리는 소프트웨어 자재 명세서(software bill of materials, SBOM)다. 운영자는 Syft 같은 도구로 그것을 생성하고, Grype와 Trivy로 스캔하며, 모든 구성 요소를 다이제스트로 고정해 공급자 등록부에 둔다 — SBOM/스캔 도구 체인과 그 등록부는 공급망 장의 결과물이지 아직 이 저장소의 Makefile에 배선되어 있지 않으므로, 여기의 워크플로는 오늘 실행할 수 있는 make 타깃이라기보다 권장되는 형태로 받아들이자. 그다음 CVE 감시 런북이 고정된 모든 이미지에 대한 권고를 구독한다. 새로운 권고는 그 구성 요소가 실제로 어디 자리 잡고 있는지에 비추어 CVSS에 기반한 분류를 받는다. 패치란 고정된 태그 와 다이제스트를 올리고, 다시 빌드하고, 테스트 스위트를 다시 돌리는 것을 뜻한다 — 검증된 환경에서 패치는 변경(change)이고, 변경은 그저 적용되는 것이 아니라 재검증되어야 하기 때문이다. 그리고 스캐너 자체도 위협 표면(threat surface) 위가 아니라 그 안에 속한다. 스캐너 바이너리와 그 피드(feed)도 공급자로 취급하고, 검토된 허용 목록(allowlist)에 대해 실행하며, 스캐너의 출처(provenance)를 맹목적 신뢰가 아니라 평가의 일부로 삼아라 — 널리 쓰이는 개발자 도구의 공급망 침해는 가설이 아니라 업계에서 반복되는 패턴이다.
VictoriaMetrics로 감시자를 감시하기
볼 수 없는 것은 운영할 수 없다. 플랫폼은 자기 자신을 모니터링해야 한다. 브로커 연결 수, 데이터베이스 복제 지연(replication lag), 디스크 여유 공간, 백업 성공, 인증서 만료, 서비스 상태. 이를 위해 스택은 VictoriaMetrics를 싣는다. victoriametrics/victoria-metrics:v1.108.1에 고정되어 있고, 같은 compose 파일에서 ops/analytics 프로파일 뒤에 게이팅되어 있다.
# examples/platform/compose/compose.yaml
# --- analytics ---------------------------------------------------------
victoriametrics:
image: victoriametrics/victoria-metrics:v1.108.1
profiles: ["analytics", "ops"]
<<: *restart
ports: ["8428:8428"]
VictoriaMetrics는 우리가 InfluxDB 대신 싣는 Apache-2 메트릭 저장소다 — InfluxDB v3 라이선스 전환을 의도적으로 피한 것으로, BSL 시대의 EMQX보다 Mosquitto에 머무르게 한 것과 같은 본능이다. 운영상으로 그것은 후하다. HA 모드로 실행되는 단일 노드가 초당 백만 샘플 미만의 수집(ingestion)을 여유롭게 처리하며, 더 큰 규모에 이르러서야 복제 기반 HA를 더해 주는 클러스터 버전에 손을 뻗게 된다 [10]. mAb 라인 하나에는 단일 노드면 충분하고, 그 단순함 자체가 하나의 기능이다 — 백업하고, 패치하고, 검증할 움직이는 부품이 더 적다. 그것이 긁어 오는 메트릭은 Grafana의 알림을 먹여서, 디스크가 가득 찬 뒤가 아니라 그 전에 당신을 호출(page)한다.
왜 중요한가
플랫폼은 한 번 동작한다고 끝난 것이 아니다. 그것이 장애와 공격과 시간을 통과해 계속 동작하고, 그렇게 했음을 입증할 수 있을 때 끝난 것이다. 부속서 11은 가용성, 백업, 연속성을 감사 가능한 의무로 바꾼다 [1]. IEC 62443은 "OT와 IT를 떼어 놓아라"를 방어 가능한 아키텍처로 바꾼다 [6]. 둘째 날 운영을 건너뛰는 것은 지름길이 아니다. 그것은 미뤄 둔 장애이자 미뤄 둔 감사 지적이고, 둘 다 이자가 붙는다.
실제 현장에서는
실제 바이오 제조사들은 이 하이브리드를 정직하게 운영한다. PostgreSQL/PITR 이야기는 오픈에서 진정으로 운영 등급이다 — pgBackRest는 세계에서 가장 규제가 큰 데이터베이스 일부를 백업한다 [4][5]. 브로커 HA 이야기는 돈이 오가는 지점이다. 진정한 클러스터 MQTT가 필요한 곳은 2025년 BSL 전환 이후 EMQX를 라이선스하거나 [3], HiveMQ를 사거나 — 단일 GMP 사이트에서 가장 흔하게는 — 빠른 장애 조치 SOP와 함께 면밀히 감시되는 단일 브로커를 돌리며 Mosquitto의 정직한 단일 노드 한계를 받아들인다 [2]. NIIMBL의 SABRE 시설 — 2024년 4월에 착공해 아직 건설 중인 NIIMBL/델라웨어 대학교 파일럿 규모 cGMP 플랜트 — 은 이 둘째 날 패턴들이 노트북이 아니라 실재하는 규제 장비에서 시험받는, 바로 그런 종류의 차세대 사이트다. 점검관과의 접촉에서 살아남는 패턴은 결코 "우리는 오픈소스를 썼다"가 아니다. 그것은 "우리는 오픈소스를 검증된 라이프사이클 안에서 썼고, 시험된 복구, 분리된 네트워크, 갱신된 인증서, CVE 런북, 그리고 자기 자신을 감시하는 스택과 함께 썼다"이다. 순수 OSS는 당신을 대부분의 길까지 데려다준다. 마지막 한 마일 — 클러스터 브로커 HA, 벤더 책임성, 턴키(turnkey) Part 11 래퍼 — 은 하이브리드이고, 그렇게 말하는 것이 이 책의 핵심 그 자체다.
핵심 용어
- 고가용성(high availability, HA): 구성 요소 하나의 고장이 서비스를 멈추게 하지 않도록 설계하는 것. 데이터베이스에는 핫 스탠바이, 브로커에는 클러스터.
- PITR(point-in-time recovery, 시점 복구): 보관된 WAL을 베이스 백업 위에 재생함으로써 데이터베이스를 선택한 임의의 순간으로 복원하는 것.
- WAL(write-ahead log, 미리 쓰기 로그): 모든 변경에 대한 PostgreSQL의 순서 있는 기록. 복제와 PITR의 원재료.
- pgBackRest: 암호화·호스트 외부·표적 복구에 쓰이는 관대한 오픈소스 PostgreSQL 백업/복구 도구.
- BSL(Business Source License): 특정 기능의 운영 사용을 제한하는(예: EMQX 5.9부터의 클러스터링) 소스 공개(source-available) 라이선스 — 읽기는 무료, 규모에 맞춰 돌리는 것은 무료가 아니다.
- IEC 62443: OT 보안 표준 계열. Part 3-3은 구역, 도관, 보안 수준을 정의한다.
- 구역과 도관(zones and conduits): 플랜트를 신뢰 구역으로 분할하고 그 사이에 통제되고 모니터링되는 경로를 두는 것.
- CVE / CVSS: 목록화된 취약점 식별자(예: CVE-2026-21888)와 그 기술적 심각도를 점수화하는 0–10 모델.
- SBOM(software bill of materials, 소프트웨어 자재 명세서): 스택 안 모든 구성 요소와 버전의 기계 판독 가능한 인벤토리. CVE 감시의 토대.
- 자가 관측성(self-observability): 플랫폼이 자기 자신의 상태와 메트릭을 모니터링하는 것. 여기서는 VictoriaMetrics를 통해.
다음 이야기
이제 플랫폼은 서 있고, 방어되고, 복구 가능하며, 감시된다. 잘 거버넌스된 데이터의 신뢰할 만한 흐름이 그것을 통과해 흐르는 가운데, 우리는 마침내 가장 보람 있는 질문을 던질 수 있다. 우리는 그 데이터에서 무엇을 배울 수 있는가? 다음 장 공정 분석: SPC, MVDA와 소프트 센서는 히스토리안과 실험실 테이블을 통계적 공정 관리(statistical process control) 차트, 다변량 배치 모델(multivariate batch model), 그리고 라만(Raman)-역가 소프트 센서(soft sensor)로 바꾼다 — 플랫폼 전체가 가능케 하려고 지어진 그 분석의 보상이다.