1. 배경
- 기획 요구사항 스펙 상 태그로 검색하는 기능이 많은 서비스를 개발해야 하는 상태
- 태그는 여러 개를 가질 수 있지만, 이는 1NF에 부합하지 않음
- 태그를 별도의 테이블로 만들고 매핑하는 것은 비효율적이라고 판단
- 검색 최적화를 위해 Elastic Search를 도입하는 방법도 있지만 이는 현재 시점에서 오버엔지니어링이라 판단
- 하나의 컬럼에 Array 형태를 저장할 수 있는 PostgreSQL을 도입하기로 결정
- 추후 확장성을 미리 고려해 초기 단계에서 DB 이중화를 1:1로 진행
- Leader-Election, Failover 등의 자동화를 위해 Patroni 도입을 고려
2. 문제 상황
- 컨테이너 설정 적용 문제 - Etcd(bitnami/etcd:latest)
- Patroni 컨테이너에서 patronictl show-config 에서 값을 반환하지 않음
- Patroni Cluster가 uninitialized로 표기됨
초기에 컨테이너에 대한 설정 문제가 많이 생겼습니다
환경 변수를 입력했음에도 설정이 제대로 적용되지 않고, 그에 따라 Etcd를 통한 Patroni 연동도 문제가 생겼어요 🥲
일부 환경 변수는 컨테이너에 제대로 반영된 반면, 또 일부의 환경 변수는 제대로 반영되지 않았고
이 때문에 해당 서비스에서 받아들이는 환경 변수가 달라진 것이라 생각해 조사를 진행했습니다
하지만 이 부분에는 문제가 없었어요
그렇다면 Docker-Compose에 command을 작성해서 해결하는 방법은 어떨까 싶어 이번에는 command를 입력했습니다
이 부분에서 또 문제가 생겼습니다
로그를 확인해 보니
conflicting environment variable is shadowed by corresponding command-line flag
이라는 내용이 나왔고, 이는 command에 추가한 환경 변수가 충돌된다
즉 여러 번 선언되었다는 의미였습니다
필자 분명 한 번 밖에 선언한 적이 없는데 이미 선언되었다는 내용이 나온 것이었죠
이에 대해 알아보니 entrypoint에 이미 선언된 내용에 추가하여 command가 실행된다는 것을 알았습니다
별도로 entrypoint를 설정한 적이 없지만, 사용 중인 이미지가 bitnami에서 제공하는 일종의 커스텀 이미지었기에
해당 이미지 제공자가 설정한 entrypoint가 있을 수 있겠구나라는 생각이 들었어요 😯
그래서 entrypoint를 임의로 지정하고 실행을 한 결과 !
command에 따라 원하는 값이 잘 지정된 것을 확인할 수 있었습니다 😊 - Replication 권한 문제
- Patroni Cluster에서 Slave 노드가 Stopped로 표시됨
이제 노드들이 클러스터에 통합되고, 설정값도 잘 넘어가지만 Slave 노드가 제대로 실행되지 않는 것을 발견했어요
Slave 노드에서 Master 노드에 제대로 접근이 되지 않는건가 싶어 확인을 해봤습니다
이렇게 실행했을 때 권한이 있다면 정상적으로 결과값이 나와야 하지만# Patroni-Slave 컨테이너 내부 psql -h <Master Node IP> -p <Master Node Port> -U postgres -c "SELECT 1;"
Password for user postgres:
라는 문구가 나타났습니다
여기에 지정한 비밀번호를 입력했더니 정상적으로 작동됐구요
이를 보고 권한 확인을 수동으로 해줘야 하기 때문에 정상적인 Replication이 일어나지 않았겠구나 하고 생각했습니다
# patroni-master.yml bootstrap: dcs: postgresql: pg_hba: - local all all trust - host replication replicator 127.0.0.1/32 trust - host replication replicator <Patroni Network 범위> trust - host all all 0.0.0.0/0 md5
Replication에 대해 작업을 수행할 수 있도록 해당 Network 범위에 trust를 달아 권한을 허용해줬습니다
(Network 범위는 CIDR 표기법으로 지정해줘야 합니다)
이후 재실행을 하니 Slave 노드가 Streaming으로 잘 나타나게 되었답니다 🥰 - Docker Volume 권한 문제
- PostgreSQL 데이터 볼륨을 Replication하는 경우 권한 문제가 발생
- Permissions should be u=rwx (0700) or u=rwx,g=rx (0750)
- Patroni Cluster에서 Slave 노드가 Start Failed로 표시됨
이 부분은 초기에 볼륨 설정을 하지 않았을 때는 발생하지 않았던 문제입니다
PostgreSQL의 컨테이너가 다운되었을 때 데이터를 보존하기 위해 볼륨을 설정하였을 때 발생하였습니다
Master Node에서 데이터를 복제하는 과정에서 해당 디렉토리에 대한 권한이 없다는 이유였습니다
볼륨을 설정하지 않았을 때는 문제가 없었으므로 Docker가 볼륨을 생성할 때 생성되는 권한에 문제가 있다고 생각했어요
때문에 처음엔 볼륨 생성 시 권한을 설정하도록 구성했습니다
하지만 해당 디렉토리는 Docker가 Up되는 시점이 아닌, Patroni가 실행된 이후에 생기는 디렉토리였습니다
때문에 초기에 권한을 설정할 방법이 없었어요
이를 해결하기 위해 entrypoint를 적용했습니다
시작 시 해당 디렉토리의 권한을 지정하도록 entrypoint에 지정하였습니다# postgre_compose.yml 중 entrypoint: ["/bin/sh", "-c", "chown -R 999:999 /var/lib/postgresql/data && chmod 0700 /var/lib/postgresql/data && exec python3 /patroni.py /etc/patroni.yml"]
이후 재실행을 하였을 때 드디어 . . !
정상적으로 실행된 화면을 볼 수 있었답니다 😭😭
3. 마치며
이렇게 막상 글로 작성하니 짧아보이지만
사실 엄청난 삽질을 했더랬죠.. 💀..
Patroni가 PostgreSQL로 Cluster 구성 및 Leader-Election과 Auto Failover에 대해 많이 사용되고 레퍼런스도 많다고 하지만
한국어로 된 레퍼런스가 많이 보이지는 않더라구요 🥲
도움이 되셨으면 좋겠습니다 😊
혹여나 내용 중 틀린 부분이 있다면 가감없이 언급 부탁드립니다 !
그럼 다음엔 더 유익한 트러블슈팅 내용으로 찾아오도록 할게요 😀
'트러블슈팅' 카테고리의 다른 글
Spring: 다중 DB 연결 이슈와 아키텍처 설계 (0) | 2025.02.18 |
---|