Docker Airflow Oracle 활용하기
Apache Airflow, Oracle 공식 문서를 토대로 진행하고자 한다.
https://airflow.apache.org/docs/apache-airflow-providers-oracle/stable/index.html
https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html
아직 Airflow를 설치하지 않았다면 아래 글을 참고한 뒤 오면 좋다
dockerhub에 이미지를 올려뒀다.
https://hub.docker.com/r/gudrb963/oracle-airflow
설치 시작
1. docker-compose에 환경변수 추가
_PIP_ADDITIONAL_REQUIREMENTS: ${_PIP_ADDITIONAL_REQUIREMENTS:- apache-airflow-providers-oracle cx_Oracle}
Airflow에는 Oracle을 기본적으로 제공하지 않기 때문에
모든 서비스에 Oracle을 설치해주어야 한다.
https://github.com/GHGHGHKO/airflow/commit/40533b26db837a4cce15f52ffc0fe362fc68f6c4
위 내용과 같다.
pip install apache-airflow-providers-oracle
pip install cx_Oracle
내용과 같다.
2. docker-compose 빌드 후 Airflow 실행
docker-compose build
docker-compose up airflow-init
docker-compose up -d
3. airflow-airflow-webserver 접속
접속하고
OracleOperator 혹은 Oracle 관련 쿼리를 실행했는데
아래와 같은 오류가 나온다.
cx_Oracle.DatabaseError: DPI-1047: Cannot locate a 64-bit Oracle Client library: "libclntsh.so: cannot open shared object file: No such file or directory". See https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html for help
Kubernetes 기반으로 실행했을 경우
해결 할 수 있는 방법이 있으나
Docker 혹은 Docker Swarm으로 실행했을 때
위 문제를 해결하기 위해서는
Dockerfile을 만든 후 이미지를 새로 만들어야 한다.
4. Dockerfile 추가
FROM apache/airflow:2.2.4
USER root
RUN apt-get update
RUN apt-get install wget -y
RUN apt-get install zip -y
WORKDIR /opt/oracle
RUN wget https://download.oracle.com/otn_software/linux/instantclient/215000/instantclient-basic-linux.x64-21.5.0.0.0dbru.zip
RUN unzip -o /opt/oracle/instantclient-basic-linux.x64-21.5.0.0.0dbru.zip
RUN apt-get install libaio1
RUN sh -c "echo /opt/oracle/instantclient_21_5 > /etc/ld.so.conf.d/oracle-instantclient.conf"
RUN ldconfig
USER airflow
위 내용은
보고있는 블로그 맨 위에 있는
https://cx-oracle.readthedocs.io/en/latest/user_guide/installation.html
내용을 참고하여 만들었다.
https://github.com/GHGHGHKO/airflow/blob/master/Dockerfile
위 내용과 같다.
언제든지 업데이트 될 수 있는 파일이 있기 때문에
좋지 않은 방법이다.
5. 이미지 생성
docker-compose.yaml 과 같은 위치에 Dockerfile을 두고
docker-compose.yaml 을 아래와 같이 수정한다.
image: pepega/airflow:2.2.4
build:
context: .
dockerfile: ./Dockerfile
docker-compose.yaml을 빌드한다.
docker-compose build
만들어진 이미지를 확인한다.
# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pepega/airflow 2.2.4 21702a20c143 2 minutes ago 1.75GB
Airflow를 실행한다.
docker-compose up airflow-init
docker-compose up -d
세션이 끊어지거나 재시작되는 경우는 없는 것 같다.
Swarm에서 Replicas 0/1 문제가 있었는데
이미지를 다시 생성하니 해결됐다.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f151fa3d0613 pepega/airflow:2.2.4 "/usr/bin/dumb-init …" 2 minutes ago Up About a minute (healthy) 8080/tcp airflow-airflow-worker-1
d2834529e241 pepega/airflow:2.2.4 "/usr/bin/dumb-init …" 2 minutes ago Up About a minute (healthy) 8080/tcp airflow-airflow-scheduler-1
fa5d09487828 pepega/airflow:2.2.4 "/usr/bin/dumb-init …" 2 minutes ago Up About a minute (healthy) 0.0.0.0:8080->8080/tcp airflow-airflow-webserver-1
c2550788df3c pepega/airflow:2.2.4 "/usr/bin/dumb-init …" 2 minutes ago Up About a minute (healthy) 8080/tcp airflow-airflow-triggerer-1
c41100bf9d96 pepega/airflow:2.2.4 "/usr/bin/dumb-init …" 2 minutes ago Up About a minute (healthy) 0.0.0.0:5555->5555/tcp, 8080/tcp airflow-flower-1
1dd46ee4b07a redis:latest "docker-entrypoint.s…" 38 minutes ago Up 38 minutes (healthy) 6379/tcp airflow-redis-1
9f435d7c3069 postgres:13 "docker-entrypoint.s…" 38 minutes ago Up 38 minutes (healthy) 5432/tcp airflow-postgres-1
6. Oracle DAG 추가
Airflow 상단 메뉴에서
Admin -> Connections에서 Oracle 접속 정보를 추가해줘야 한다.
import datetime
import pendulum
from airflow import DAG
from airflow.providers.oracle.operators.oracle import OracleOperator
KST = pendulum.timezone("Asia/Seoul")
default_args = {
'owner': 'pepega',
}
with DAG(
dag_id="oracle_test",
start_date=datetime.datetime(2022, 3, 1, tzinfo=KST),
schedule_interval="@once",
catchup=True,
tags=['pepega'],
) as dag:
oracle_task = OracleOperator(
task_id='oracle',
oracle_conn_id='oracle_test',
sql='SELECT * FROM DUAL',
dag=dag,
)
oracle_task
https://github.com/GHGHGHKO/airflow/blob/master/dags/oracle_test.py
잘 작동한다.
다음 글에는
Branch를 활용할 것이다.