نحوه کانتینرایز کردن برنامههای وب پایتون #
مقدمه #
کانتینریزه کردن برنامههای وب پایتون، ساختار برنامه و وابستگیهای آن را در یک بسته واحد کپسوله میکند تا از استقرارهای سازگار و قابل تکرار در محیطهای مختلف اطمینان حاصل شود. استقرار برنامههای وب پایتون کانتینریزه شده، یک رویکرد اساسی برای توسعه نرمافزار مدرن است که شامل مقیاسبندی و اتوماسیون هنگام استقرار در پلتفرمهایی مانند Kubernetes میشود.
شما میتوانید برنامههای پایتون را با استفاده از چارچوبهای توسعه مختلف بسازید. هر پلتفرم ممکن است به رویکردی کمی متفاوت برای کانتینر کردن و ارسال تصویر برنامه نیاز داشته باشد. چارچوبهای محبوب پایتون عبارتند از:
- Flask : یک چارچوب وب سبک و انعطافپذیر که ابزارهای ضروری برای ساخت برنامههای وب را فراهم میکند. این چارچوب مینیمالیستی است و ابزارهای مستقیمی ارائه میدهد که به توسعهدهندگان اجازه میدهد کتابخانهها را بر اساس نیازهای خاص پروژه اضافه کنند.
- جنگو : یک چارچوب وب فولاستک سطح بالا که مجموعهای کامل از ابزارها و کتابخانهها را برای ساخت برنامههای وب قوی فراهم میکند.
- FastAPI : یک چارچوب وب مدرن و با کارایی بالا برای ساخت APIها با پایتون. این چارچوب از type hints برای فعال کردن مستندسازی API تعاملی خودکار (با استفاده از Swagger UI) استفاده میکند و با استفاده از سیستم نوع پایتون، کارایی بالایی را ارائه میدهد.
- Pyramid : یک چارچوب انعطافپذیر و مقیاسپذیر که به توسعهدهندگان اجازه میدهد اجزای مورد نیاز برای برنامههای خود را انتخاب کنند.
- Tornado : یک کتابخانه شبکه ناهمزمان و چارچوب وب که در درجه اول به دلیل عملکرد بالا و توانایی مدیریت بسیاری از اتصالات همزمان شناخته شده است.
این مقاله نحوه کانتینرایز کردن برنامههای وب پایتون برای استقرار در محیطهای عملیاتی مانند کلاسترهای Kubernetes را توضیح میدهد.
پیش نیازها #
قبل از شروع:
- یک کلاستر Kubernetes Engine (VKE) را برای استفاده به عنوان پلتفرم استقرار در محیط عملیاتی، مستقر کنید.
- برای ذخیره تصویر برنامه پایتون، یک رجیستری کانتینر ایجاد کنید.
- یک داکر برای استفاده به عنوان ایستگاه کاری مدیریت نصب کنید.
- با استفاده از SSH به عنوان یک کاربر غیر ریشه با امتیازات sudo به ایستگاه کاری دسترسی پیدا کنید .
- Kubectl را برای دسترسی به کلاستر نصب و پیکربندی کنید .
- برای نصب برنامههای خوشهای اضافی، ابزار Helm CLI را نصب کنید.console
$ sudo snap install helm --classic
ایجاد یک برنامه وب پایتون #
برای ایجاد یک تصویر ثابت از برنامه وب پایتون که بتوانید با چارچوبهای مختلفی مانند Flask یا Django از آن استفاده کنید، کد خود را طوری ساختار دهید که منطق رابط کاربری HTTP سرور frontend از منطق اصلی برنامه جدا باشد. مراحل زیر را برای ایجاد یک برنامه پایه پایتون با استفاده app.pyاز فایل اصلی برنامه و استفاده از یک server.pyفایل برای گنجاندن منطق اولیه HTTP سرور دنبال کنید.
- محیط مجازی پایتون و مدیر بسته PIP را نصب کنید.کنسول
$ sudo apt install python3-venv python3-pip -y - یک دایرکتوری پروژه جدید برای ذخیره فایلهای برنامه ایجاد کنید.کنسول
$ mkdir python-app - به دایرکتوری تغییر دهید.کنسول
$ cd python-app
- یک محیط مجازی پایتون جدید ایجاد کنید تا وابستگیهای برنامه را از سایر بستههای سیستم جدا کنید.کنسول
$ python3 -m venv python-env - محیط مجازی را فعال کنید.کنسول
$ source python-env/bin/activate
- فایل اصلی برنامه را
app.pyبا استفاده از یک ویرایشگر متن مانند Nano ایجاد کنید.کنسول(python-env)$ nano app.py
- کد زیر را به فایل اضافه کنید.python
def hello_world(): print("Hello, World!") if __name__ == "__main__": hello_world()
فایل را ذخیره کنید و ببندید.
کد بالا یک برنامه وب پایتون پایه ایجاد میکند که یک
Hello, World!اعلان نمایش میدهد. درون برنامه:- این
hello_worldتابعHello, World!هنگام فراخوانی، رشته را چاپ میکند. if __name__ == "__main__":: بررسی میکند که آیا اسکریپت به عنوان برنامه اصلی اجرا میشود یا خیر. این تضمین میکند که عناصر کد خاصی هنگام شروع اسکریپت با نخ اصلی اجرا شوند. اگر اسکریپت برنامه اصلی باشد،hello_worldتابع را فراخوانی میکند.
- این
- یک فایل جدید
server.pyبرای راهاندازی یک برنامه HTTP پایه با استفاده از پایتونhttp.serverوsocketserverماژولها ایجاد کنید.کنسول(python-env)$ nano server.py
- کد زیر را به فایل اضافه کنید.پایتون
from http.server import SimpleHTTPRequestHandler from socketserver import TCPServer from threading import Thread class HelloWorldHandler(SimpleHTTPRequestHandler): def do_GET(self): # Handle GET requests self.send_response(۲۰۰) self.send_header("Content-type", "text/plain") self.end_headers() self.wfile.write(b"Hello, World!") def start_server(): # Set up the HTTP server with custom handler server_address = ("", ۸۰۰۰) httpd = TCPServer(server_address, HelloWorldHandler) print("Server is running at http://localhost:8000") try: # Serve indefinitely httpd.serve_forever() except KeyboardInterrupt: # Handle keyboard interrupt to gracefully shut down the server print("Shutting down the server.") httpd.shutdown() if __name__ == "__main__": # Start the server in a separate thread server_thread = Thread(target=start_server) server_thread.start() # Run the main application from app import hello_world hello_world() # Wait for the server thread to finish server_thread.join()
فایل را ذخیره کنید و ببندید.
کد برنامه فوق به درخواستهای GET ورودی با یک
Hello, World!اعلان پاسخ میدهد. درون کد:HelloWorldHandler: یک کلاس هندلر سفارشی تعریف میکند کهSimpleHTTPRequestHandlerتابع ماژول HTTP را برای مدیریت درخواستهای GET به ارث میبرد.start_server: یکTCPServerنمونه در حال اجرا روی پورت میزبان ایجاد میکند. علاوه بر این، استثنائات + وقفهها را۸۰۰۰ضبط میکند تا سرور را به طور مناسب خاموش کند.KeyboardInterruptCtrlC(if __name__ == "__main__":)سرور HTTP را با استفاده از تابع در یک نخ جداگانه اجرا میکند . سپس، یک تابع را از ماژولThread(target=start_server)وارد و فراخوانی میکند . قبل از بستن اتصال، منتظر میماند تا نخ سرور تکمیل شود.hello_worldappserver_thread.join()
- برنامه پایتون را به عنوان یک وظیفه پسزمینه در جلسه سرور خود اجرا کنید.کنسول
(python-env)$ python3 server.py &
خروجی:
Server is running at http://localhost:8000 ۸۰۰۰برای تأیید دسترسی به برنامه، یک درخواست GET به پورت میزبان ارسال کنید .کنسول(python-env)$ curl -X GET -H "Content-Type: application/json" http://localhost:8000
خروجی:
Hello, World!وقتی درخواست GET فوق با شکست مواجه شد، بررسی کنید که هیچ برنامهی ناسازگاری روی پورت میزبان تعریفشده اجرا نشود
۸۰۰۰.- شناسه کار برنامه پسزمینه را مشاهده کنید.کنسول
$ jobs
خروجی:
[۱] python3 server.py & - برنامه را با استفاده از شناسه شغل متوقف کنید. برای مثال
۱.کنسول(python-env)$ kill %۱
- محیط مجازی خود را غیرفعال کنید.کنسول
(python-env)$ deactivate
کانتینرایز کردن برنامه وب پایتون #
- یک Dockerfile جدید
Dockerfileبرای تنظیم تصویر کانتینر برنامه پایتون خود ایجاد کنید.کنسول$ nano Dockerfile - محتویات زیر را به فایل اضافه کنید.Dockerfile
FROM python:3.8-slim WORKDIR /app COPY . /app CMD ["python3", "./server.py"]
فایل را ذخیره کنید و ببندید.
پیکربندی Dockerfile فوق، دایرکتوری کانتینر پایتون و ساختار زمان اجرا را تعریف میکند. در داخل پیکربندی:
FROM python:3.8-slim: از ایمیج رسمی پایتون ۳.۸ به عنوان ایمیج پایه برای اجرای کانتینر استفاده میکند.WORKDIR /appدایرکتوری کاری را/appداخل کانتینر تنظیم میکند.COPY . /app: دادهها را از دایرکتوری پروژه شما به کانتینر کپی میکند.CMD ["python3", "./server.py"]:server.pyاسکریپت را هنگام شروع کانتینر اجرا میکند.
- ایمیج داکر را با تمام فایلهای دایرکتوری بسازید.کنسول
$ docker build -t python-app . - برای تأیید در دسترس بودن برنامه، تصاویر محلی Docker را مشاهده کنید.کنسول
$ docker imagesخروجی:
REPOSITORY TAG IMAGE ID CREATED SIZE python-app latest 86ff1e8041fe 19 seconds ago 180MB
تصویر برنامه پایتون را به رجیستری کانتینر نگارنوین منتقل کنید #
برای ذخیره و استفاده از تصویر برنامه پایتون روی پلتفرمی مانند Kubernetes، تصویر را به رجیستری کانتینر نگارنوین منتقل کنید تا آن را به محیطهای هدف خود ارسال کنید، همانطور که در مراحل زیر توضیح داده شده است.
- وارد رجیستری کانتینر نگارنوین خود شوید. به جای ،،
pythonregistryجزئیات رجیستری واقعی خود را قرار دهید.vcr-uservcr-passwordکنسول$ docker login https://sjc.negarnovin.com/pythonregistry -u vcr-user -p vcr-password - ایمیج محلی داکر را با مخزن رجیستری کانتینر نگارنوین هدف خود برچسبگذاری کنید.کنسول
$ docker tag python-app:latest sjc.negarnovin.com/pythonregistry/python-app:latest - لیست تصاویر Docker موجود را مشاهده کنید و تأیید کنید که تصویر رجیستری در دسترس است.کنسول
$ docker imagesخروجی:
sjc.negarnovin.com/pythonregistry/python-app latest 5594b65d7cd5 3 minutes ago 159MB python-app latest 01acb92c461c 3 minutes ago 159MB python 3.8-slim 067655fb1c09 2 months ago 128MB - تصویر برنامه پایتون خود را به رجیستری کانتینر نگارنوین منتقل کنید.کنسول
$ docker push sjc.negarnovin.com/pythonregistry/python-app:latestخروجی:
The push refers to repository [sjc.negarnovin.com/pythonregistry/python-app] ۱.2e1e26d6f: Pushed ۱.df21a05: Pushed b081d565ce24: Pushed e67a1acfc698: Pushed ۱.8551e70: Pushed da5d55102092: Pushed fb1bd2fc5282: Pushed latest: digest: sha256:4a523aab91202e4d79d9456672571ae855a7227590d2dd63de11498bf64f098c size: 1788 - برای آزمایش دسترسی به برنامه، یک کانتینر داکر جدید با استفاده از تصویر کانتینر رجیستری خود راهاندازی کنید.کنسول
$ docker run -dit -p ۸۰۰۰:۸۰۰۰ sjc.negarnovin.com/pythonregistry/python-app:latest
- برای تأیید اینکه کانتینر برنامه شما در دسترس است، لیست کانتینرهای داکر در حال اجرا را مشاهده کنید.کنسول
$ docker psخروجی:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cfaf3ab6bfac python-app:latest "python3 ./server.py" 8 seconds ago Up 7 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp jovial_brattain ۸۰۰۰برای تأیید دسترسی به کانتینر برنامه، یک درخواست GET جدید به پورت میزبان ارسال کنید .$ curl -X GET -H "Content-Type: application/json" http://127.0.0.1:8000خروجی:
Hello, World!
استقرار برنامه پایتون در یک کلاستر Kubernetes #
برای استقرار ایمن برنامه پایتون کانتینر شده خود در یک محیط عملیاتی مانند خوشه Kubernetes، دسترسی به رجیستری کانتینر نگارنوین خود را تنظیم کرده و تصویر برنامه را به عنوان یک منبع استقرار جدید نصب کنید. هنگام استقرار، کانتینر برنامه شما به اتصالات ورودی روی پورتی ۸۰۰۰که در پیکربندی کانتینر تعریف شده است، گوش میدهد. برای استقرار و استفاده از تصویر برنامه پایتون خود در یک خوشه negarnovin Kubernetes Engine (VKE) مراحل زیر را دنبال کنید.
- به کنترل پنل رجیستری کانتینر نگارنوین خود دسترسی پیدا کنید.
- به برگه Docker/Kubernetes بروید و روی Generate Kubernetes YAML کلیک کنید تا یک رجیستری جدید برای پیکربندی منابع مخفی ایجاد شود.

