نشر C++ على Kubernetes: دليل أساسي للمبتدئين

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة: لماذا ننشر C++ في Kubernetes؟

\n\n

تظل لغة C++ واحدة من أكثر لغات البرمجة أداءً، خاصة في مجالات الأنظمة عالية التحميل، وخوادم الألعاب، والتطبيقات المالية، وإنترنت الأشياء. ومع ذلك، في عالم الحوسبة السحابية الحديث، لا يكفي مجرد كتابة كود سريع - بل يجب أن تكون قادرًا على نشره وتوسيعه وتحديثه بشكل موثوق دون توقف. وهنا يأتي دور Kubernetes (K8s) - نظام تنسيق الحاويات الذي يعمل على أتمتة نشر التطبيقات وتوسيع نطاقها وإدارتها.

\n\n

في هذا الدليل، سنشرح خطوة بخطوة عملية نشر تطبيق C++ بسيط في مجموعة Kubernetes. ستتعلم كيفية حزم كود C++ في صورة Docker، وكتابة المانيفستات اللازمة لـ Kubernetes، وتشغيل تطبيقك في السحابة. المقال موجه للمبتدئين، لذلك لن نتعمق في التكوينات المعقدة، بل سنركز على خط أنابيب أساسي ولكنه عملي.

\n\n

1. التحضير: تطبيق C++ وحاوية Docker

\n\n

قبل الحديث عن Kubernetes، نحتاج إلى تجهيز تطبيق C++ الخاص بنا للعمل داخل حاوية. الحاوية هي تغليف التطبيق مع جميع تبعياته في بيئة معزولة. بالنسبة لـ C++، هذا أمر بالغ الأهمية، لأن الملف الثنائي المترجم قد يعتمد على إصدارات محددة من المكتبات (libc، libstdc++، إلخ) على الجهاز الهدف.

\n\n

1.1. تطبيق C++ بسيط للنشر

\n\n

لننشئ ملف main.cpp - خادم HTTP بسيط يستجيب للطلبات. للتبسيط، لن نستخدم مكتبات خارجية، بل سنكتب خادم TCP بدائي.

\n\n
// main.cpp\n#include <iostream>\n#include <string>\n#include <cstring>\n#include <sys/socket.h>\n#include <netinet/in.h>\n#include <unistd.h>\n\nint main() {\n    int server_fd, new_socket;\n    struct sockaddr_in address;\n    int opt = 1;\n    int addrlen = sizeof(address);\n    char buffer[1024] = {0};\n    const char* hello = "HTTP/1.1 200 OK\\nContent-Type: text/plain\\nContent-Length: 12\\n\\nHello, K8s!\\n";\n\n    // إنشاء socket\n    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {\n        perror("socket failed");\n        exit(EXIT_FAILURE);\n    }\n\n    // الربط بالمنفذ 8080\n    if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {\n        perror("setsockopt");\n        exit(EXIT_FAILURE);\n    }\n    address.sin_family = AF_INET;\n    address.sin_addr.s_addr = INADDR_ANY;\n    address.sin_port = htons(8080);\n\n    if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) {\n        perror("bind failed");\n        exit(EXIT_FAILURE);\n    }\n\n    if (listen(server_fd, 3) < 0) {\n        perror("listen");\n        exit(EXIT_FAILURE);\n    }\n\n    std::cout << "Server listening on port 8080" << std::endl;\n\n    while(true) {\n        if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen))<0) {\n            perror("accept");\n            exit(EXIT_FAILURE);\n        }\n        read(new_socket, buffer, 1024);\n        send(new_socket, hello, strlen(hello), 0);\n        close(new_socket);\n    }\n    return 0;\n}\n
\n\n

1.2. بناء ملف ثنائي ثابت

\n\n

لجعل حاويتنا صغيرة قدر الإمكان وغير معتمدة على مكتبات النظام المضيف، من الأفضل بناء ملف ثنائي مرتبط بشكل ثابت. نفذ الأمر التالي:

\n\n
g++ -static -o server main.cpp -lpthread
\n\n

العلامة -static تضم جميع المكتبات الضرورية مباشرة في الملف التنفيذي. العلامة -lpthread مطلوبة للعمل مع الخيوط (على الرغم من أنها ليست إلزامية في مثالنا البسيط، إلا أنها ستكون مفيدة للمشاريع الحقيقية).

\n\n

1.3. ملف Dockerfile لتطبيق C++

\n\n

الآن لننشئ Dockerfile. سنستخدم البناء متعدد المراحل (multi-stage build): أولاً نقوم بترجمة الكود في صورة كبيرة تحتوي على المترجم، ثم

المدونات

توصيات الكتب