ํ”„๋กœ์ ํŠธ/DB ์ž๋™ํ™”

ํ์‡„๋ง RHEL 6.5์— ํŒŒ์ด์ฌ ๋ฐฐํฌํ•˜๊ธฐ (2) ๋„์ปค๋กœ ์ž์ฒด์™„๊ฒฐ ๋ฒˆ๋“ค ๋งŒ๋“ค๊ธฐ

THE NICOLE 2026. 6. 24. 18:19

ํ•ต์‹ฌ ์š”์•ฝ

  • 1ํŽธ์—์„œ "์™œ ๊ทธ๋ƒฅ ์•ˆ ๋˜๋Š”๊ฐ€"(RHEL 6.5 = GLIBC 2.12 = ์ตœ์‹  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฑฐ๋ถ€)๋ฅผ ์ •๋ฆฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ํŽธ์€ ์‹ค์ œ๋กœ ์ž์ฒด์™„๊ฒฐ ๋ฒˆ๋“ค์„ ๋งŒ๋“  ๊ณผ์ •์ž…๋‹ˆ๋‹ค.
  • ํ•ต์‹ฌ์€ RHEL 6.5์™€ ๊ฐ™์€ GLIBC 2.12 ํ™˜๊ฒฝ(manylinux2010 ๋„์ปค ์ด๋ฏธ์ง€)์—์„œ ๋นŒ๋“œํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์œˆ๋„์šฐ๋‚˜ ์ตœ์‹  ์šฐ๋ถ„ํˆฌ์—์„œ ๋งŒ๋“ค๋ฉด GLIBC๊ฐ€ ๋†’์•„ RHEL 6.5์—์„œ ์•ˆ ๋•๋‹ˆ๋‹ค.
  • ๋งŒ๋“œ๋Š” ๋™์•ˆ ํ•จ์ •์ด ์—ฌ๋Ÿฟ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. โ‘  ๋„์ปค์˜ Python์ด ์‹ค์ œ ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ์‹ฌ๋ณผ๋ฆญ ๋งํฌ์˜€๋˜ ๊ฒƒ(๋ฒˆ๋“ค์ด 196KB๋กœ ๋‚˜์˜ด) โ‘ก RHEL 6.5์— ์—†๋Š” ๋น„ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ 2๊ฐœ๋ฅผ ๊ฐ™์ด ๋‹ด์•„์•ผ ํ–ˆ๋˜ ๊ฒƒ โ‘ข ๊ฒ€์ฆ ํ™˜๊ฒฝ(CentOS 6 ์ปจํ…Œ์ด๋„ˆ)์ด ์„ธ๊ทธํดํŠธ๋กœ ์ฃฝ์€ ๊ฒƒ ๋“ฑ์ž…๋‹ˆ๋‹ค.
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋กœ๋“œ๋ฟ ์•„๋‹ˆ๋ผ ์•ฑ์ด ๋๊นŒ์ง€ ๋„๋Š”์ง€(์ˆ˜์ง‘→ํƒ์ง€→๋ฆฌํฌํŠธ), ๋ชจ๋ธ ์žฌํ•™์Šต, ๊ทธ๋ž˜ํ”„ ํ•œ๊ธ€ ํฐํŠธ๊นŒ์ง€ ๊ฒ€์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ์ตœ์ข… ์‚ฐ์ถœ๋ฌผ์€ ์•ฝ 124MB์˜ tar.gz ํ•œ ๊ฐœ์ž…๋‹ˆ๋‹ค. RHEL 6.5์—์„œ ์ธํ„ฐ๋„ท·์‹œ์Šคํ…œ ํŒŒ์ด์ฌ ์—†์ด ํ’€์–ด์„œ ์‹คํ–‰ํ•˜๋ฉด ํ•œ๊ธ€ ๊ทธ๋ž˜ํ”„ ๋ฆฌํฌํŠธ๊นŒ์ง€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

1. ๋นŒ๋“œ ์ „๋žต: ์™œ ๋„์ปค์ด๊ณ , ์™œ manylinux2010์ธ๊ฐ€

๋งŒ๋“ค ๊ฒƒ์€ "์ธํ„ฐ๋„ท ์—†์ด RHEL 6.5์—์„œ ๊ทธ๋ƒฅ ํ’€๋ฉด ๋„๋Š” ํ•œ ๋ฉ์–ด๋ฆฌ(tar.gz)" ์ž…๋‹ˆ๋‹ค. ์•ˆ์— ๋“ค์–ด๊ฐˆ ๊ฒƒ์€ โ‘  RHEL 6.5 ํ˜ธํ™˜ Python โ‘ก ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ โ‘ข ์•ฑ ์ฝ”๋“œ โ‘ฃ ๋ชจ๋ธ์ž…๋‹ˆ๋‹ค.

์—ฌ๊ธฐ์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒฐ์ •์€ ์–ด๋””์„œ ๋นŒ๋“œํ•˜๋А๋ƒ์ž…๋‹ˆ๋‹ค. 1ํŽธ์—์„œ ๋ดค๋“ฏ, RHEL 6.5๋Š” GLIBC 2.12๋ผ ๊ทธ ํ™˜๊ฒฝ์—์„œ ๋„๋Š” Python·๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ฐ™์€ GLIBC 2.12 ํ™˜๊ฒฝ์—์„œ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ํ™˜๊ฒฝ์„ ์†์‰ฝ๊ฒŒ ์ฃผ๋Š” ๊ฒƒ์ด manylinux2010 ๋„์ปค ์ด๋ฏธ์ง€์ž…๋‹ˆ๋‹ค. ์ด ์ด๋ฏธ์ง€๋Š” CentOS 6 ๊ธฐ๋ฐ˜(GLIBC 2.12)์— ํŒŒ์ด์ฌ ํŒจํ‚ค์ง€ ๋นŒ๋“œ์— ํ•„์š”ํ•œ ๊ฒƒ๋“ค์ด ๋ฏธ๋ฆฌ ๋“ค์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋„์ปค ์ปจํ…Œ์ด๋„ˆ๋Š” "๊ทธ ์˜ค๋‘๋ง‰๊ณผ ๋˜‘๊ฐ™์€ ๋‚ก์€ ๋ฐฉ์„ ์ฆ‰์„์—์„œ ์ง“๊ณ  ๋‹ค ์“ฐ๋ฉด ๋ฒ„๋ฆฌ๋Š” ์กฐ๋ฆฝ์‹ ๋ฐฉ"์ž…๋‹ˆ๋‹ค. manylinux2010์€ "RHEL 6.5์™€ ๊ฐ™์€ ํ‰ํ˜•์˜ ๋ชจ๋ธํ•˜์šฐ์Šค"์ž…๋‹ˆ๋‹ค. ๊ฐ€๊ตฌ(ํŒŒ์ด์ฌ·๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ)๋Š” ๊ทธ ๋ชจ๋ธํ•˜์šฐ์Šค ์•ˆ์—์„œ ๋งž์ถฐ์•ผ ์ง„์งœ ์˜ค๋‘๋ง‰ ๋ฌธํ‹€(๋‚ฎ์€ GLIBC)์— ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