ایجاد و نصب برنامه وب پایتون - یک فایل منبع مخفی جدید ایجاد کنید
secret.yaml.کنسول$ nano secret.yaml - پیکربندی YAML رجیستری کانتینر نگارنوین تولید شده خود را به فایلی مشابه فایل زیر اضافه کنید:
apiVersion: v1 kind: Secret metadata: name: negarnovin-cr-credentials data: .dockerconfigjson: example-json type: kubernetes.io/dockerconfigjsonفایل را ذخیره کنید و ببندید.
- راز را در کلاستر خود مستقر کنید.کنسول
$ kubectl apply -f secret.yaml - منابع کلاستر را مشاهده کنید تا مطمئن شوید که اعتبارنامههای رجیستری شما آماده استفاده هستند.کنسول
$ kubectl get secretخروجی:
NAME TYPE DATA AGE negarnovin-cr-credentials kubernetes.io/dockerconfigjson 1 29m - یک فایل منبع Deployment جدید ایجاد کنید
deployment.yamlتا نحوه اجرای برنامه خود را در یک pod شرح دهید.کنسول$ nano deployment.yaml - پیکربندیهای زیر را به فایل اضافه کنید. آن را
sjc.negarnovin.com/pythonregistry/python-app:latestبا مخزن رجیستری NegarNovin Container واقعی خود جایگزین کنید.yamlkind: Deployment apiVersion: apps/v1 metadata: name: python-app spec: replicas: ۳ selector: matchLabels: app: python-app template: metadata: labels: app: python-app spec: containers: - name: python-app image: sjc.negarnovin.com/pythonregistry/python-app:latest ports: - containerPort: ۸۰۰۰ imagePullSecrets: - name: negarnovin-cr-credentials
فایل را ذخیره کنید و ببندید.
- استقرار را روی کلاستر خود اعمال کنید.کنسول
$ kubectl apply -f deployment.yaml - برای تأیید در دسترس بودن منبع جدید، استقرارهای کلاستر را مشاهده کنید.کنسول
$ kubectl get deploymentخروجی:
NAME READY UP-TO-DATE AVAILABLE AGE python-app 3/3 3 3 21s - برای تأیید تمام پادهای مرتبط با استقرار خود، پادهای کلاستر را مشاهده کنید.کنسول
$ kubectl get podsخروجی:
NAME READY STATUS RESTARTS AGE python-app-6cb76cfc8d-5wjbf 1/1 Running 0 35s python-app-6cb76cfc8d-tphrx 1/1 Running 0 35s python-app-6cb76cfc8d-txk5p 1/1 Running 0 35s
دسترسی خارجی به برنامه پایتون را به طور ایمن در معرض دید قرار دهید #
برای اینکه برنامه پایتون خود را برای دسترسی خارجی با استفاده از خوشه negarnovin Kubernetes Engine (VKE) خود در معرض نمایش قرار دهید، یک کنترلکننده Ingress نصب کنید تا سرویس برنامه شما را به یک نام دامنه نگاشت کند. این کنترلکننده به طور ایمن تمام درخواستهای برنامه را از نام دامنه شما به سرویس برنامه پایتون backend هدایت میکند. برای نمایش برنامه در خوشه VKE خود، مراحل زیر را دنبال کنید.
- مخزن ورودی NGINX را به منابع Helm خود اضافه کنید.کنسول
$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx - فهرست مخزن Helm را بهروزرسانی کنید.کنسول
$ helm repo update - NGINX Ingress Controller را با استفاده از Helm روی کلاستر خود نصب کنید.کنسول
$ helm install nginx-ingress ingress-nginx/ingress-nginx --set controller.publishService.enabled=true
- حداقل
۳چند دقیقه صبر کنید تا Nginx Ingress Controller تمام CRD های لازم را نصب کند. سپس، سرویسهای کنترلر را مشاهده کنید تا آدرس IP اختصاص داده شده به Load Balancer را تأیید کنید.کنسول$ kubectl get service --namespace default nginx-ingress-ingress-nginx-controllerخروجی:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-ingress-ingress-nginx-controller LoadBalancer 10.98.94.149 192.0.2.100 80:32671/TCP,443:32325/TCP 2m58sبرای دسترسی خارجی به سرویسهای کلاستر خود، مقدار EXTERNAL-IP کنترلر Ingress را یادداشت کنید .
- یک رکورد دامنه A جدید که به آدرس IP عمومی کنترلکننده Ingress اشاره میکند، تنظیم کنید . برای مثال،
app.example.com. - یک فایل منبع سرویس پایتون جدید ایجاد کنید
service.yamlکنسول$ nano service.yaml - محتویات زیر را به فایل اضافه کنید.یامل
apiVersion: v1 kind: Service metadata: name: python-app spec: selector: app: python-app ports: - protocol: TCP port: ۸۰ targetPort: ۸۰۰۰
فایل را ذخیره کنید و ببندید.
پیکربندی سرویس فوق، تمام درخواستهای شبکه روی پورت HTTP را
۸۰به پورت برنامه پایتون شما ارسال میکند۸۰۰۰. - سرویس را روی کلاستر خود اعمال کنید.کنسول
$ kubectl apply -f service.yaml - یک فایل منبع Ingress جدید
ingress.yamlبرای نمایش سرویس برنامه پایتون ایجاد کنید.کنسول$ nano ingress.yaml - محتویات زیر را به فایل اضافه کنید.
app.example.comدامنه واقعی خود را جایگزین کنید.یاملapiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress namespace: default annotations: kubernetes.io/ingress.class: nginx spec: rules: - host: app.example.com http: paths: - backend: service: name: python-app port: number: ۸۰ path: / pathType: Prefix
فایل را ذخیره کنید و ببندید.
پیکربندی Ingress فوق، تمام درخواستهای ریشه را از
app.example.comسرویس برنامه پایتون شما روی پورت ارسال میکند۸۰. - منبع Ingress را روی کلاستر خود اعمال کنید.کنسول
$ kubectl apply -f ingress.yaml - اشیاء Ingress کلاستر را مشاهده کنید و تأیید کنید که منبع جدید در دسترس است.کنسول
$ kubectl get ingressخروجی:
NAME CLASS HOSTS ADDRESS PORTS AGE nginx-ingress nginx app.example.com 192.0.2.100 80 32s - برای آزمایش دسترسی به برنامه، با استفاده از یک مرورگر وب مانند فایرفاکس به دامنه خود دسترسی پیدا کنید.

نتیجه گیری #
شما یک برنامه پایتون را کانتینرایز کردهاید و آن را در مخزن رجیستری کانتینر نگارنوین برای استقرار در یک خوشه VKE ذخیره کردهاید. ارسال برنامههای وب پایتون به عنوان تصاویر کانتینر، مدیریت و ارتقاء کارآمد اجزای برنامه را برای استقرار در محیطهای مختلف امکانپذیر میکند.

