1. 문제 배경
- NaviSafe 프로젝트에서는 도로 링크와 노드 데이터를 기반으로 위치 정보 처리와 경로 탐색 기능이 필요했다.
- 기존 MySQL 중심 구조에서는 데이터 저장은 가능했지만, 좌표 기반 연산이나 최단 경로 계산과 같은 기능을 처리하기에는 한계가 있었다.
- 따라서 PostgreSQL 기반 환경을 별도로 구성하고, PostGIS와 pgRouting 확장을 통해 공간 연산과 경로 탐색이 가능한 구조로 전환했다.
2. 목표
- Kubernetes 환경에서 PostgreSQL 실행
- PostGIS, pgRouting 확장 구성
- 도로 노드 / 링크 / 회전 데이터 적재
- 경로 탐색이 가능한 데이터 구조 준비
3. PostGIS와 pgRouting이란 무엇인가
3-1) PostGIS
PostGIS는 PostgreSQL에서 좌표 기반 데이터를 처리하기 위한 확장 모듈이다.
- Point, Line, Polygon 저장
- 거리 계산
- 영역 포함 여부 판단
- 공간 인덱스 기반 검색
즉, 위치 기반 데이터 처리가 가능해진다.
3-2) pgRouting
pgRouting은 PostGIS 데이터를 기반으로 경로 탐색 알고리즘을 제공하는 확장 모듈이다.
- 최단 경로 (A*)
- 네트워크 기반 경로 계산
- 다중 경로 탐색
도로 네트워크 데이터를 활용한 실제 경로 계산이 가능하다.
3-3) 왜 필요한가
이번 프로젝트에서는
- 위치 계산 → PostGIS
- 경로 탐색 → pgRouting
이 필요했기 때문에 PostgreSQL을 확장해 공간 데이터 처리 + 경로 계산이 가능한 구조로 구성했다.
4. PostgreSQL + PostGIS + pgRouting 환경 구성
FROM postgis/postgis:15-3.4
RUN apt-get update && \
apt-get install -y \
postgresql-15-pgrouting \
postgis \
postgresql-15-postgis-3
이 이미지를 Kubernetes에 배포해 공간 데이터 처리 환경을 구성했다.
5. Kubernetes 배포 구조
PostgreSQL은 상태 저장 서비스이기 때문에 StatefulSet으로 구성했다.
PostgreSQL Kubernetes 구성 요소 실행 순서
PostgreSQL은 상태 저장 서비스이기 때문에 리소스를 순서대로 생성해야 정상적으로 동작한다.
환경 준비 (Secret)
→ 저장소 준비 (PVC)
→ 네트워크 준비 (Service)
→ DB 실행 (StatefulSet)
5-1) Secret 생성 (환경변수 준비)
DB 계정 정보는 Secret으로 먼저 만든다.
kubectl apply -f postgres-secret.yaml
확인
kubectl get secret

5-2) PVC 생성 (데이터 저장 공간 확보)
데이터를 저장할 PersistentVolumeClaim을 생성한다.
kubectl apply -f postgres-pvc.yaml
확인
kubectl get pvc

5-3) Service 생성 (접근 경로 생성)
PostgreSQL에 접근할 수 있는 내부 주소를 생성한다.
kubectl apply -f postgres-service.yaml
확인
kubectl get svc

5-4) StatefulSet 생성 (DB 실행)
마지막으로 PostgreSQL Pod를 생성한다.
kubectl apply -f postgres-statefulset.yaml
확인
kubectl get pods

Pod가 재시작되더라도 데이터가 유지되도록 구성했다.
PostgreSQL StatefulSet은 Secret, PVC, Service가 먼저 준비된 상태에서 실행해야 정상적으로 동작한다.
6. 공간 데이터 파일 준비
ITS 국가교통정보센터
ITS 국가교통정보센터
its.go.kr
해당 사이트에서 최신 자료를 다운로드 한 후 아래와 같이 Navisafe 폴더에 위치 시킨다.

반드시 dbf, shp, shx 파일 모두 위치 시킨다. 하나라도 누락되면 정상적으로 적재되지 않는다.
postgresql 컨테이너로 해당 폴더를 복사
kubectl cp ../shp_data/. navisafe-postgres-0:/tmp
7. shapefile → PostgreSQL 적재
실행 위치: PostgreSQL Pod 내부 bash
kubectl exec -it navisafe-postgres-0 -- bash
# 노드
shp2pgsql -I -s 5186:4326 -W CP949 /tmp/MOCT_NODE.shp node | psql -U navisafe -d navigation
# 링크
shp2pgsql -I -s 5186:4326 -W CP949 /tmp/MOCT_LINK.shp link | psql -U navisafe -d navigation
# 회전정보
shp2pgsql -I -s 5186:4326 /tmp/TURNINFO.dbf turninfo | psql -U navisafe -d navigation
자동 생성
- 테이블
- geometry 컬럼
- spatial index
8. 데이터 적재 확인
PostgreSQL 접속
kubectl exec -it navisafe-postgres-0 -- psql -U navisafe -d navigation
8-1)전체 테이블 목록 확인
\dt