manylinux2010 ์ปจํ…Œ์ด๋„ˆ(CentOS 6 / GLIBC 2.12)์—์„œ ๋ฒˆ๋“ค์„ ๋งŒ๋“ค๊ณ , ๊ทธ ๊ฒฐ๊ณผ๋ฌผ์„ RHEL 6.5์— ๊ฐ€์ ธ๊ฐ€๋Š” ํ๋ฆ„์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋‘ ํ™˜๊ฒฝ์˜ GLIBC๊ฐ€ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋นŒ๋“œ ๊ฒฐ๊ณผ๊ฐ€ ๋ชฉ์ ์ง€์—์„œ ๊ทธ๋Œ€๋กœ ๋ˆ๋‹ค๋Š” ์ ์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

๋กœ์ปฌ์— ๋„์ปค๊ฐ€ ๊น”๋ ค ์žˆ์œผ๋ฉด(Docker Desktop) ๋ณ„๋„ ์„œ๋ฒ„ ์—†์ด ์œˆ๋„์šฐ์—์„œ๋„ ๋ฆฌ๋ˆ…์Šค ์ปจํ…Œ์ด๋„ˆ๋กœ ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๋ถ€ํ„ฐ ๋ฐ›์Šต๋‹ˆ๋‹ค.

$ docker pull quay.io/pypa/manylinux2010_x86_64
Status: Downloaded newer image ...   # ์•ฝ 1GB

์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ Python 3.7์€ /opt/python/cp37-cp37m/bin/python ์— ์žˆ์Šต๋‹ˆ๋‹ค.


2. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์ง„์งœ ๋„๋Š”์ง€ ๋จผ์ € ํ™•์ธ

์ „๋žต์€ ์ข‹์€๋ฐ, ๊ฐ€์žฅ ํฐ ์˜๋ฌธ์ด ๋‚จ์•„ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

"๊ทธ๋ž˜์„œ ์ง„์งœ๋กœ, RHEL 6.5์—์„œ ๋„๋Š”(manylinux2010) pandas·scikit-learn์ด ์กด์žฌํ•˜๊ธด ํ•˜๋‚˜?"

์ด๊ฒŒ ์•ˆ ๋˜๋ฉด ์ „๋žต ์ž์ฒด๊ฐ€ ๋ฌด๋„ˆ์ง‘๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ด๊ฑธ ์ œ์ผ ๋จผ์ € ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š”์ง€๋ถ€ํ„ฐ ๋ดค์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ค‘์š”ํ•œ ์ ์€, ์ด ํ™•์ธ์€ ์œˆ๋„์šฐ ๋กœ์ปฌ์—์„œ ํ–ˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. pip download๋Š” ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜·์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ํŒŒ์ผ๋งŒ ๋‚ด๋ ค๋ฐ›๊ธฐ๋งŒ ํ•˜๊ณ , "์–ด๋–ค OS·ํŒŒ์ด์ฌ ๋ฒ„์ „์šฉ wheel์„ ๋ฐ›์„์ง€"๋ฅผ ์˜ต์…˜์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ, ์œˆ๋„์šฐ์—์„œ๋„ RHEL 6.5์šฉ ๋ฆฌ๋ˆ…์Šค wheel ํŒŒ์ผ์„ ๋ฐ›์•„๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

$ pip download --only-binary=:all: \
    --platform manylinux2010_x86_64 --platform manylinux1_x86_64 \
    --python-version 37 --implementation cp --abi cp37m \
    -d ./wheels \
    numpy==1.19.5 scipy==1.5.4 pandas==1.1.5 \
    scikit-learn==0.24.2 matplotlib==3.3.4 joblib==1.1.0 PyYAML==5.4.1

์˜ต์…˜์„ ํ’€์–ด ์ฝ์œผ๋ฉด ์ด๋ ‡์Šต๋‹ˆ๋‹ค.

  • --platform manylinux2010_x86_64 : "RHEL 6.5(CentOS 6) ํ˜ธํ™˜ wheel๋งŒ"
  • --python-version 37 : "ํŒŒ์ด์ฌ 3.7์šฉ์œผ๋กœ" (๊ตฌ๋ฒ„์ „ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋ณดํ†ต 3.7๊นŒ์ง€ manylinux2010 wheel์ด ์žˆ์Œ)
  • --only-binary=:all: : "์†Œ์Šค ๋ง๊ณ  ๋ฏธ๋ฆฌ ์ปดํŒŒ์ผ๋œ wheel๋งŒ" (ํ˜„์žฅ์—์„œ ์ปดํŒŒ์ผ ๋ชป ํ•˜๋‹ˆ๊นŒ)
  • ๋ฒ„์ „์„ ๊ตฌ๋ฒ„์ „์œผ๋กœ ์ฝ• ์ง‘์Œ (pandas 1.1.5 ๋“ฑ) — ์ตœ์‹ ์€ manylinux2014๋ผ ์•ˆ ๋˜๋‹ˆ๊นŒ

๊ฒฐ๊ณผ๋Š” ์ „๋ถ€ ๋ฐ›์•„์กŒ์Šต๋‹ˆ๋‹ค. 15๊ฐœ wheel, ํ•ฉ๊ณ„ 86MB. ํŒŒ์ผ ์ด๋ฆ„ ๋์˜ manylinux2010_x86_64·manylinux1_x86_64๊ฐ€ "RHEL 6.5์—์„œ ๋ˆ๋‹ค"๋Š” ๋ณด์ฆ์„œ์ž…๋‹ˆ๋‹ค.

numpy-1.19.5-cp37-cp37m-manylinux2010_x86_64.whl       # RHEL6.5 ํ˜ธํ™˜
scipy-1.5.4-cp37-cp37m-manylinux1_x86_64.whl           # ๋” ์˜›๋‚  ๊ธฐ์ค€์ด๋ผ ๋” ์•ˆ์ „
pandas-1.1.5-cp37-cp37m-manylinux1_x86_64.whl
scikit_learn-0.24.2-cp37-cp37m-manylinux2010_x86_64.whl
matplotlib-3.3.4-cp37-cp37m-manylinux1_x86_64.whl
...

