프로젝트 배경
v1.0에서 구축한 단일 서버 기반 스마트 팩토리 모니터링 시스템을 분산 아키텍처로 확장했다. 데비안 미니PC(중앙 서버)와 라즈베리파이(Edge Device)를 분리하고, MQTT 외에 산업 표준 프로토콜인 OPC-UA를 추가 지원하며, AWS 클라우드 연동까지 구현했다.
기술 스택
- IaC: Terraform v1.5+
- 메시징: MQTT (Eclipse Mosquitto)
- 산업 프로토콜: Modbus TCP, OPC-UA
- 데이터 수집: Telegraf (멀티 프로토콜 지원)
- 시계열 DB: InfluxDB 2.0
- 시각화: Grafana
- 클라우드: AWS Kinesis, S3, CloudWatch
- Edge Computing: Raspberry Pi K3s
시스템 아키텍처

핵심 구현 사항
1. 멀티 프로토콜 데이터 수집 Telegraf를 MQTT와 OPC-UA 동시 수집용으로 확장:
# MQTT 입력
[[inputs.mqtt_consumer]]
servers = ["ssl://mosquitto-terra:8883"]
topics = ["factory/sensor/+"]
# OPC-UA 입력
[[inputs.opcua]]
endpoint = "opc.tcp://192.168.45.205:4840/pearl-factory/server"
nodes = [
{name="temperature", namespace="2", identifier_type="i", identifier="2"},
{name="humidity", namespace="2", identifier_type="i", identifier="3"}
]
# 태그 기반 라우팅
[[outputs.influxdb_v2]]
bucket = "sensors"
[outputs.influxdb_v2.tagpass]
source = ["mqtt", "opcua"]
2. OPC-UA Gateway 구현 Modbus 데이터를 OPC-UA 표준으로 변환:
class OPCUAModbusGateway:
async def init_opcua_server(self):
self.opcua_server = Server()
await self.opcua_server.init()
self.opcua_server.set_endpoint(f"opc.tcp://0.0.0.0:4840/pearl-factory/server")
# OPC-UA 노드 생성
plc_node = await objects.add_object(idx, "ModbusPLC")
self.nodes['temperature'] = await plc_node.add_variable(
idx, "Temperature", 0.0, ua.VariantType.Double)
async def poll_modbus_data(self):
# Modbus에서 읽기
result = self.modbus_client.read_holding_registers(0, count=9)
# OPC-UA 노드 업데이트
await self.nodes['temperature'].write_value(temperature)
3. AWS 데이터 파이프라인 실시간 데이터를 클라우드로 스트리밍:
# Kinesis Stream
resource "aws_kinesis_stream" "pearl_factory_stream" {
name = "pearl-factory-stream"
retention_period = 168
stream_mode_details {
stream_mode = "ON_DEMAND"
}
}
# Firehose → S3
resource "aws_kinesis_firehose_delivery_stream" "kinesis_to_s3" {
name = "kinesis-to-s3"
destination = "extended_s3"
extended_s3_configuration {
role_arn = aws_iam_role.firehose_role.arn
bucket_arn = aws_s3_bucket.data_lake.arn
buffering_size = 5
buffering_interval = 300
compression_format = "GZIP"
}
}
4. Edge 컨테이너 오케스트레이션 라즈베리파이의 컨테이너를 Docker Compose로 관리:
services:
modbus-device:
image: oitc/modbus-server:latest
ports:
- "502:5020"
modbus-writer:
build: ./modbus-writer
environment:
- MODBUS_HOST=modbus-device
- MODBUS_PORT=5020
opcua-gateway:
build: ./opcua-gateway
ports:
- "4840:4840"
environment:
- MODBUS_HOST=modbus-device
데이터 흐름
- 센서 시뮬레이션: Modbus Writer가 5초마다 온도, 습도, 압력 등 생성
- 프로토콜 변환: OPC-UA Gateway가 Modbus → OPC-UA 변환
- 데이터 수집: Telegraf가 MQTT와 OPC-UA 동시 폴링
- 저장 및 시각화: InfluxDB 저장 → Grafana 대시보드
- 클라우드 백업: Kinesis → Firehose → S3 (5분 단위 배치)
보안 강화
# AWS IAM 역할 분리
resource "aws_iam_role" "kinesis_role" {
assume_role_policy = data.aws_iam_policy_document.kinesis_assume.json
}
# 네트워크 격리
networks:
pearl-factory-vpc:
driver: bridge
name: pearl-factory-vpc # prefix 없이 명시적 이름
실행 방법
# 1. 데비안 (Terraform)
terraform init
terraform apply -var-file="production.tfvars"
# 2. 라즈베리파이 (Docker Compose)
docker-compose up -d
# 3. 데이터 확인
docker exec influxdb-terra influx query '
from(bucket: "sensors")
|> range(start: -5m)
|> filter(fn: (r) => r.source == "opcua")
'
결론
v2.0에서는 실제 산업 현장과 유사한 환경을 구축했다. 특히 OPC-UA 통합으로 레거시 PLC 장비들을 Terraform을 이용하여 현대적인 클라우드 인프라와 연결할 수 있게 되었다. Terraform을 처음 사용해봤는데, 첫 이미지에 비해서는 학습레벨이 높진 않았다. 다음으로는, 현재 인프라를 좀더 “클라우드 네이티브”하게 구축해보고자 한다.
답글 남기기