كيفية نشر تطبيق Ruby on Rails باستخدام HAProxy Ingress و unicorn / puma ومآخذ الويب

بعد أشهر من الاختبار ، قمنا أخيرًا بتحويل تطبيق Ruby on Rails إلى الإنتاج مع مجموعة Kubernetes.


في هذه المقالة ، سأوضح لك كيفية تكوين التوجيه المستند إلى المسار لتطبيق Kubernetes Ruby on Rails باستخدام وحدة تحكم HAProxy Ingress.


الصورة


من المفترض أن لديك فكرة ما عن القرون ، والنشر ، والخدمات ، وخريطة التكوين و Ingress في Kubernetes


عادة في تطبيق Rails ، هناك خدمات مثل unicorn / puma و sidekiq / delayed-job / resque ومقابس الويب والعديد من خدمات API الخاصة. كان لدينا خدمة ويب واحدة مفتوحة من خلال الموازن ، وعمل كل شيء على ما يرام. لكن حركة المرور زادت ، وكان من الضروري توجيهها عن طريق URL أو Path.


ليس لدى Kubernetes حل جاهز لموازنة هذا النوع من الحمل. يتم بالفعل تطوير وحدة تحكم في إدخال الألبوم ، ولكنها لا تزال ليست في مرحلة ألفا ولإنتاجها.


بالنسبة إلى التوجيه المستند إلى المسار ، كان من الأفضل استخدام وحدة تحكم Ingress .


درسنا القضية ووجدنا أن k8s لديها حلول مختلفة لـ Ingress.



لقد جربنا nginx-ingress و HAProxy واستقرنا على HAProxy - إنه أفضل لمقابس الويب Rails التي استخدمناها في المشروع.


سأوضح لك خطوة بخطوة كيفية إرفاق HAProxy Ingress إلى تطبيق Rails.


إعداد تطبيق ريلز باستخدام جهاز تحكم HAProxy Ingress


إليك ما سنفعله:


  • دعونا نقوم بإنشاء تطبيق ريلز بخدمات وعمليات نشر مختلفة.
  • أنشئ سر TLS لـ SSL.
  • إنشاء خريطة تكوين HAProxy Ingress.
  • إنشاء وحدة تحكم HAProxy Ingress.
  • دعونا نفتح الوصول إلى Ingress من خلال خدمة مثل LoadBalancer.
  • دعونا تكوين تطبيقات DNS لخدمة Ingress.
  • قم بإنشاء قواعد دخول مختلفة للتوجيه المستند إلى المسار.
  • توجيه الاختبار بناءً على المسار.

دعنا ننشئ بيانًا لنشر تطبيق Rails لخدمات مختلفة - الويب (يونيكورن) ، مهام الخلفية (sidekiq) ، مقبس الويب (روبي رقيق) ، API (يونيكورن مخصص).


هنا نشر تطبيق الويب الخاص بنا ونموذج الخدمة.


--- apiVersion: v1 kind: Deployment metadata: name: test-production-web labels: app: test-production-web namespace: test spec: template: metadata: labels: app: test-production-web spec: containers: - image: <your-repo>/<your-image-name>:latest name: test-production imagePullPolicy: Always env: - name: POSTGRES_HOST value: test-production-postgres - name: REDIS_HOST value: test-production-redis - name: APP_ENV value: production - name: APP_TYPE value: web - name: CLIENT value: test ports: - containerPort: 80 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: test-production-web labels: app: test-production-web namespace: test spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: test-production-web 

هنا هو نشر تطبيق الخلفية ونموذج الخدمة.


 --- apiVersion: v1 kind: Deployment metadata: name: test-production-background labels: app: test-production-background namespace: test spec: template: metadata: labels: app: test-production-background spec: containers: - image: <your-repo>/<your-image-name>:latest name: test-production imagePullPolicy: Always env: - name: POSTGRES_HOST value: test-production-postgres - name: REDIS_HOST value: test-production-redis - name: APP_ENV value: production - name: APP_TYPE value: background - name: CLIENT value: test ports: - containerPort: 80 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: test-production-background labels: app: test-production-background namespace: test spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: test-production-background 