๊ทธ๋Ÿฐ๋ฐ "๋ฐ›์•„์ง„๋‹ค"์™€ "์ง„์งœ ๋ˆ๋‹ค"๋Š” ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ, manylinux2010 ์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ ์ธํ„ฐ๋„ท์„ ๋Š๊ณ (--no-index) ์„ค์น˜ํ•˜๊ณ  import๊นŒ์ง€ ๋˜๋Š”์ง€ ๋ดค์Šต๋‹ˆ๋‹ค.

$ docker run --rm -v "$PWD/wheels:/wheels:ro" -v "$PWD:/deploy:ro" \
    quay.io/pypa/manylinux2010_x86_64 bash -c '
      cat /etc/redhat-release; ldd --version | head -1
      PY=/opt/python/cp37-cp37m/bin/python; $PY --version
      $PY -m pip install --no-index --find-links /wheels -r /deploy/requirements-rhel65.txt
      MPLBACKEND=Agg $PY -c "import numpy,scipy,pandas,sklearn,matplotlib,yaml,joblib; print(pandas.__version__)"'

๊ฒฐ๊ณผ:

CentOS release 6.10 (Final)
GLIBC: ldd (GNU libc) 2.12
Python 3.7.13
Successfully installed numpy-1.19.5 pandas-1.1.5 scikit-learn-0.24.2 ... matplotlib-3.3.4
ALL OK -> pandas 1.1.5 | sklearn 0.24.2 | numpy 1.19.5 | matplotlib 3.3.4

--no-index๋Š” "๋งˆํŠธ(์ธํ„ฐ๋„ท) ๋ฌธ์„ ์ž ๊ทธ๊ณ , ๋“ค๊ณ  ์˜จ ์žฅ๋ฐ”๊ตฌ๋‹ˆ(wheel)๋งŒ์œผ๋กœ ์š”๋ฆฌ๊ฐ€ ๋˜๋‚˜ ๋ณธ ๊ฒƒ"์ž…๋‹ˆ๋‹ค. import ์„ฑ๊ณต์€ "์žฌ๋ฃŒ๋ฅผ ์‹ค์ œ๋กœ ๋ƒ„๋น„์— ๋„ฃ์–ด๋ณด๋‹ˆ ๋ฉ€์ฉกํžˆ ์ต๋”๋ผ" — ์ฆ‰ ๋ณด๊ด€๋งŒ ๋œ ๊ฒŒ ์•„๋‹ˆ๋ผ ์ง„์งœ ์“ธ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ์ž„์„ ํ™•์ธํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

import๊ฐ€ ์ „๋ถ€ ์„ฑ๊ณตํ–ˆ๋‹ค๋Š” ๊ฑด GLIBC 2.12(=RHEL 6.5)์—์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ค์ œ๋กœ ๋กœ๋“œ๋œ๋‹ค๋Š” ์‹ค์ฆ์ž…๋‹ˆ๋‹ค. ์ด ์ž‘์—…์˜ ๊ฐ€์žฅ ํฐ ๋ถˆํ™•์‹ค์„ฑ์ด ์—ฌ๊ธฐ์„œ ํ’€๋ ธ์Šต๋‹ˆ๋‹ค.

์œˆ๋„์šฐ ๋กœ์ปฌ์—์„œ pip download๋กœ wheel์„ ๋ฐ›๊ณ , ๊ทธ๊ฒƒ์„ manylinux2010 ์ปจํ…Œ์ด๋„ˆ์— ๋„ฃ์–ด ์ธํ„ฐ๋„ท ์—†์ด ์„ค์น˜·import๊นŒ์ง€ ๊ฒ€์ฆํ•˜๋Š” ๋‹จ๊ณ„๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. "๋ฐ›๊ธฐ"์™€ "์‹ค์ œ๋กœ ๋Œ๊ธฐ"๋ฅผ ๋ถ„๋ฆฌํ•ด ํ™•์ธํ–ˆ๋‹ค๋Š” ์ ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.


3. ๋ฒˆ๋“ค ์กฐ๋ฆฝ๊ณผ ์ฒซ ํ•จ์ •: ์‹ฌ๋ณผ๋ฆญ ๋งํฌ

์ด์ œ ์‹ค์ œ๋กœ ํ•œ ๋ฉ์–ด๋ฆฌ๋กœ ๋ฌถ์„ ์ฐจ๋ก€์ž…๋‹ˆ๋‹ค. ์ฒ˜์Œ์—” ๋‹จ์ˆœํ•˜๊ฒŒ "๋„์ปค ์•ˆ Python ํด๋”๋ฅผ ๋ณต์‚ฌํ•˜๋ฉด ๋˜๊ฒ ์ง€" ํ–ˆ์Šต๋‹ˆ๋‹ค.

cp -r /opt/python/cp37-cp37m  $BUNDLE/python

๊ทธ๋Ÿฐ๋ฐ ๋ฒˆ๋“ค์ด 196KB๋ฐ–์— ์•ˆ ๋์Šต๋‹ˆ๋‹ค. Python ํ•˜๋‚˜๊ฐ€ ์ˆ˜์‹ญ MB์ผ ํ…๋ฐ ์ด์ƒํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธํ•ด๋ณด๋‹ˆ /opt/python/cp37-cp37m์€ ์‹ค์ œ Python์ด ์•„๋‹ˆ๋ผ ๋งํฌ ๋ชจ์Œ์ด์—ˆ๊ณ , ์ง„์งœ Python์€ ๋‹ค๋ฅธ ๊ณณ์— ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

$ readlink -f /opt/python/cp37-cp37m/bin/python3.7
/opt/_internal/cpython-3.7.13/bin/python3.7      # ์ง„์งœ๋Š” ์—ฌ๊ธฐ (68MB)

๋” ๊ณ ์•ฝํ•œ ๊ฑด, ์ฒซ "์žฌ๋ฐฐ์น˜ ๊ฒ€์ฆ"์ด ๊ฑฐ์ง“์œผ๋กœ ํ†ต๊ณผํ–ˆ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋ณต์‚ฌ๋ณธ์ด ๋งํฌ๋ผ, ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— ๋‚จ์•„์žˆ๋˜ ์›๋ณธ์„ ๋”ฐ๋ผ๊ฐ€์„œ import๊ฐ€ ๋๋˜ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋ชฉ์ ์ง€(RHEL 6.5)์—” ์›๋ณธ์ด ์—†์œผ๋‹ˆ ์‹ค์ œ๋ก  ์•ˆ ๋์„ ์ƒํ™ฉ์ž…๋‹ˆ๋‹ค.

