์์ฝ
- ์ธํ๋ผ ํ๊ฒฝ ๊ตฌ์ถ: ๋จผ์ ์์ ์ ์ธ ์๋ฒ ์ด์ฉ์ ์ํด ๊ณ ์ IP๋ฅผ ํ๋ณดํ๊ณ VCN ๋ณด์ ๋ชฉ๋ก์์ SSH(22), Airflow(8080), DB(5432) ํฌํธ๋ฅผ ๊ฐ๋ฐฉํ์ฌ ๋คํธ์ํฌ ๊ธฐ์ด๋ฅผ ๋ง๋ จํฉ๋๋ค. ์ธ์คํด์ค ์์ฑ ์์๋ ์ด๊ธฐํ ์คํฌ๋ฆฝํธ๋ฅผ ํตํด OS ๋ฐฉํ๋ฒฝ์ ์๋์ผ๋ก ํด์ ํ์ฌ ์ ์ ํ์์์์ ๋ฐฉ์งํ๊ณ , ์์ฑ ํ VNIC ์ค์ ์ ํตํด ๊ณ ์ IP๋ฅผ ์ฐ๊ฒฐํ์ฌ ๋ณํ์ง ์๋ ์ ์ ํ๊ฒฝ์ ์์ฑํฉ๋๋ค.
- ์ํํธ์จ์ด ๋ฐ ์๋น์ค ๊ตฌ์ถ: ์๋ฒ์ ํ์์กด์ ํ๊ตญ ํ์ค์(KST)๋ก ๋ณ๊ฒฝํ ํ, ๋ฐ์ดํฐ ๊ด๋ฆฌ์ ํธ์์ฑ๊ณผ ์์์ฑ์ ์ํด PostgreSQL์ ํธ์คํธ ์๋ฒ์ ์ง์ ์ค์นํ๊ณ ์ธ๋ถ ์ ์์ด ๊ฐ๋ฅํ๋๋ก ์ค์ ์ ๋ณ๊ฒฝํฉ๋๋ค. Airflow๋ ํ๊ฒฝ ๊ฒฉ๋ฆฌ๋ฅผ ์ํด Docker ์ปจํ ์ด๋๋ก ๊ตฌ๋ํ๋ฉฐ, ๋จ์ผ ์๋ฒ์ ์ต์ ํ๋
LocalExecutor๋ฅผ ์ฌ์ฉํฉ๋๋ค.- ์ฐ๋ ๋ฐ ์ต์ ํ: Docker ์ปจํ ์ด๋(Airflow)๊ฐ ํธ์คํธ(PostgreSQL)์ ํจ์จ์ ์ผ๋ก ์ ์ํ ์ ์๋๋ก
docker-compose.yaml์extra_hosts์ค์ ์ ์ถ๊ฐํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ธ๋ถ ํธ๋ํฝ ๋ ธ์ถ ์์ด ๋ด๋ถ ์ฃผ์์ธhost.docker.internal์ ์ฌ์ฉํ์ฌ ๋ณด์์ฑ๊ณผ ๋คํธ์ํฌ ์ฑ๋ฅ์ ๋์์ ํ๋ณดํ ํ์ด๋ธ๋ฆฌ๋ ์ํคํ ์ฒ๋ฅผ ๊ตฌํํฉ๋๋ค.
0. ๋ค์ด๊ฐ๋ฉฐ
์ด์ ํฌ์คํ ์์ Oracle ์ ํตํด ๋๋ง์ ์๋ฒ๋ฅผ ๊ตฌ์ถํ์๋ค. (์ฐธ๊ณ : (Oracle Cloud) ๋๋ง์ ์๋ฒ ๋ง๋ค๊ธฐ)
์ด์ ํ๋์จ์ด(์๋ฒ)๊ฐ ์ค๋น๋์์ผ๋ ์ํํธ์จ์ด๋ฅผ ์ฌ๋ฆด ์ฐจ๋ก์ ๋๋ค. ์ฐ๋ฆฌ์ ๋ชฉํ ์ํคํ ์ฒ๋ ๋ค์๊ณผ ๊ฐ๋ค.
- PostgreSQL: ์๋ฒ(Host)์ ์ง์ ์ค์น (๋ฐ์ดํฐ ์์์ฑ ๋ฐ ๊ด๋ฆฌ ์ฉ์ด์ฑ)
- Airflow: Docker ์ปจํ ์ด๋๋ก ๊ตฌ๋ (์ค์น ๋ณต์ก๋ ์ ๊ฑฐ ๋ฐ ํ๊ฒฝ ๊ฒฉ๋ฆฌ)
์ ๋ mac์์ termius ๋ผ๋ ์ฑ์ ์ด์ฉํ์ฌ, ์๋ฒ์ ์ ์ํด์ ์์ ์ ์ํํ์๋ค. Termius ์ค์น
(ํด๋น ๋ด์ฉ๋ Gemini Pro์ ๋์์ ๋ฐ์๋ค!)
1. ์๋ฒ ๊ธฐ์ด ์ค์ (ํ์์กด ๋ณ๊ฒฝ)
ํด๋ผ์ฐ๋ ์๋ฒ๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธ๊ณ ํ์ค์(UTC)๋ก ์ค์ ๋์ด ์๋ค. ๋ฐ์ดํฐ ์์ง ๋ฐ Airflow ์ค์ผ์ค๋ง ๋ฑ์ ํธ์๋ฅผ ์ํด KST(ํ๊ตญ ์๊ฐ)๋ก ๋ณ๊ฒฝํ์๋ค.
# ํจํค์ง ์
๋ฐ์ดํธ
sudo apt update && sudo apt upgrade -y
# ํ๊ตญ ์๊ฐ์ผ๋ก ๋ณ๊ฒฝ
sudo timedatectl set-timezone Asia/Seoul
# ํ์ธ
date # KST๋ผ๊ณ ๋์ค๋ฉด ์ฑ๊ณต2. PostgreSQL ์ค์น (Host Install)
Docker๋ก DB๋ฅผ ๋์ธ ์๋ ์์ง๋ง, ๋ฐ์ดํฐ์ ์์ ํ ๋ณด๊ด๊ณผ ์ธ๋ถ(๋ด ๋ก์ปฌ PC, DataGrip ๋ฑ) ์ ์ ํธ์๋ฅผ ์ํด ์๋ฒ์ ์ง์ ์ค์นํ๋ ๋ฐฉ์์ ์ ํ
2.1 ์ค์น ๋ฐ ์ค์
# PostgreSQL ์ค์น
sudo apt install postgresql postgresql-contrib -y
# ๋ถํ
์ ์๋ ์์ ๋ฑ๋ก ๋ฐ ์คํ
sudo systemctl enable postgresql
sudo systemctl start postgresql2.2 ์ธ๋ถ ์ ์ ํ์ฉ (์ค์)
๊ธฐ๋ณธ์ ์ผ๋ก Postgres๋ ๋ก์ปฌ ์ ์๋ง ํ์ฉํ๋ฏ๋ก, ์ธ๋ถ ์ ์์ ์ํด ๋ ๊ฐ์ง ํ์ผ์ ์์ ํด์ผ ํ๋ค
1) postgresql.conf ์์ (๋ชจ๋ IP์์ ์ ์ ํ์ฉ)
# ์ค์ ํ์ผ ์ด๊ธฐ (nano ์๋ํฐ ์ฌ์ฉ)
sudo nano /etc/postgresql/16/main/postgresql.conf
# (๋ฒ์ 16์ด ์๋๋ผ๋ฉด 14, 15 ๋ฑ ์ค์น๋ ๋ฒ์ ์ซ์๋ก ๊ฒฝ๋ก ํ์ธ ํ์)Ctrl + W๋ฅผ ๋๋ฌlisten_addresses๋ฅผ ๊ฒ์- ์ฃผ์(
#)์ ์ ๊ฑฐํ๊ณlocalhost๋ฅผ*๋ก ๋ณ๊ฒฝ- AS-IS:
#listen_addresses = 'localhost' - TO-BE:
listen_addresses = '*'
- AS-IS:
Ctrl + O(์ ์ฅ) โEnterโCtrl + X(๋๊ฐ๊ธฐ)
2) pg_hba.conf ์์ (์ธ์ฆ ๋ฐฉ์ ์ค์ )
sudo nano /etc/postgresql/16/main/pg_hba.conf- ํ์ผ ๋งจ ์๋๋ก ์ด๋ํด์ ๋ค์ ์ค ์ถ๊ฐํ์ฌ, ๋ชจ๋ IP ์์ ์ ์ ํ์ฉ
host all all 0.0.0.0/0 scram-sha-256์๋น์ค ์ฌ์์
sudo systemctl restart postgresql2.3 DB ๋ฐ ์ ์ ์์ฑ
ํ๋ก์ ํธ์ฉ ์ ์ ์ DB๋ฅผ ์์ฑํฉ๋๋ค.
# postgres ๊ด๋ฆฌ์ ๊ณ์ ์ผ๋ก ์ ํ
sudo -i -u postgres
# SQL ์ ์
psqlCREATE USER myuser WITH PASSWORD 'mypassword123';
-- Airflow์ฉ DB ์์ฑ
CREATE DATABASE airflow_db;
-- ํ๋ก์ ํธ ๋ฐ์ดํฐ ์ ์ฅ์ฉ DB ์์ฑ
CREATE DATABASE project;
-- ๊ถํ ๋ถ์ฌ
GRANT ALL PRIVILEGES ON DATABASE airflow_db TO myuser;
GRANT ALL PRIVILEGES ON DATABASE project TO myuser;3. Airflow ์ค์น (Docker Compose)
Airflow๋ ์์กด์ฑ ํจํค์ง๊ฐ ๋ง์ ์ง์ ์ค์น(Native Install)ํ๋ฉด ๊ผฌ์ด๊ธฐ ์ฌ์ ๊น๋ํ๊ฒ Docker๋ฅผ ์ฌ์ฉ
3.1 Docker ์ค์น
์ค๋ผํด A1 ์ธ์คํด์ค๋ ARM64 ์ํคํ ์ฒ์ด์ง๋ง, Docker๋ ์ด๋ฅผ ์๋ฒฝํ๊ฒ ์ง์ํฉ๋๋ค. ๊ณต์ ๋ฌธ์๋ฅผ ์ฐธ๊ณ ํด Docker Engine๊ณผ Docker Compose๋ฅผ ์ค์นํฉ๋๋ค.
# 1. Docker ํ์ ํจํค์ง ์ค์น
sudo apt install apt-transport-https ca-certificates curl software-properties-common -y
# 2. Docker ๊ณต์ GPG ํค ์ถ๊ฐ
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 3. ๋ ํฌ์งํ ๋ฆฌ ์ถ๊ฐ (ARM64 ์ํคํ
์ฒ ์๋ ์ธ์)
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 4. Docker Engine ์ค์น
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin -y
# 5. ๊ถํ ์ค์ (sudo ์์ด docker ์ฐ๊ธฐ ์ํจ)
sudo usermod -aG docker $USER
# 6. ์ ์ฉ์ ์ํด ์ธ์
์ฌ์ ์ ํ์ (exit ํ ๋ค์ ์ ์)
exit3.2 Airflow ์คํ ๋ฐ ์ค์
ํ ๋๋ ํ ๋ฆฌ์ airflow ํด๋๋ฅผ ๋ง๋ค๊ณ docker-compose.yaml์ ์์ฑํ์ต๋๋ค. ์ฌ๊ธฐ์ ์ค์ํ ์ค์ ํฌ์ธํธ๊ฐ ๋ ๊ฐ์ง ์์ต๋๋ค.
ํ๋ก์ ํธ ํด๋ ์์ฑ ๋ฐ ์ด๋
cd ~
mkdir airflow
cd airflow
mkdir -p ./dags ./logs ./plugins ./configdocker-compose.yaml ํ์ผ ์์ฑ
Airflow ์คํ ์ค์ ์ ๋ด์ ํ์ผ ์์ฑ ํ, ๋ด์ฉ ๋ถ์ฌ๋ฃ๊ธฐ (ํธ์คํธ DB(PostgreSQL)์์ ์ฐ๊ฒฐ์ ์ํด extra_hosts ์ค์ ์ ํฌํจ)
# ํ์ผ ์์ฑ ๋ฐ ํธ์ง
nano docker-compose.yamlversion: '3.8'
x-airflow-common:
&airflow-common
image: apache/airflow:2.10.4 # ์ต์ ๋ฒ์
environment:
&airflow-common-env
AIRFLOW__CORE__EXECUTOR: LocalExecutor # ๋จ์ผ ์๋ฒ์ฉ ์ต์ ๋ชจ๋
AIRFLOW__CORE__SQL_ALCHEMY_CONN: postgresql+psycopg2://airflow:airflow@postgres/airflow
AIRFLOW__CORE__FERNET_KEY: ''
AIRFLOW__CORE__DAGS_ARE_PAUSED_AT_CREATION: 'true'
AIRFLOW__CORE__LOAD_EXAMPLES: 'false' # ์์ DAG ๋๊ธฐ (๊น๋ํ๊ฒ)
AIRFLOW__API__AUTH_BACKEND: 'airflow.api.auth.backend.basic_auth,airflow.api.auth.backend.session'
volumes:
- ./dags:/opt/airflow/dags
- ./logs:/opt/airflow/logs
- ./plugins:/opt/airflow/plugins
- ./config:/opt/airflow/config
user: "${AIRFLOW_UID:-50000}:0"
depends_on:
&airflow-common-depends-on
postgres:
condition: service_healthy
# โ
์ค์: ์ปจํ
์ด๋ ๋ด๋ถ์์ ํธ์คํธ(๋ด ์๋ฒ)์ DB์ ์ ์ํ๊ธฐ ์ํ ์ค์
extra_hosts:
- "host.docker.internal:host-gateway"
services:
# 1. Airflow ๋ฉํ๋ฐ์ดํฐ์ฉ ๋ด๋ถ DB (์ฌ์ฉ์ DB์ ๋ถ๋ฆฌ)
postgres:
image: postgres:13
environment:
POSTGRES_USER: airflow
POSTGRES_PASSWORD: airflow
POSTGRES_DB: airflow
volumes:
- postgres-db-volume:/var/lib/postgresql/data
healthcheck:
test: ["CMD", "pg_isready", "-U", "airflow"]
interval: 5s
retries: 5
restart: always
# 2. Airflow ์น ์๋ฒ (UI)
airflow-webserver:
<<: *airflow-common
command: webserver
ports:
- "8080:8080"
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:8080/health"]
interval: 10s
timeout: 10s
retries: 5
restart: always
# 3. Airflow ์ค์ผ์ค๋ฌ (์์
๊ด๋ฆฌ)
airflow-scheduler:
<<: *airflow-common
command: scheduler
healthcheck:
test: ["CMD", "curl", "--fail", "http://localhost:8974/health"]
interval: 30s
timeout: 10s
retries: 5
restart: always
# 4. ์ด๊ธฐํ ์ปจํ
์ด๋ (์ต์ด 1ํ ์คํ ํ ์ข
๋ฃ๋จ)
airflow-init:
<<: *airflow-common
command: version
environment:
<<: *airflow-common-env
_AIRFLOW_DB_UPGRADE: 'true'
_AIRFLOW_WWW_USER_CREATE: 'true'
_AIRFLOW_WWW_USER_USERNAME: ${_AIRFLOW_WWW_USER_USERNAME:-airflow}
_AIRFLOW_WWW_USER_PASSWORD: ${_AIRFLOW_WWW_USER_PASSWORD:-airflow}
user: "0:0"
volumes:
- ./dags:/opt/airflow/dags
- ./logs:/opt/airflow/logs
- ./plugins:/opt/airflow/plugins
volumes:
postgres-db-volume:Point 1:
LocalExecutor์ฌ์ฉ ์ด์
๋ณดํต ์์ฉ ํ๊ฒฝ์์๋ CeleryExecutor + Redis ์กฐํฉ์ ์ฐ์ง๋ง, ์ฐ๋ฆฌ๋ ๋จ์ผ ์๋ฒ์์ ๋๋ฆฌ๋ ๊ฐ์ธ ํ๋ก์ ํธ์
๋๋ค. ๋ถํ์ํ ๋ฆฌ์์ค ๋ญ๋น๋ฅผ ์ค์ด๊ณ ๊ตฌ์ฑ์ ๋จ์ํํ๊ธฐ ์ํด ๋ก์ปฌ์์ ๋ฐ๋ก ์์
์ ์ํํ๋ LocalExecutor๊ฐ ๊ฐ์ฅ ํจ์จ์ ์
๋๋ค.
environment:
AIRFLOW__CORE__EXECUTOR: LocalExecutorPoint 2:
extra_hosts์ค์ (Linux Docker ํ์)
Docker ์ปจํ
์ด๋(Airflow) ์์์ ๋ด ์๋ฒ(Postgres)๋ฅผ host.docker.internal์ด๋ผ๋ ์ด๋ฆ์ผ๋ก ๋ถ๋ฅด๊ธฐ ์ํ ์ค์ ์
๋๋ค. (Mac/Windows Docker์ ๋ฌ๋ฆฌ ๋ฆฌ๋
์ค์์๋ ์ด ์ค์ ์ ์ง์ ๋ฃ์ด์ค์ผ ํ๋ค.
extra_hosts:
- "host.docker.internal:host-gateway"ํ๊ฒฝ๋ณ์ ์ค์ ๋ฐ ์ด๊ธฐํ
ํ์ฌ ์ฌ์ฉ์์ ๊ถํ์ Docker์ ์ ๋ฌํ๊ธฐ ์ํด .env ํ์ผ์ ์์ฑ
echo "AIRFLOW_UID=$(id -u)" > .env์ต์ด ํ ๋ฒ ์คํํด์ค๋๋ค. airflow-init ์ปจํ
์ด๋๊ฐ ์คํ๋๋ค๊ฐ ์ฑ๊ณต์ ์ผ๋ก ์ข
๋ฃ(exited with code 0)๋์ด์ผ ํฉ๋๋ค.
# ์ด๊ธฐํ
docker compose up airflow-init
# ์คํ
docker compose up -d
# ํ์ธ
docker compose ps4. ์น ์ ์ ๋ฐ DB ์ฐ๊ฒฐ ํ ์คํธ
Airflow ์น UI(http://๊ณ ์ IP:8080)์ ์ ์ํ ๋ค, Admin -> Connections์์ DB ์ฐ๊ฒฐ ์ ๋ณด๋ฅผ ๋ฑ๋กํฉ๋๋ค. ์ด๋ ๊ฐ์ฅ ๊ณ ๋ฏผ๋์๋ ๋ถ๋ถ์ด ๋ฐ๋ก Host ์ฃผ์์์ต๋๋ค.
๋ด ์๋ฒ์ ๊ณ ์ IP๊ฐ ์๋๋ฐ, ์
host.docker.internal์ฌ์ฉ ์ด์์ด์ 1: ๋ณด์ (Security)
- ๊ณ ์ IP ์ฌ์ฉ ์: ํธ๋ํฝ์ด ์๋ฒ ๋ฐ์ผ๋ก ๋๊ฐ๋ค๊ฐ ๋ค์ ๊ณต์ธ IP๋ฅผ ํ๊ณ ๋ค์ด์ต๋๋ค. ์ด๋ฅผ ์ํด์๋ ๋ฐฉํ๋ฒฝ(VCN)์์ DB ํฌํธ(5432)๋ฅผ ์ ์ธ๊ณ์ ์ด์ด๋ฌ์ผ ํฉ๋๋ค.
- ๋ด๋ถ ์ฃผ์ ์ฌ์ฉ ์: ํธ๋ํฝ์ด ์ธ๋ถ๋ก ๋๊ฐ์ง ์๊ณ ์๋ฒ ๋ด๋ถ(Docker Bridge)์์๋ง ๋๋๋ค. ๋์ค์ ๋ณด์์ ์ํด 5432 ํฌํธ๋ฅผ ๋ซ์๋ฒ๋ ค๋ Airflow๋ ์ฌ์ ํ DB์ ์ ์ํ ์ ์์ต๋๋ค.
์ด์ 2: ํจ์จ์ฑ (Performance)
- ๋ฐฉ๋ฌธ์ ์ด๊ณ ๋ฐ๋ก ์๋ฐฉ(๋ด๋ถ ํต์ )์ผ๋ก ๊ฐ๋ ๊ฒ๊ณผ, ํ๊ด๋ฌธ์ ๋๊ฐ์ ์ ํ๋ฅผ ๊ฑธ์ด ๋ถ๋ฅด๋ ๊ฒ(์ธ๋ถ ํต์ )์ ์ฐจ์ด์ ๋๋ค. ๋ด๋ถ ํต์ ์ด ๋คํธ์ํฌ ์ง์ฐ(Latency) ์์ด ํจ์ฌ ๋น ๋ฅด๊ณ ์์ ์ ์ ๋๋ค.
์ต์ข ์ฐ๊ฒฐ ์ค์
- Conn Id:
์ฌ์ฉ์์ค์ - Conn Type:
Postgres - Host:
host.docker.internal - Database:
project - Login/Password: (์ค์ ํ ๊ณ์ ์ ๋ณด)