Upgrade to Pro — share decks privately, control downloads, hide ads and more …

[PyCon KR 2024] 엔터프라이즈 공급을 위한 파이썬 엔지니어링

[PyCon KR 2024] 엔터프라이즈 공급을 위한 파이썬 엔지니어링

Joongi Kim

October 27, 2024
Tweet

More Decks by Joongi Kim

Other Decks in Programming

Transcript

  1. 목차 엔터프라이즈 솔루션 공급 특징 엔터프라이즈 인스톨러 개발하기 • 단일

    바이너리 배포를 위한 Python 패키징 기법 • Textual 라이브러리를 이용한 터미널 UI (TUI) 구성 기법 결론
  2. Backend.AI 엔터프라이즈 고객사 공급 구조 하드웨어 파트너 리셀링 파트너 래블업

    직접 계약 직접 계약 고객사 고객사 신규 하드웨어 구축 기존 보유 하드웨어 활용 하드웨어 별도 구매 파트너 등급에 따라 1차 기술지원을 제공하기도 함 대부분 하드웨어 자체에 대한 기술지원만 제공
  3. 엔터프라이즈 환경: 인프라와 업데이트 통제의 어려움 인프라에 대한 직접 통제

    불가 • 방화벽 포트 하나만 추가로 열려고 해도 고객사 담당자 확인과 보안팀 승인 등의 절차 필요 • 고객사 네트워크 관리부서나 보안팀도 모르는 레거시 방화벽 및 미들박스 설정으로 인한 부작용 예) 일정 시간 패킷이 없는 TCP 연결을 명시적 리셋 없이 모든 패킷을 블랙홀로 보냄 • 기존 인프라에 올리는 경우 서버의 디스크 파티션이나 네트워크 사양 등이 최적 권장 구성이 아닐 수 있음 업데이트 시점에 대한 통제 불가 • 폐쇄망 환경이어서 직접 방문해야만 업데이트 작업 가능 • 원격 접속이 가능하더라도 사전 승인과 일정 조율 필요 • 설치나 업데이트 진행 시 외부 패키지 관리자를 사용할 수 없음
  4. 엔터프라이즈 환경: 간접적인 트러블슈팅 프로세스 고객사 관리자가 당황하지 않게 하기

    • 고객사 관리자가 고객사 내·외부 사용자들을 상황을 납득시킬 수 있는 ʻ설명’을 우리가 제공해야 함 • 문제 원인이 솔루션인지(자체 버그 / 잘못된 설정 / 사용법 미숙 / upstream 이슈), 고객 코드인지, 운영체제나 드라이버인지, 하드웨어 장애인지 구분해주어야 함 파트너사 엔지니어를 통한 트러블슈팅 • 우리 코드를 100% 이해할 수 없는 파트너사 엔지니어가 1차 기술지원을 하는 경우가 있음 • 1차 기술지원으로 해결 가능한 트러블슈팅 가이드 문서 작성 필요 • Escalation 시 첨부해야 하는 시스템 로그나 기존 확인·조치사항에 대한 체크리스트화 필요
  5. 엔터프라이즈 환경: 재현이 어려운 기술적 이슈들 보안 규정 준수 •

    고객사 내부 정보를 외부로 반출할 수 없는 규정이 강하게 적용되는 경우, 오류 로그 하나를 바깥으로 가져가는 것도 쉽지 않은 경우가 있음 (직접 방문해서만 볼 수 있음) 재현가능한 하드웨어 구성 • 특정 하드웨어 조합에서만 발생하는 이슈들을 어떻게 재현할 것인가? • CUDA 버전, GPU 모델, 인피니밴드 네트워크, … • GPU 100장을 묶어서 돌릴 때만 관찰되는 버그가 있다면 그럼 우리도 고객이랑 똑같은 GPU를 100장 사서 돌려봐야 하는가? (한 대에 수천만원 짜리, 물론 전력과 상면공간은 별도)
  6. 기술적으로 보완할 수 있는 부분들 어려운 점 인프라 통제의 어려움

    폐쇄망 고려한 업데이트 고객사 관리자 당황하지 않게 하기 보안 규정 준수 재현가능한 하드웨어 구성 파트너사 엔지니어 지원 보완 방법 본 발표에서 다루는 부분 Static build로 배포하기 ✅ GUI 기반 인스톨러 제공 ✅ 설치 전 자동화된 precondition 검사 맥락 기반 로깅 시스템 (request ID 등을 활용한 인덱싱) Staging 인프라에 쉽게 자동으로 소스 설치
  7. 엔터프라이즈용 인스톨러 개발 목표 (1) 단일 바이너리 배포 (static build

    + self-contained build) • 설치 파일 반입 절차 자체가 CD/DVD 등의 읽기전용 매체를 요구하거나, USB 메모리(사용 후 파쇄) 등을 이용하여야 하는 경우가 있음 • 온라인으로 전달하는 경우라도 사전 보안 검토 및 별도의 악성코드 검사 절차를 거쳐야 함 • 원격설치를 하는 경우라도 원격데스크탑 환경을 3중 4중으로 타고 들어가야 해서 서버 사용 자체가 매우매우 느리고 버벅이는 경우도 있음 • 따라서 단일 압축파일로 묶을 수 있고 가능한 한 자동화된 설치가 가능하도록 패키징 필요
  8. 단일 바이너리 인스톨러 개발: scie 프로젝트 Scie 프로젝트 • https://github.com/a-scie

    • Pantsbuild와 PEX 기반으로 스스로 압축을 해제하는 단일 실행파일로 Python 프로그램을 패키징할 수 있음 • (macOS, Linux) x (x86-64, arm64) 조합 지원 • Rust로 작성된 bootstrapper를 사용하여 실행파일 진입 오버헤드가 매우 적음
  9. 단일 바이너리 인스톨러 개발: scie 실행파일 구조 Python Interpreter (static

    standalone build by indygreg) $ ./my-executable (download the interpreter or extract it into ~/.cache/nce/…/cpython-3.12.2…/python) (extract the pex into ~/.cache/nce/…/bindings/pex_root) (starts the pex entrypoint with the interpreter) (extract the python sources into ~/.cache/nce/…/bindings/pex_root/user_code) (extract the 3rd party wheels into ~/.cache/nce/…/binding/pex_root/installed_wheels) (your python program starts!) 모든 의존성이 이미 압축 해제된 상태에서는 초기화 과정이 100 msec 이내 소요 scie로 빌드한 ./my-executable의 구조 lift.json scie-jump (written in Rust, a static executable) PEX 3rd party (rebuilt) wheels Python Sources
  10. 단일 바이너리 인스톨러 개발: scie 실행파일 제작 방법 • Pantsbuild

    내장 기능이 아니므로 별도로 플러그인 설치 필요 ◦ https://github.com/sureshjoshi/pants-plugins/tree/main/pants-plugins/experimental/scie ◦ config.py의 Interpter 클래스에서 원하는 Python 버전과 매칭되는 https://github.com/indygreg/python-build-standalone 릴리즈 날짜(yyyymmdd) 설정 ◦ subsystems.py에서 필요하다면 science 릴리즈 버전 및 해시값 업데이트 • Fat 버전(인터프리터 내장)과 Lazy 버전(자동 다운로드) 구분 가능하도록 플러그인 직접 패치 ◦ 참고) backend.ai-client의 Fat 버전 크기 : 약 48 MiB ◦ 참고) backend.ai-client의 Lazy 버전 크기 : 약 28 MiB • 오른쪽과 같은 설정을 pants BUILD 파일에 추가 • 빌드 명령 : pants --tag=scie --tag=fat src/ai/backend/client:: scie_binary( name="backendai-client", fat=False, dependencies=[":pex"], tags=["scie", "lazy"], ) scie_binary( name="backendai-client-fat", fat=True, dependencies=[":pex"], tags=["scie", "fat"], )
  11. 단일 바이너리 인스톨러 개발: 플러그인 오픈소스 코어 및 내장 플러그인

    • pantsbuild를 이용하여 직접 scie 안에 내장하여 빌드 엔터프라이즈 및 고객사 전용 플러그인 • pip wheel 명령으로 모든 의존성을 포함한 “wheelhouse” 아카이브 생성 • 해당 디렉토리를 scie 실행파일과 같은 디렉토리에 복사하면, pex 진입점 실행 시: ◦ 자동으로 wheel 파일들을 압축 해제 ◦ 자동으로 wheel 파일들의 entrypoint 인식 ◦ 모든 압축 해제된 wheel 파일들의 소스 디렉토리를 sys.path에 추가
  12. 엔터프라이즈용 인스톨러 개발 목표 (2) 텍스트 기반 GUI (TUI) •

    실제 고객사 내에서 설치용으로 사용하는 PC가 고객측에서 제공한 랩탑이나 데스크탑으로 제한되기도 하며, 웹브라우저나 데스크탑 OS를 오래된 구버전을 사용하거나 별도의 설치 요청을 해야 하는 경우가 있음 • 아무리 최악의 환경이라도 대부분의 경우 (고객사 방문이든 원격이든) 터미널과 SSH 접속은 제공 ◦ Windows 환경도 openssh 내장, Windows Terminal 앱으로 예전보다 많이 편리해짐 ◦ 최신 버전이 아닌 경우라도 PuTTY나 XShell만 있다면… • 따라서 터미널 상에서 GUI를 구현할 수 있으면 설치 과정의 편의성을 높일 수 있음
  13. TUI 인스톨러 개발: Textual 프로젝트 Textual 프로젝트 • https://textual.textualize.io/ •

    계층적 widget 시스템과 asyncio 지원 • 마우스 기반 상호작용 지원 • 자체 “tcss” 이용한 widget 스타일링 • 터미널 앱을 그대로 웹브라우저에서 실행 가능 • Rich와 연동하여 Markdown 렌더링 제공 • 별도 프로세스로 실행되는 디버그 콘솔 지원 • MIT 라이센스 https://textual.textualize.io/getting_started/#demo
  14. TUI 인스톨러 개발: headless unattended 모드 구현 필요성 • Staging

    area 환경 구축 시 미리 설정된 경로와 옵션으로 자동 설치 • CI 환경에서 실행할 때 tty가 할당되지 않는 경우에도 설치 코드를 돌려볼 수 있게 하기 구현 방법 • 주 App 객체를 생성할 때 headless=True 옵션 지정하여 모든 렌더링을 메모리 상에서만 진행하게 함 • on_mount 이벤트 핸들러에서 post_messeage() 메소드를 사용하여 자동으로 액션 이벤트 주입 Excerpt from https://github.com/lablup/backend.ai/blob/3212918/src/ai/backend/install/cli.py
  15. • 엔터프라이즈 환경에 솔루션 패키지를 배포·유지보수하는 과정은 클라우드 및 자체

    IDC 인프라를 통해 웹서비스를 구축·운영하는 것과 달리 인프라와 업데이트 시점 통제가 어려움 • Python의 풍부한 오픈소스 생태계로부터 Pantsbuild, Scie, Textual 라이브러리를 도입하여, 자체 TUI 기반 단일 바이너리 형식의 self-contained 인스톨러 개발 • 이와 같이 Python을 머신러닝 개발, 단순한 스크립팅 도구, 또는 웹서비스 구현 용도뿐만 아니라 엔터프라이즈 솔루션을 위한 빌드 체인 및 배포 도구로도 사용할 수 있음 결론
  16. 향후 개선할 부분들 🤔 • indygreg의 standalone build는 최대 호환성을

    위해 일부러 옛날 커널 버전을 사용하여 빌드하기 때문에, 최신 커널에서 이 빌드를 실행하더라도 최신 시스템콜을 사용할 수 없음 ◦ 현재 CPython 구조 상 최신 pidfd_open()과 같은 최신 시스템콜은 CPython 빌드 시점에 해당 시스템콜을 지원하는 커널을 사용해야 런타임에 커널의 지원여부를 인식함 ◦ asyncio는 pidfd가 지원되는 환경에서 이를 활용하여 SIGCHLD race 문제를 피하는 효율적인 구현을 자동으로 적용하는데 indygreg build에서는 이러한 개선 혜택을 누릴 수 없음 • 엔터프라이즈 전용 추가 컴포넌트의 설치 프로그램(recipe, script)을 TUI installer가 자동 인식 및 사용하도록 만들기 ◦ 플러그인은 오픈소스 컴포넌트 실행 시 sys.path 조작으로 로드 가능하지만, 컴포넌트 자체가 오픈소스가 아닌 경우에 대한 고려 필요 ◦ 이를 위한 공통 recipe 형식 및 player 사양을 정의해야 함