๋ƒ‰์žฅ๊ณ ๋ฅผ ํ†ต์งธ๋กœ ์˜ฎ๊ธด ์ค„ ์•Œ์•˜๋Š”๋ฐ, ์•Œ๊ณ  ๋ณด๋‹ˆ ์˜ฎ๊ธด ๊ฑด "๋ƒ‰์žฅ๊ณ ๋Š” ์ €์ชฝ์— ์žˆ์Œ"์ด๋ผ๊ณ  ์ ํžŒ ์ชฝ์ง€(๋งํฌ)์˜€์Šต๋‹ˆ๋‹ค. ์ง„์งœ ๋ƒ‰์žฅ๊ณ (์›๋ณธ Python)๋Š” ์›๋ž˜ ๋ฐฉ์— ๊ทธ๋Œ€๋กœ ์žˆ์–ด์„œ, ๊ทธ ๋ฐฉ ์•ˆ์—์„œ ํ…Œ์ŠคํŠธํ•˜๋ฉด ์ž˜ ๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค(๊ฑฐ์ง“ ํ†ต๊ณผ). ์ชฝ์ง€๋งŒ ๋“ค๊ณ  ์˜ค๋‘๋ง‰์— ๊ฐ€๋ฉด ๋ƒ‰์žฅ๊ณ ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

cp -r๋กœ ์˜ฎ๊ธด ๊ฒƒ์ด ์‹ค์ œ ํŒŒ์ผ์ด ์•„๋‹ˆ๋ผ ์›๋ณธ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋งํฌ์˜€๊ณ , ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ ์•ˆ์— ์›๋ณธ์ด ๋‚จ์•„ ์žˆ์–ด ํ…Œ์ŠคํŠธ๊ฐ€ ํ†ต๊ณผํ•œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์˜€๋˜ ์ƒํ™ฉ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋ชฉ์ ์ง€์—” ์›๋ณธ์ด ์—†์œผ๋ฏ€๋กœ ์‹ค์ œ๋กœ๋Š” ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ ์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

๊ตํ›ˆ์€ ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. โ‘  ์ง„์งœ Python(/opt/_internal/cpython-3.7.13)์„ ๋ณต์‚ฌํ•  ๊ฒƒ โ‘ก ๊ฒ€์ฆ์€ "์›๋ณธ์„ ๋‹ค ์น˜์šด ์ƒํƒœ"๋กœ ํ•ด์•ผ ์ง„์งœ๋‹ค.


4. ๊ฐ™์ด ๋‹ด์•„์•ผ ํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฐพ๊ธฐ (ldd)

Python์„ ์ œ๋Œ€๋กœ ๋ณต์‚ฌํ–ˆ์–ด๋„ ๋์ด ์•„๋‹™๋‹ˆ๋‹ค. Python ๋ฐ”์ด๋„ˆ๋ฆฌ์™€ ํ‘œ์ค€ ํ™•์žฅ ๋ชจ๋“ˆ์ด ์˜์กดํ•˜๋Š” ๊ณต์œ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(.so) ์ค‘ RHEL 6.5์— ์—†๋Š” ๊ฒƒ์ด ์žˆ์œผ๋ฉด ์‹คํ–‰ ์‹œ ์ฃฝ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ldd๋กœ ์˜์กด์„ฑ์„ ํ›‘์–ด, ํ‘œ์ค€ ์‹œ์Šคํ…œ ๊ฒฝ๋กœ(/lib64·/usr/lib64) ๋ฐ”๊นฅ์—์„œ ์˜ค๋Š” ๊ฒƒ์„ ์ฐพ์•˜์Šต๋‹ˆ๋‹ค.

$ { ldd .../python3.7; find . -name "*.so*" -exec ldd {} \; ; } \
    | grep -E '=> (/usr/local|/opt)'
libcrypt.so.2   => /usr/local/lib/libcrypt.so.2     # libxcrypt, 198KB
libsqlite3.so.0 => /usr/local/lib/libsqlite3.so.0   # 1.2MB

๋”ฑ ๋‘ ๊ฐœ์˜€์Šต๋‹ˆ๋‹ค. ์ด ๋‘˜๋งŒ ๋ฒˆ๋“ค์— ๊ฐ™์ด ๋„ฃ๊ณ , ์‹คํ–‰ํ•  ๋•Œ LD_LIBRARY_PATH๋กœ ์žก์•„์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

ํœด๋Œ€์šฉ ๋ถ€์—Œ(Python)์ด ํŠน์ˆ˜ ์ฝ˜์„ผํŠธ ๋‘ ๊ฐœ(libcrypt·libsqlite3)๊ฐ€ ์žˆ์–ด์•ผ ๋„๋Š”๋ฐ, ๋‚ก์€ ์˜ค๋‘๋ง‰์—” ๊ทธ ์ฝ˜์„ผํŠธ๊ฐ€ ์—†์–ด ์–ด๋Œ‘ํ„ฐ ๋‘ ๊ฐœ๋„ ๋ฐ•์Šค์— ๊ฐ™์ด ์ฑ™๊ธฐ๋Š” ์…ˆ์ž…๋‹ˆ๋‹ค.

๋‚˜๋จธ์ง€๋Š” ์–ด๋–ป๊ฒŒ ์ž๊ธ‰๋˜๋Š”์ง€๋„ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

  • numpy·scipy·matplotlib·Pillow์˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(openblas·libpng ๋“ฑ): manylinux wheel์ด ํŒจํ‚ค์ง€ ์•ˆ *.libs/ ํด๋”์— ์ž์ฒด ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. → ๋ฒˆ๋“ค์— ๊ทธ๋Œ€๋กœ ๋”ฐ๋ผ์˜ต๋‹ˆ๋‹ค(์ž๊ธ‰).
  • openssl(_ssl·_hashlib): manylinux Python์€ openssl์„ ์ •์  ๋งํฌํ•ฉ๋‹ˆ๋‹ค(ldd์— libssl ์—†์Œ, ssl.OPENSSL_VERSION์ด ํ‘œ์‹œ๋จ). → ์™ธ๋ถ€ openssl ๋ถˆํ•„์š”(์ž๊ธ‰).

openssl์€ "๋ฐฐํ„ฐ๋ฆฌ ๋‚ด์žฅํ˜• ๋„๊ตฌ"๋ผ ์ฝ˜์„ผํŠธ๊ฐ€ ํ•„์š” ์—†๊ณ , numpy·matplotlib ๊ฐ™์€ ์žฌ๋ฃŒ๋Š” "์ž๊ธฐ ์–‘๋…์„ ํ†ต์งธ๋กœ ๋“ค๊ณ  ๋‹ค๋‹ˆ๋Š”" ์…ˆ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋ฐ•์Šค ๋ฐ–์—์„œ ๋” ์ฑ™๊ธธ ๊ฒŒ ๋”ฑ ๋‘ ๊ฐœ๋ฟ์ด์—ˆ์Šต๋‹ˆ๋‹ค.