هنا هو مأخذ توصيل تطبيق ويب ونموذج الخدمة.


 --- apiVersion: v1 kind: Deployment metadata: name: test-production-websocket labels: app: test-production-websocket namespace: test spec: template: metadata: labels: app: test-production-websocket spec: containers: - image: <your-repo>/<your-image-name>:latest name: test-production imagePullPolicy: Always env: - name: POSTGRES_HOST value: test-production-postgres - name: REDIS_HOST value: test-production-redis - name: APP_ENV value: production - name: APP_TYPE value: websocket - name: CLIENT value: test ports: - containerPort: 80 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: test-production-websocket labels: app: test-production-websocket namespace: test spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: test-production-websocket 

إليك نشر تطبيق API ومعلومات الخدمة.


 --- `apiVersion: v1 kind: Deployment metadata: name: test-production-api labels: app: test-production-api namespace: test spec: template: metadata: labels: app: test-production-api spec: containers: - image: <your-repo>/<your-image-name>:latest name: test-production imagePullPolicy: Always env: - name: POSTGRES_HOST value: test-production-postgres - name: REDIS_HOST value: test-production-redis - name: APP_ENV value: production - name: APP_TYPE value: api - name: CLIENT value: test ports: - containerPort: 80 imagePullSecrets: - name: registrykey --- apiVersion: v1 kind: Service metadata: name: test-production-api labels: app: test-production-api namespace: test spec: ports: - port: 80 protocol: TCP targetPort: 80 selector: app: test-production-api 

لنقم بتشغيل البيان باستخدام kubectl apply .


 $ kubectl apply -f test-web.yml -f test-background.yml -f test-websocket.yml -f test-api.yml deployment "test-production-web" created service "test-production-web" created deployment "test-production-background" created service "test-production-background" created deployment "test-production-websocket" created service "test-production-websocket" created deployment "test-production-api" created service "test-production-api" created 

بمجرد نشر التطبيق وتشغيله ، ستحتاج إلى إنشاء HAProxy Ingress. ولكن أولاً ، دعنا ننشئ سر TLS بمفتاح SSL وشهادة.


سيسمح لـ HTTPS لعنوان URL الخاص بالتطبيق وإنهائه على L7.


$ kubectl create secret tls tls-certificate --key server.key --cert server.pem


server.key هنا هو مفتاح SSL الخاص بنا ، و server.pem هي شهادة SSL بتنسيق pem.


الآن إنشاء موارد وحدة تحكم HAProxy.


خريطة تكوين HAProxy


اطلع على جميع خيارات التكوين المتاحة لـ HAProxy هنا .


 apiVersion: v1 data: dynamic-scaling: "true" backend-server-slots-increment: "4" kind: ConfigMap metadata: name: haproxy-configmap namespace: test 

نشر وحدة تحكم HAProxy Ingress


نمط النشر لوحدة تحكم Ingress مع نسختين متماثلتين على الأقل لإدارة النشر المتسلسل.


 apiVersion: extensions/v1beta1 kind: Deployment metadata: labels: run: haproxy-ingress name: haproxy-ingress namespace: test spec: replicas: 2 selector: matchLabels: run: haproxy-ingress template: metadata: labels: run: haproxy-ingress spec: containers: - name: haproxy-ingress image: quay.io/jcmoraisjr/haproxy-ingress:v0.5-beta.1 args: - --default-backend-service=$(POD_NAMESPACE)/test-production-web - --default-ssl-certificate=$(POD_NAMESPACE)/tls-certificate - --configmap=$(POD_NAMESPACE)/haproxy-configmap - --ingress-class=haproxy ports: - name: http containerPort: 80 - name: https containerPort: 443 - name: stat containerPort: 1936 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace 

في هذا البيان ، نحن مهتمون بشكل خاص بالحجج التي يتم تمريرها إلى وحدة التحكم.
--default-backend-service هي الخدمة التي سيستخدمها التطبيق إذا لم تتطابق أي قواعد مع الطلب.


لدينا test-production-web ، ولكن يمكن أن تكون صفحة 404 مخصصة أو شيء من هذا القبيل - أنت تقرر.


--default-ssl-certificate هي سر طبقة المقابس الآمنة الذي --default-ssl-certificate للتو. سيتم إنهاء SSL على L7 ، وسيكون التطبيق متاحًا خارجيًا عبر HTTPS.


خدمة دخول HAProxy


هذا هو نوع من خدمة LoadBalancer التي تتيح وصول حركة مرور العميل إلى وحدة التحكم في Ingress.


يتمتع LoadBalancer بالوصول إلى الشبكة العامة وشبكة Kubernetes الداخلية ، وفي L7 يقوم بتوجيه حركة المرور إلى جهاز التحكم في Ingress.


 apiVersion: v1 kind: Service metadata: labels: run: haproxy-ingress name: haproxy-ingress namespace: test spec: type: LoadBalancer ports: - name: http port: 80 protocol: TCP targetPort: 80 - name: https port: 443 protocol: TCP targetPort: 443 - name: stat port: 1936 protocol: TCP targetPort: 1936 selector: run: haproxy-ingress 

دعنا نطبق جميع قوائم HAProxy.


 $ kubectl apply -f haproxy-configmap.yml -f haproxy-deployment.yml -f haproxy-service.yml configmap "haproxy-configmap" created deployment "haproxy-ingress" created service "haproxy-ingress" created 

عند تشغيل جميع الموارد ، حدد نقطة نهاية LoadBalancer.


 $ kubectl -n test get svc haproxy-ingress -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR haproxy-ingress LoadBalancer 100.67.194.186 a694abcdefghi11e8bc3b0af2eb5c5d8-806901662.us-east-1.elb.amazonaws.com 80:31788/TCP,443:32274/TCP,1936:32157/TCP 2m run=ingress 

تعيين DNS لعنوان URL للتطبيق


بمجرد تحديد نقطة نهاية ELB لخدمة Ingress ، سنحتاج إلى تعيين DNS للخدمة وعنوان URL للطلب (على سبيل المثال test-rails-app.com ).


تنفيذ الدخول


الجزء الأصعب متأخر ، لقد حان الوقت لتكوين قواعد Ingress و Path-Based.


نحن بحاجة إلى القواعد التالية.


ستتم معالجة طلبات https://test-rails-app.com بواسطة خدمة test-production-web .


ستتم معالجة طلبات https://test-rails-app.com/websocket بواسطة خدمة test-production-websocket .


ستتم معالجة طلبات https://test-rails-app.com/api بواسطة خدمة test-production-api .


لنقم بإنشاء بيان خروج مع كل هذه القواعد.


 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress namespace: test spec: tls: - hosts: - test-rails-app.com secretName: tls-certificate rules: - host: test-rails-app.com http: paths: - path: / backend: serviceName: test-production-web servicePort: 80 - path: /api backend: serviceName: test-production-api servicePort: 80 - path: /websocket backend: serviceName: test-production-websocket servicePort: 80 

في حالة تغييرات التكوين ، لدينا تعليقات توضيحية لموارد Ingress .


كما هو متوقع ، بشكل افتراضي ، / توجيه حركة المرور إلى / إلى خدمة test-production-web و /api إلى test-production-api و /websocket to test-production-websocket .


كنا بحاجة إلى التوجيه المستند إلى المسار وإنهاء SSL على L7 في Kubernetes ، وحل تطبيق Ingress هذه المشكلة.

Source: https://habr.com/ru/post/ar424789/


All Articles