EC2 위의 PostgreSQL 컨테이너 데이터를 RDS로 이관하기
이 문제는 포트 바인딩으로 해결할 수 있습니다. 포트 바인딩이란 컨테이너 내부 프로그램을 외부로 노출시킬 때 사용되는데요, 호스트의 특정 포트를 컨테이너의 특정 포트로 연결시켜주면 작동합니다.
docker run --name postgres -d -p 5432:5432 postgres:9.6-alpine
여기서 -p 뒤에 오는 포트 두 가지가 바인딩될 호스트포트:컨테이너포트입니다. 이제 호스트 서버의 5432 포트로 들어가면 PostgreSQL이 깔려있는 컨테이너로 접속됩니다.
한 가지 더 다른 옵션을 줍시다. 제가 작업한 redash의 경우 호스트 서버 위에 데이터 보관용 폴더 /opt/redash/postgres-data가 존재했습니다. 이 폴더가 PostgreSQL 컨테이너 내부의 /var/lib/postgresql/data 폴더에 마운트 된 형태로 작동했습니다. 따라서 docker로 실행할 때 -v (volume의 약자)라는 옵션을 사용해 이런 환경을 적용시켜줍니다. -v 뒤에 마운트할 폴더:마운트 대상 폴더를 적어주면 됩니다.
docker run --rm --name postgres -d -p 5432:5432 -v /opt/redash/postgres-data:/var/lib/postgresql/data postgres:9.6-alpine
자 이제 필요한 서버는 다 구동되었습니다. 이제 호스트 서버에 postgresql-client 패키지를 설치해주면 PostgreSQL cli 명령어를 사용할 수 있습니다.
ubuntu@ip-000-00-0-000:/$ sudo apt-get install postgresql-client
포트를 바인딩해주었으니 localhost의 5432 포트로 접근하면 PostgreSQL 컨테이너로 연결됩니다.
ubuntu@ip-000-00-0-000:/$ psql -U postgres -p 5432 -h localhost
Password for user postgres:
psql (10.18 (Ubuntu 10.18-0ubuntu0.18.04.1), server 9.6.20)
Type "help" for help.
postgres=#
의도한 대로 잘 동작하는 걸 확인했으니, 호스트 서버에서 덤프 명령어인 pg_dump를 사용할 차례입니다.
여기서 조금의 삽질이 있었는데,
처음에는 압축파일로 데이터를 백업하려 했습니다.
sudo pg_dump -U postgres -h localhost -p 5432 postgres | gzip > ~/db_backup.gz
하지만 이렇게 압축된 백업 데이터를 까 보면 sql 확장자가 아닌 평문 데이터임을 확인할 수 있습니다. sql 확장자가 아닌 파일로 데이터를 복원하기 위해서는 pg_restore라는 명령어를 사용해야 하는데, 또 이 pg_restore 명령어는 PostreSQL(RDS) 서버와 명령어를 실행 주체인(좀 전에 다운로드하였던) postgresql-client 패키지의 버전이 일치해야만 작동하는 뭣 같은 상황이 발생해 버립니다. 운이 좋아서 이미 같은 버전이 깔려 있다면 좋겠지만, 개발자들은 매번 그렇듯 운이 더럽게도 없으니 웬만해서는 압축하지 말고 덤프를 뜨시는 걸 추천드립니다. (*버전 맞춰주는 게 여간 귀찮은 일이 아닌지라...)
* postgresql-client 패키지를 리눅스에서 설치하면 default로 9.x 버전을 설치해줍니다. 하지만 PostgreSQL이 13 버전까지 나온 마당에 그보다 상위 버전을 쓰고 있는 분들이 더 많을 것 같습니다. (AWS에서 애초에 내년이면 9.x 버전은 지원도 안 해준다.)
무튼 postgresql-client 12~13 버전을 설치하기 위해서는 험난한 삽질이 기다리고 있기에... 내 백업 데이터 너무 커서 호스트 서버에 용량이 부족한데 어떡하죠?라는 상황이 아닌 이상 sql 확장자 파일로 덤프를 만들어줍니다. (이런 상황도 사실 후딱 EBS 올리는 게 편할 듯)
# 여기서 DB 자리에 덤프 대상이 될 데이터베이스 이름을 적어주면 된다. redash의 경우 postgres
pg_dump DB > backup_data.sql
해당 파일이 잘 생성되었으면, RDS로 데이터를 이관해줍니다. 만약 이미 RDS 안에 데이터가 존재한다면, 내부 데이터를 한 번 드랍해준 다음 덤프를 올려줘야 합니다. PostgreSQL에서 모든 테이블을 드랍하는 방법은 여기를 참고하세요. 드랍하고 난 다음 제대로 잘 비워졌는지 확인하는 것도 필수입니다.
이제 RDS에 데이터를 옮겨줄 차례입니다.
psql -U postgres -h myinstance.123456789012.ap-northeast-2.rds.amazonaws.com -p 5432 --set ON_ERROR_STOP=1 --single-transaction < backup_data.sql
데이터가 잘 생성되었으면 금이야 옥이야 서둘러 s3에 저장해줍니다.
ubuntu@ip-000-00-0-000:~$ aws s3 cp backup_data.sql s3://bucket.url.co.kr/name
이제 redash 서버가 해당 RDS를 바라보게 설정만 해주면 됩니다. 우선 호스트 서버에서, /opt/redash/env 파일부터 바꿔줍니다.
그중 REDASH_DATABASE_URL 변수만 바꿔주면 됩니다.
#예시
REDASH_DATABASE_URL=postgresql://postgres:password@rds-name.123456789012.ap-northeast-2.rds.amazonaws.com/postgres
docker-compose 파일도 수정해줍시다. postgres와 연관된 줄은 모두 삭제하거나 주석 처리해주면 됩니다.
version: "2"
x-redash-service: &redash-service
image: redash/redash:latest
depends_on:
# - postgres
- redis
#생략...
services:
#생략...
redis:
image: redis:5.0-alpine
restart: always
# postgres:
# image: postgres:9.6-alpine
# env_file: /opt/redash/env
# volumes:
# - /opt/redash/postgres-data:/var/lib/postgresql/data
# restart: always
컨테이너를 재실행해줍니다.
$ docker-compose restart
혹은
$ docker stop $(docker ps -a -q)
$ docker-compose up -d
EC2 엔드포인트로 접속해보면 잘 동작하는지 확인해볼 수 있습니다.
기존에 쓰고 있던 redash였으니까, 로그인화면이 나와야 정상입니다.
RDS에서 문제가 없는걸 확인했으니, 이제 ECS Fargate로 redash app을 이관할 차례입니다. 해당 작업은 다음 포스트에서 다뤄보도록 하겠습니다.
pub/sub 이해하기 (JS 예시) (0) | 2021.10.25 |
---|---|
경력 0개월차 개발자의 고래 해체 작업 썰 - 3 [ECS task-definitions] (0) | 2021.10.04 |
경력 0개월차 개발자의 고래 해체 작업 썰 - 1 [Docker, ECS] (1) | 2021.08.24 |
(macOS) AWS EC2 인스턴스 / 리눅스 서버 접속 (0) | 2021.03.05 |
AWS로 EC2 인스턴스 생성 / 탄력적 IP(Elastic IP) 할당 (0) | 2021.03.05 |
댓글 영역