link, node, turninfo 테이블이 정상적으로 적재된 것을 확인할 수 있다.
8-2) 해당 테이블 row수 확인
SELECT COUNT(*) FROM node;
SELECT COUNT(*) FROM link;
SELECT COUNT(*) FROM turninfo;

link, node, turninfo 테이블이 정상적으로 적재된 것을 확인할 수 있다.
9. SQL 파일 복사 및 실행
9-1) SQL 파일 복사

데이터 적재 이후 구조를 구성하기 위한 SQL 스크립트는 SQL 폴더에 분리했다.
SQL/
├── create_edge_base.sql
├── create_indexes.sql
├── create_user_grants.sql
├── extensions.sql
postgresql 컨테이너로 해당 폴더를 복사
kubectl cp ../SQL/. navisafe-postgres-0:/sql
9-2) SQL 실행
실행 위치: PostgreSQL Pod 내부 bash
kubectl exec -it navisafe-postgres-0 -- bash
PostgreSQL Pod 내부 bash에 접속하여 아래 순서대로 sql 스크립트를 실행한다.
psql -U navisafe -d navigation -f /sql/extensions.sql
psql -U navisafe -d navigation -f /sql/create_edge_base.sql
psql -U navisafe -d navigation -f /sql/create_indexes.sql
psql -U navisafe -d navigation -f /sql/create_user_grants.sql
실행 순서
shapefile 적재
→ 확장 생성
→ 구조 생성
→ 인덱스 생성
→ 권한 설정
10. 확장 확인
PostgreSQL 접속
kubectl exec -it navisafe-postgres-0 -- psql -U navisafe -d navigation
확장 설치 확인
SELECT PostGIS_Version();
SELECT pgr_version();

11. PostgreSQL 실행 안정화 설정
데이터 적재 중 PostgreSQL이 종료되는 문제가 발생했다.
로그:
- parallel worker exited
- LLVM 관련 오류
PostgreSQL 접속
kubectl exec -it navisafe-postgres-0 -- psql -U navisafe -d navigation
설정 적용
ALTER SYSTEM SET jit = off;
ALTER SYSTEM SET max_parallel_workers_per_gather = 0;
SELECT pg_reload_conf();
적용 결과
- DB 종료 문제 해결
- 대용량 데이터 처리 안정화
12. 핵심 포인트
이번 작업은 단순 DB 구축이 아니라 공간 데이터 처리 환경을 구성하는 과정이었다.
- PostGIS → 공간 연산
- pgRouting → 경로 탐색
- shapefile → DB 직접 적재
또한 실행 위치와 순서가 중요했다.
13. 서비스 접속을 위한 포트 포워딩
Kubernetes 환경에서 실행 중인 서비스는 기본적으로 클러스터 내부에서만 접근할 수 있기 때문에, 로컬 환경에서 확인하기 위해 포트 포워딩을 사용했다.
13-1) Backend 포트 포워딩
kubectl port-forward svc/backend 30080:8080
- 로컬 localhost:30080 → Kubernetes backend 서비스로 연결
13-2) Frontend 포트 포워딩
kubectl port-forward svc/frontend 5173:5173
- 로컬 localhost:5173 → frontend 서비스로 연결
최종 결과 및 검증

- Kubernetes 환경에서 PostgreSQL, PostGIS, pgRouting을 구성하고 공간 데이터 적재 및 경로 탐색 구조까지 준비한 이후, 프론트엔드와 백엔드를 포트 포워딩을 통해 연결해 실제 동작을 확인했다.
- 프론트엔드(localhost:5173)에서 출발지와 도착지를 입력하면 백엔드 API를 통해 경로 탐색 요청이 전달되고,
pgRouting을 기반으로 계산된 결과가 반환되는 구조로 동작한다. - 네트워크 요청을 확인해보면 백엔드(localhost:8080)로 요청이 전달되고 정상적으로 응답이 반환되는 것을 확인할 수 있다.
- 또한 지도 화면에서 실제 경로가 표시되고, 총 이동 거리(예: 26.51km)가 함께 계산되어 출력되는 것을 통해 다음 흐름이 정상적으로 연결된 것을 확인했다.
Frontend → Backend API → PostgreSQL (pgRouting) → 결과 반환 → 지도 렌더링
'Navisafe > Infrastructure' 카테고리의 다른 글
| AWS S3를 활용한 데이터 저장 구조 설계 (0) | 2026.05.02 |
|---|---|
| AWS S3 및 IAM 설정 - 클라우드 데이터 접근 환경 구성 (0) | 2026.04.29 |
| Kubernetes 환경 구성 (4) - 데이터 파이프라인 동작 검증 (0) | 2026.04.20 |
| Kubernetes 환경 구성 (3) - NaviSafe 서비스 배포와 Kafka Topic 초기화 (0) | 2026.04.20 |
| Kubernetes 환경 구성 (2) - NaviSafe 배포를 위한 사전 준비 (이미지, Helm, 공통 리소스) (1) | 2026.04.20 |