에어플로우에서 SSH로 다른 인스턴스에 접속하기

hyeok2·2023년 8월 10일
0

Airflow_stu

목록 보기
1/5
post-thumbnail

계기

  • 사용자 기반 ML 모델을 돌리기 위한 인스턴스와 에어플로우, django, DB 인스턴스를 모두 분리해놓았다.
  • 효율적인 관리를 위함이었다.
  • 따라서 에어플로우에서 다른 인스턴스에 접속하여 사용자기반 추천시스템을 실행하는 주기적인 작업 실행을 세팅해야했다.

세팅과정

1. GCP 간의 SSH 접속을 위한 authorized_key 등록

에어플로우가 설치된 인스턴스에서 작업

  • ssh-keygen -t rsa : 키 생성 -> 엔터->엔터 id_rsa 개인키와 id_rsa.pub가 생긴다.
  • cd ~ 홈으로 가서 cd .ssh ssh 폴더로 들어가고vim id_rsa.pub id_rsa.pub을 편집기로 들어간다.
    (cat id_rsa.pub, vi id_rsa.pub, nano id_rsa.pub) 편한걸로 골라잡으면 된다.
  • ssh-rsa로 시작하는 코드를 복사해놓는다 (메모장에 하면 편함)

원격접속할 인스턴스로 접속

  • 기존 로컬에서 접속을 해본다. GCP에서는 웹으로 가능(ppk파일 생성하여 접속 등)
  • 원격접속 ssh를 원하는 인스턴스로 접속, cd ~/.ssh로 접속하여 authorized_keys 파일에 ssh-rsa 값을 붙여넣는다. (vim authorized_keys -> 복붙 -> :wq)
  • 원격 접속할 인스턴스에서 작업은 끝이다.

접속확인

  • 에어플로우 인스턴스에서 ssh {USER이름}@IP주소 를 치면 정상 접속되는 것을 확인 할 수 있다.

2. airflow에 id_rsa 프라이빗 키를 넣어준다.

  • 이 부분은 해당사항이 없을 수도 있겠지만 도커로 실행했다면 꼭 필요한 과정이다.
  • 도커로 실행중이라는 것을 망각한 나머지... 왜 안돼! 왜오애ㅗ애ㅗ애!!! 하게 되었다. 뒤늦게 알아버린 사실..
  • 도커로 실행했다면 .ssh 폴더를 볼륨으로 마운트하지 않은 이상 바로 접속은 어렵다.

도커 컨테이너(웹서버) 안에 들어가보기

  • docker ps 로 에어플로우 웹서버의 컨테이너 이름을 확인한다.
  • docker exec -it pshyeok_airflow-webserver_1 /bin/bash 에어플로우 웹서버의 bash셀을 실행한다.
  • pwd로 경로를 확인하면 대부분 /opt/airflow 로 나올거다(아마도..?)
  • 볼륨을 마운트하고 다시 컴포즈업 하기 귀찮으니 그냥 이미 마운트 되어있는 dags에 id_rsa를 넣는다.

id_rsa 파일 복사하기

  • cd ~/.ssh .ssh 폴더로 진입
  • cp id_rsa ~/dags/id_rsa : 복사한다.
    -> 에어플로우 컨테이너 안에도 파일이 들어간걸 확인할 수 있다.

3. airflow 웹서버에서 설정하기

커넥션 설정하기

  • admin > connections > + 어드민 커넥션 +버튼 순서대로 눌러준다.
  • 커넥션id를 설정해주고 type은 ssh로 설정
  • 파일을 실행할 인스턴스의 ip주소를 입력
  • 유저네임을 적는다.
  • 포트는 일반적으로 사용하는 22번 포트를 사용하니 입력해놓았다.
  • Extra : 여기에 키파일의 위치를 적어준다. 접속하는데 타임아웃을 줘 무한정 대기하지 않게 설정.
    {
      "key_file": "/opt/airflow/dags/id_rsa",
      "conn_timeout": "10"
    }
  • 테스트를 눌러본다
  • 잘 연결이 되었단다.

4. 에어플로우 덱을 실행시켜본다.

  • 여기까지했으면 끝이다.
  • [2023-08-10, 19:28:11 KST] {transport.py:1893} INFO - Authentication (publickey) successful!
  • python 파일
from datetime import datetime
from airflow import DAG
from airflow.providers.ssh.hooks.ssh import SSHHook
from airflow.providers.ssh.operators.ssh import SSHOperator
# SSHHook 객체 생성
ssh_hook = SSHHook(
    ssh_conn_id="<연결시 설정한 connection 이름>",
    username="<유저이름>",
    remote_host="<인스턴스 ip 주소>",
    key_file=""
)
default_args = {
    'owner': 'pshyeok2',
    'depends_on_past': False,
    'start_date': datetime(2023, 8, 10, 3, 0), # 시작 날짜 및 시간 설정
    'retries': 0
}
with DAG('my_dag',
         default_args=default_args,
         schedule_interval='0 3 * * *', # 스케줄 (매일 3시에 실행)
         catchup=False
         ) as dag:
    # SSH Hook 설정
    ssh_hook = SSHHook(ssh_conn_id="ML")
    # SSHOperator를 이용하여 실행할 파일 경로 설정
    remote_file_path = "<실행할파일의 경로>"
    # SSHOperator를 이용하여 파일 실행
    run_file_command = f"python {remote_file_path}"
    ssh_operator = SSHOperator(task_id="run_file", ssh_hook=ssh_hook, command=run_file_command)

끝.

  • 해당 인스턴스에서 복잡한 과정을 거치는게 아니라 어렵지는 않았지만
  • 도커환경에서 볼륨 마운트 설정이 계속 신경써야한다는점.
  • 복잡한 스케쥴링을 추가하게되면 어떤 방향으로 덱을짜야할지를 계속 생각해봐야겠다.

참고자료

profile
땅을 파다보면 흙과 물을 보겠지만, 코드를 파다보면 답이 보일것이다.

2개의 댓글

comment-user-thumbnail
2024년 5월 27일

저는 PermissionError: [Errno 13] Permission denied: '/opt/airflow/ssh-keys/id_rsa' 에러가 나는데 파일 권한 수정 없이 하셨는지요?

1개의 답글