์ด์ œ ๋ฒˆ๋“ค์„ ์กฐ๋ฆฝํ•ฉ๋‹ˆ๋‹ค(์ปจํ…Œ์ด๋„ˆ ์•ˆ์—์„œ).

B=/work/db_ai_bundle
cp -r /opt/_internal/cpython-3.7.13  $B/python                 # ์ง„์งœ Python
mkdir $B/python/lib_extra
cp -P /usr/local/lib/libcrypt.so.2* libsqlite3.so.0* $B/python/lib_extra/   # ๋น„ํ‘œ์ค€ .so 2์ข…
$B/python/bin/python3.7 -m pip install --no-index --find-links /wheels -r requirements.txt
cp app/*.py app/config.yaml $B/app/ ; cp -r models $B/app/models   # ์•ฑ ์ฝ”๋“œ+๋ชจ๋ธ
cp run.sh $B/ ; tar czf bundle.tar.gz db_ai_bundle                # ์••์ถ•

run.sh๋Š” ๋ฒˆ๋“ค ์•ˆ Python์œผ๋กœ ์•ฑ์„ ์‹คํ–‰ํ•˜๋Š” ๋Ÿฐ์ฒ˜์ž…๋‹ˆ๋‹ค. ๋™๋ด‰ํ•œ .so ๋‘ ๊ฐœ๋ฅผ ์ฐพ๋„๋ก LD_LIBRARY_PATH๋ฅผ ์žก์•„์ค๋‹ˆ๋‹ค.

#!/bin/bash
DIR="$(cd "$(dirname "$0")" && pwd)"
export LD_LIBRARY_PATH="$DIR/python/lib_extra:$LD_LIBRARY_PATH"
cd "$DIR/app"
exec "$DIR/python/bin/python3.7" main.py "$@"

 

๋ฒˆ๋“ค ํ•œ ๋ฉ์–ด๋ฆฌ ์•ˆ์— Python ์‹คํ–‰๊ธฐ์™€ ๋™๋ด‰ํ•œ ๋น„ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(lib_extra), ์•ฑ ์ฝ”๋“œ์™€ ๋ชจ๋ธ, ์‹คํ–‰ ๋Ÿฐ์ฒ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ๋“ค์–ด๊ฐ€๋Š”์ง€ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋ฐ•์Šค ๋ฐ–์—์„œ ๋”ฐ๋กœ ์ฑ™๊ธธ ๊ฒƒ์ด ๋น„ํ‘œ์ค€ .so ๋‘ ๊ฐœ๋ฟ์ด๋ผ๋Š” ์ ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

๊ฒฐ๊ณผ๋Š” ๋ฒˆ๋“ค ํด๋” ์•ฝ 414MB, ์••์ถ•๋ณธ tar.gz ์•ฝ 124MB์˜€์Šต๋‹ˆ๋‹ค.


5. ์ง„์งœ ๊ฒ€์ฆ: ๊นจ๋—ํ•œ ํ™˜๊ฒฝ์—์„œ ์ž๊ธ‰์ž์กฑ

3์žฅ์˜ ๊ตํ›ˆ๋Œ€๋กœ, ๊ฒ€์ฆ์€ "์›๋ณธ์„ ๋‹ค ์น˜์šด ์ƒํƒœ"๋กœ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฒ˜์Œ์—” ์ง„์งœ RHEL 6.5์— ๊ฐ€๊นŒ์šด CentOS 6 ๋„์ปค ์ด๋ฏธ์ง€(centos:6)๋กœ ํ’€์–ด๋ณด๋ ค ํ–ˆ์Šต๋‹ˆ๋‹ค.

$ docker run --rm centos:6 bash -c 'cat /etc/redhat-release; ...'
$ echo $?
139      # ์„ธ๊ทธํดํŠธ

์ข…๋ฃŒ์ฝ”๋“œ 139๋Š” ์„ธ๊ทธํดํŠธ์ž…๋‹ˆ๋‹ค. CentOS 6 ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ตœ์‹  ์ปค๋„์—์„œ ๋ชป ๋„๋Š” ์•Œ๋ ค์ง„ ๋ฌธ์ œ(vsyscall)์ž…๋‹ˆ๋‹ค. CentOS 6 ์ด๋ฏธ์ง€ ์ž์ฒด๋ฅผ ํ…Œ์ŠคํŠธ ๋ฒ ๋“œ๋กœ ์“ธ ์ˆ˜ ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

๋Œ€์‹ , ์ด๋ฏธ ์ž˜ ๋„๋Š” manylinux2010(๊ฐ™์€ GLIBC 2.12) ์•ˆ์—์„œ manylinux ์ „์šฉ ๊ฒฝ๋กœ๋ฅผ ์ˆจ๊ฒจ RHEL 6.5๋ฅผ ์žฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค.

mv /opt/_internal /opt/_internal_HIDDEN        # ์›๋ณธ Python ์น˜์›€
mv /usr/local/lib /usr/local/lib_HIDDEN        # ๋น„ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถœ์ฒ˜ ์น˜์›€
cd /tmp/db_ai_bundle ; export LD_LIBRARY_PATH=$PWD/python/lib_extra
ldd python/bin/python3.7 | grep 'not found'    # ๋ฏธํ•ด๊ฒฐ ์—†์Œ ํ™•์ธ
./python/bin/python3.7 importtest.py

๊ฒฐ๊ณผ:

๋ฏธํ•ด๊ฒฐ(not found) ์—†์Œ
Python 3.7.13
FULL import OK
  pandas 1.1.5 | sklearn 0.24.2 | numpy 1.19.5 | matplotlib 3.3.4
  ssl: OpenSSL 1.1.1q | sqlite3: 3.39.2

์›๋ณธ Python๊ณผ ๋น„ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ๋‹ค ์น˜์šด ์ƒํƒœ์—์„œ, ๋ฒˆ๋“ค ์ž์ฒด ์ž์›๋งŒ์œผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ‘œ์ค€ ๋ชจ๋“ˆ(ssl·sqlite3 ๋“ฑ)๊นŒ์ง€ ์ „๋ถ€ ๋กœ๋“œ๋์Šต๋‹ˆ๋‹ค. GLIBC 2.12์—์„œ ์ž๊ธ‰์ž์กฑ์œผ๋กœ ๋„๋Š” ๊ฒƒ์„ ์‹ค์ฆํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋นŒ๋“œ ํ™˜๊ฒฝ์— ๋‚จ์•„ ์žˆ๋˜ ์›๋ณธ Python·๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฒฝ๋กœ๋ฅผ ์ผ๋ถ€๋Ÿฌ ์น˜์šฐ๊ณ (์ˆจ๊ธฐ๊ณ ), ๋ฒˆ๋“ค ์•ˆ์˜ ์ž์›๋งŒ์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. "๋ฐ•์Šค ๋ฐ– ๋„์›€ ์—†์ด ๋์œผ๋‹ˆ ์ง„์งœ ์˜ค๋‘๋ง‰์—์„œ๋„ ๋œ๋‹ค"๋Š” ๋…ผ๋ฆฌ๋ฅผ ์‹œ๊ฐํ™”ํ•ฉ๋‹ˆ๋‹ค.


6. ์•ฑ์ด ๋๊นŒ์ง€ ๋„๋Š”๊ฐ€ (e2e)

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋กœ๋“œ๋ฟ ์•„๋‹ˆ๋ผ, ์šฐ๋ฆฌ ์•ฑ์ด ์ด ๊ตฌ๋ฒ„์ „ ์Šคํƒ(Python 3.7·pandas 1.1.5)์—์„œ ๋๊นŒ์ง€ ๋„๋Š”์ง€๋„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ๋Š” ์ตœ์‹ (Python 3.12)์—์„œ ์งฐ์œผ๋‹ˆ, ๊ตฌ๋ฒ„์ „์—์„œ ๊นจ์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ € ๋ฌธ๋ฒ•๋ถ€ํ„ฐ ๋ดค์Šต๋‹ˆ๋‹ค. ์ฝ”๋“œ๊ฐ€ 3.8 ์ด์ƒ ์ „์šฉ ๋ฌธ๋ฒ•(walrus := ๋“ฑ)์„ ์“ฐ๋ฉด 3.7์—์„œ ์•„์˜ˆ ์ปดํŒŒ์ผ์ด ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

$ for f in *.py; do python3.7 -m py_compile "$f"; done
# ์ „์ฒด ํ†ต๊ณผ — 3.8+ ๋ฌธ๋ฒ• ์•ˆ ์”€

๋‹ค์Œ์œผ๋กœ ์‹ค์ œ ํŒŒ์ดํ”„๋ผ์ธ์ž…๋‹ˆ๋‹ค. ํ˜„์žฅ๊ณผ ๊ฐ™์€ ๊ฒฝ๋กœ(API์—์„œ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘)๋ฅผ ์žฌํ˜„ํ•˜๋ ค๊ณ , ๋ฐ์ดํ„ฐ๋ฅผ API ํ˜•ํƒœ๋กœ ์„œ๋น™ํ•˜๋Š” ๋ชจ์˜ ์„œ๋ฒ„๋ฅผ ๋„์šฐ๊ณ , ๋ฒˆ๋“ค์ด ๊ทธ๊ฑธ ํ˜ธ์ถœํ•˜๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ์ž‘์€ ํ•จ์ •์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

urllib.error.HTTPError: HTTP Error 404: Not Found

์—ฐ๊ฒฐ์€ ๋๋Š”๋ฐ 404์˜€์Šต๋‹ˆ๋‹ค. ์ˆ˜์ง‘ ๋ชจ๋“ˆ์ด base_url + "/data/metrics" ๋กœ ํ˜ธ์ถœํ•˜๋Š”๋ฐ, base_url์— API ๊ฒฝ๋กœ ์ผ๋ถ€(/v1 ๋“ฑ)๊ฐ€ ๋น ์ ธ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ฒฝ๋กœ๋ฅผ ๋งž์ถ”๋‹ˆ ํ†ต๊ณผํ–ˆ์Šต๋‹ˆ๋‹ค.

์ˆ˜์ง‘ ์™„๋ฃŒ: 3๊ฐœ DB
[mysql] ๋“ฑ๊ธ‰=warning ์ด์ƒ=1๊ฑด
[oracle] ๋“ฑ๊ธ‰=warning ์ด์ƒ=1๊ฑด
[postgresql] ๋“ฑ๊ธ‰=warning ์ด์ƒ=2๊ฑด
๋ฆฌํฌํŠธ HTML ์ €์žฅ: report.html
์™„๋ฃŒ.

๋ฒˆ๋“ค Python์œผ๋กœ ์ˆ˜์ง‘ → ์ด์ƒ ํƒ์ง€ → ๋ฆฌํฌํŠธ ์ƒ์„ฑ๊นŒ์ง€ ์—๋Ÿฌ ์—†์ด ์™„์ฃผํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ตฌ๋ฒ„์ „ ์Šคํƒ์—์„œ ์•ฑ์ด ์ •์ƒ ๋™์ž‘ํ•จ์„ ์‹ค์ฆํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ๋ฅผ API ํ˜•ํƒœ๋กœ ๋‚ด๋ณด๋‚ด๋Š” ๋ชจ์˜ ์„œ๋ฒ„์™€, ๊ทธ๊ฒƒ์„ ํ˜ธ์ถœํ•ด ์ˆ˜์ง‘→ํƒ์ง€→๋ฆฌํฌํŠธ๊นŒ์ง€ ๋„๋Š” ๋ฒˆ๋“ค์˜ ์—ฐ๊ฒฐ ๊ตฌ์กฐ๋ฅผ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ํ˜„์žฅ(์‹ค์ œ API)๊ณผ ๊ฐ™์€ ํ˜ธ์ถœ ๊ฒฝ๋กœ๋กœ ๊ฒ€์ฆํ–ˆ๋‹ค๋Š” ์ ์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.


7. ๋ชจ๋ธ ์žฌํ•™์Šต: ๋ฒ„์ „ ์‚ผ๊ฐ๊ด€๊ณ„

์ด์ƒ ํƒ์ง€์—๋Š” ๋ฏธ๋ฆฌ ํ•™์Šตํ•œ ๋ชจ๋ธ์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ๋ฐ ์ด ๋ชจ๋ธ์€ ๋ฒˆ๋“ค์˜ scikit-learn ๋ฒ„์ „(0.24.2)์œผ๋กœ ํ•™์Šตํ•ด์•ผ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ๋ชจ๋ธ์€ ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ํ•™์Šต๋ผ ์žˆ์–ด ์•ˆ ๋งž์Šต๋‹ˆ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ ํ•™์Šต ์ฝ”๋“œ๋Š” ์—‘์…€์„ ์ฝ์–ด์•ผ ํ•˜๊ณ , ์—‘์…€ ์ฝ๊ธฐ์— ์“ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์‹ ๋ฒ„์ „ pandas(2.2+)์—์„œ๋งŒ ๋˜๋Š” ์—”์ง„์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ฆ‰:

  • ์—‘์…€ ์ฝ๊ธฐ = ์‹ ๋ฒ„์ „ pandas ํ•„์š”
  • ๋ชจ๋ธ ํ•™์Šต = ๊ตฌ๋ฒ„์ „ scikit-learn ํ•„์š”
  • ๊ทธ๋Ÿฐ๋ฐ ์‹ ๋ฒ„์ „ pandas์™€ ๊ตฌ๋ฒ„์ „ scikit-learn์€ numpy ์š”๊ตฌ ๋ฒ„์ „์ด ์ถฉ๋Œํ•ด ํ•œ ํ™˜๊ฒฝ์— ๊ฐ™์ด ๋ชป ๋‘ 

"์žฌ๋ฃŒ๋ฅผ ๋‹ค๋“ฌ๋Š” ์นผ(์—‘์…€ ์ฝ๊ธฐ)"์€ ์ตœ์‹  ๋„๋งˆ(์‹  pandas)์—์„œ๋งŒ ๋งž๊ณ , "์š”๋ฆฌ๋ฒ•(๊ตฌ scikit-learn)"์€ ์˜›๋‚  ์ฃผ๋ฐฉ์—์„œ๋งŒ ๋ฉ๋‹ˆ๋‹ค. ๋‘˜์„ ํ•œ ์ฃผ๋ฐฉ์— ๋ชป ๋‘ก๋‹ˆ๋‹ค.

์—‘์…€ ์ฝ๊ธฐ์— ํ•„์š”ํ•œ ์‹ ๋ฒ„์ „ pandas์™€ ๋ชจ๋ธ ํ•™์Šต์— ํ•„์š”ํ•œ ๊ตฌ๋ฒ„์ „ scikit-learn์ด numpy ์š”๊ตฌ ๋ฒ„์ „ ๋•Œ๋ฌธ์— ํ•œ ํ™˜๊ฒฝ์— ๊ณต์กดํ•  ์ˆ˜ ์—†๋Š” ๊ตฌ์กฐ๋ฅผ ์‚ผ๊ฐํ˜•์œผ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ "์ฝ๊ธฐ ๋ฐฉ์‹๋งŒ ๋ฐ”๊ฟ”" ์šฐํšŒํ•œ ๋ฐฐ๊ฒฝ์ด ๋“œ๋Ÿฌ๋‚ฉ๋‹ˆ๋‹ค.

ํ•ด๊ฒฐ์€, ํ•™์Šตํ•  ๋•Œ๋งŒ ์—‘์…€ ์ฝ๊ธฐ ๋ฐฉ์‹์„ ๋ฒ„์ „ ๋ฌด๊ด€ํ•œ ๋ฐฉ๋ฒ•์œผ๋กœ ๋ฐ”๊ฟ”์น˜๊ธฐ(๋Ÿฐํƒ€์ž„ ๋ชฝํ‚คํŒจ์น˜) ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์›๋ณธ ์ฝ”๋“œ๋Š” ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ , ํ•™์Šต ๋“œ๋ผ์ด๋ฒ„์—์„œ๋งŒ ์—‘์…€ ์ฝ๊ธฐ ํ•จ์ˆ˜๋ฅผ ๊ต์ฒดํ–ˆ์Šต๋‹ˆ๋‹ค.

# ์ผํšŒ์„ฑ ํ•™์Šต ๋“œ๋ผ์ด๋ฒ„ (์›๋ณธ ์ฝ”๋“œ ๋ฌด์ˆ˜์ •)
from python_calamine import get_sheet_data
import collector

def _read_compat(path):
    rows = get_sheet_data(path, 0)          # ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ง์ ‘ ํ˜ธ์ถœ (pandas ๋ฒ„์ „ ๋ฌด๊ด€)
    ...                                      # DataFrame์œผ๋กœ ๋ณ€ํ™˜

collector.ExcelMetricSource._read_series = staticmethod(_read_compat)

import train; train.main()                   # ๊ฐ™์€ ๋ฒ„์ „(scikit-learn 0.24.2)์œผ๋กœ ํ•™์Šต

๋ฒˆ๋“ค๊ณผ ๊ฐ™์€ ๋ฒ„์ „(Python 3.7 + scikit-learn 0.24.2)์„ ๊น ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ด ๋“œ๋ผ์ด๋ฒ„๋กœ ํ•™์Šตํ•ด, ๋ชจ๋ธ ์„ธ ๊ฐœ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ๋ฒˆ๋“ค์˜ scikit-learn์œผ๋กœ ๊ทธ๋Œ€๋กœ ๋กœ๋“œ๋ฉ๋‹ˆ๋‹ค.


8. ๋งˆ์ง€๋ง‰ ํ•œ ๊ฑธ์Œ: ํ•œ๊ธ€ ํฐํŠธ

ML๊นŒ์ง€ ์ผœ๊ณ  ๋‹ค์‹œ ๋Œ๋ฆฌ๋‹ˆ ๊ทธ๋ž˜ํ”„ ์„ธ ๊ฐœ๊ฐ€ ๋‚˜์™”๋Š”๋ฐ, ๊ฒฝ๊ณ ๊ฐ€ ๋–ด์Šต๋‹ˆ๋‹ค.

RuntimeWarning: Glyph 54588 missing from current font.

๊ทธ๋ž˜ํ”„์˜ ํ•œ๊ธ€์ด โ–ก๋กœ ๋‚˜์˜ค๋Š” ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค. ํ์‡„๋ง ์„œ๋ฒ„์—๋Š” ํ•œ๊ธ€ ํฐํŠธ๊ฐ€ ์—†์–ด์„œ์ž…๋‹ˆ๋‹ค. ํ‰์†Œ ๊ฐ™์œผ๋ฉด apt install fonts-nanum์œผ๋กœ ๊น”๊ฒ ์ง€๋งŒ, ํ์‡„๋ง์ด๋ผ ์„ค์น˜ ๋Œ€์‹  ๋ฒˆ๋“ค์— ํฐํŠธ๋ฅผ ๋™๋ด‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋‹คํ–‰ํžˆ ๋ฆฌํฌํŠธ ์ฝ”๋“œ๊ฐ€ ํฐํŠธ๋ฅผ ์ž๋™ ์„ ํƒํ•  ๋•Œ ํ›„๋ณด ๋ชฉ๋ก์—์„œ "NanumGothic"์„ ์ฐพ๋„๋ก ๋ผ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ NanumGothic.ttf๋ฅผ ๋ฒˆ๋“ค์˜ matplotlib ํฐํŠธ ํด๋”์— ๋„ฃ๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์ฝ”๋“œ ์ˆ˜์ •์€ ํ•„์š” ์—†์—ˆ์Šต๋‹ˆ๋‹ค.

# ๋ฒˆ๋“ค์˜ matplotlib ํฐํŠธ ํด๋”์— ํ•œ๊ธ€ ํฐํŠธ ๋™๋ด‰
cp NanumGothic.ttf  $B/python/lib/python3.7/site-packages/matplotlib/mpl-data/fonts/ttf/

๋‹ค์‹œ ๊ฒ€์ฆํ•˜๋‹ˆ ํฐํŠธ ์ธ์‹ True, "Glyph missing" ๊ฒฝ๊ณ  0, ๊ทธ๋ž˜ํ”„ ์„ธ ๊ฐœ๊ฐ€ ํ•œ๊ธ€๊นŒ์ง€ ์ •์ƒ์œผ๋กœ ๋‚˜์™”์Šต๋‹ˆ๋‹ค.


9. ๊ฒฐ๊ณผ

์ตœ์ข… ์‚ฐ์ถœ๋ฌผ์€ ์•ฝ 124MB์˜ tar.gz ํ•œ ๊ฐœ์ž…๋‹ˆ๋‹ค. RHEL 6.5์—์„œ ์ธํ„ฐ๋„ท·์‹œ์Šคํ…œ ํŒŒ์ด์ฌ ์—†์ด ํ’€์–ด์„œ ์‹คํ–‰ํ•˜๋ฉด, ์ˆ˜์ง‘๋ถ€ํ„ฐ ํ•œ๊ธ€ ๊ทธ๋ž˜ํ”„๊ฐ€ ํฌํ•จ๋œ ๋ฆฌํฌํŠธ ์ƒ์„ฑ๊นŒ์ง€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.

์ •๋ฆฌํ•˜๋ฉด, ์ด๋ฒˆ ์ž‘์—…์€ "๋ฐ›์•„์ง„๋‹ค"์—์„œ ์‹œ์ž‘ํ•ด ๋‹ค์Œ ์ˆœ์„œ๋กœ ํ™•์‹ ์„ ์Œ“์•„๊ฐ„ ๊ณผ์ •์ด์—ˆ์Šต๋‹ˆ๋‹ค.

  1. RHEL 6.5 ํ˜ธํ™˜ wheel์ด ์กด์žฌํ•˜๋Š”๊ฐ€ → pip download๋กœ ํ™•์ธ
  2. ๊ทธ ์•ˆ์—์„œ import ๋˜๋Š”๊ฐ€ → --no-index ์„ค์น˜·import๋กœ ํ™•์ธ
  3. ๋ฒˆ๋“ค์ด ์ž๊ธ‰์ž์กฑ์ธ๊ฐ€ → ์›๋ณธ ๊ฒฝ๋กœ๋ฅผ ๋‹ค ์น˜์šด ์ƒํƒœ์—์„œ ํ™•์ธ
  4. ์•ฑ์ด ๋๊นŒ์ง€ ๋„๋Š”๊ฐ€ → ๋ชจ์˜ API๋กœ e2e ํ™•์ธ
  5. ๋ชจ๋ธ·๊ทธ๋ž˜ํ”„ ํ•œ๊ธ€๊นŒ์ง€ → ์žฌํ•™์Šต·ํฐํŠธ ๋™๋ด‰์œผ๋กœ ํ™•์ธ

๊ฐ ๋‹จ๊ณ„์—์„œ "๋˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๋Š” ๊ฒƒ"๊ณผ "์ง„์งœ ๋˜๋Š” ๊ฒƒ"์„ ๊ตฌ๋ถ„ํ•˜๋Š” ๊ฒŒ ํ•ต์‹ฌ์ด์—ˆ์Šต๋‹ˆ๋‹ค(์‹ฌ๋ณผ๋ฆญ ๋งํฌ ๊ฑฐ์ง“ ํ†ต๊ณผ๊ฐ€ ๋Œ€ํ‘œ์ ์ž…๋‹ˆ๋‹ค).


๋ถ€๋ก: ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ… ์š”์•ฝ

์ฆ์ƒ ์›์ธ ํ•ด๊ฒฐ
๋ฒˆ๋“ค์ด 196KB๋กœ ๋‚˜์˜ด /opt/python์ด ์‹ฌ๋ณผ๋ฆญ ๋งํฌ ์ง„์งœ Python(/opt/_internal/...) ๋ณต์‚ฌ
์žฌ๋ฐฐ์น˜ ๊ฒ€์ฆ์ด ํ†ต๊ณผํ•˜๋Š”๋ฐ ๋ฏธ์‹ฌ์ฉ์Œ ์›๋ณธ์ด ๊ฐ™์€ ์ปจํ…Œ์ด๋„ˆ์— ๋‚จ์•„ ๊ฑฐ์ง“ ํ†ต๊ณผ ์›๋ณธ ๊ฒฝ๋กœ๋ฅผ ์น˜์šด ์ƒํƒœ์—์„œ ์žฌ๊ฒ€์ฆ
์‹คํ–‰ ์‹œ .so ๋ชป ์ฐพ์„ ์œ„ํ—˜ RHEL 6.5์— ์—†๋Š” libcrypt·libsqlite3 ์˜์กด ๋‘ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋™๋ด‰ + LD_LIBRARY_PATH
centos:6 ์ปจํ…Œ์ด๋„ˆ ์„ธ๊ทธํดํŠธ(139) ์ตœ์‹  ์ปค๋„ vsyscall ๋น„ํ˜ธํ™˜ manylinux2010์—์„œ ๊ฒฝ๋กœ ์ˆจ๊ฒจ RHEL 6.5 ์žฌํ˜„
๋ชจ์˜ API ํ˜ธ์ถœ 404 base_url์— API ๊ฒฝ๋กœ ์ผ๋ถ€ ๋ˆ„๋ฝ ๊ฒฝ๋กœ๋ฅผ ๋งž์ถฐ ํ˜ธ์ถœ
๋ชจ๋ธ ๋กœ๋“œ ๋ฒ„์ „ ๋ถˆ์ผ์น˜ ์‹  pandas์™€ ๊ตฌ scikit-learn ๊ณต์กด ๋ถˆ๊ฐ€ ์—‘์…€ ์ฝ๊ธฐ๋งŒ ๋Ÿฐํƒ€์ž„ ๊ต์ฒดํ•ด ๊ฐ™์€ ๋ฒ„์ „์œผ๋กœ ํ•™์Šต
๊ทธ๋ž˜ํ”„ ํ•œ๊ธ€์ด โ–ก ์„œ๋ฒ„์— ํ•œ๊ธ€ ํฐํŠธ ์—†์Œ NanumGothic.ttf๋ฅผ ๋ฒˆ๋“ค์— ๋™๋ด‰