Bagaimana cara menyebarkan aplikasi Ruby on Rails dengan HAProxy Ingress, unicorn / puma, dan soket web

Setelah berbulan-bulan pengujian, kami akhirnya mengirim aplikasi Ruby on Rails ke produksi dengan kluster Kubernetes.


Pada artikel ini, saya akan menunjukkan kepada Anda cara mengkonfigurasi routing berbasis Path untuk aplikasi Ruby on Rails di Kubernetes dengan kontroler HAProxy Ingress.


gambar


Diasumsikan bahwa Anda memiliki beberapa gagasan tentang apa itu pod , penyebaran , layanan , peta konfigurasi, dan Ingress di Kubernetes.


Biasanya dalam aplikasi Rails ada layanan seperti unicorn / puma, sidekiq / delay-job / resque, soket web dan beberapa layanan API khusus. Kami memiliki satu layanan web yang dibuka melalui penyeimbang, dan semuanya bekerja dengan baik. Tetapi lalu lintas bertambah, dan perlu untuk merutekannya dengan URL atau Path.


Kubernetes tidak memiliki solusi turnkey untuk menyeimbangkan jenis beban ini. Pengontrol alb-ingress sudah dikembangkan untuk itu, tetapi masih belum pada tahap alfa dan untuk produksi.


Untuk routing berbasis jalur, yang terbaik adalah menggunakan pengontrol Ingress .


Kami mempelajari masalah ini dan menemukan bahwa k8 memiliki solusi yang berbeda untuk Ingress.



Kami bereksperimen dengan nginx-ingress dan HAProxy dan memilih HAProxy - lebih cocok untuk soket web Rails yang kami gunakan dalam proyek.


Saya akan menunjukkan kepada Anda langkah demi langkah cara melampirkan HAProxy Ingress ke aplikasi Rails.


Menyiapkan aplikasi Rails dengan pengontrol HAProxy Ingress


Inilah yang akan kami lakukan:


  • Mari kita membuat aplikasi Rails dengan berbagai layanan dan penerapan.
  • Buat rahasia TLS untuk SSL.
  • Buat peta konfigurasi HAProxy Ingress.
  • Buat pengontrol HAProxy Ingress.
  • Mari kita buka akses ke Ingress melalui layanan seperti LoadBalancer.
  • Mari mengkonfigurasi aplikasi DNS untuk layanan Ingress.
  • Buat aturan Ingress berbeda untuk routing berbasis Path.
  • Uji rute berdasarkan Path.

Mari kita membuat manifes untuk menyebarkan aplikasi Rails untuk berbagai layanan - web (unicorn), tugas latar belakang (sidekiq), soket web (ruby thin), API (unicorn dedicated).


Ini adalah aplikasi web dan template layanan yang kami gunakan.


--- 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 

Berikut adalah latar belakang penerapan aplikasi dan template layanan.


 --- 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 

Ini adalah soket aplikasi web dan template layanan.


 --- 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 

Berikut adalah penyebaran aplikasi dan informasi layanan 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 

Mari kita jalankan manifes dengan 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 

Setelah aplikasi dikerahkan dan diluncurkan, Anda harus membuat HAProxy Ingress. Tapi pertama-tama, mari kita buat rahasia TLS dengan kunci dan sertifikat SSL.


Dia akan mengizinkan HTTPS untuk URL aplikasi dan menghentikannya di L7.


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


server.key sini adalah kunci SSL kami, dan server.pem adalah sertifikat SSL kami dalam format pem.


Sekarang buat sumber daya dari pengontrol HAProxy.


Peta konfigurasi HAProxy


Lihat semua opsi konfigurasi yang tersedia untuk HAProxy di sini .


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

Penerapan Pengendali Ingress HAProxy


Pola penyebaran untuk pengontrol Ingress dengan setidaknya dua replika untuk mengelola penyebaran berurutan.


 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 

Dalam manifes ini, kami sangat tertarik dengan argumen yang diteruskan ke controller.
--default-backend-service adalah layanan yang akan digunakan aplikasi jika tidak ada aturan yang sesuai dengan permintaan.


Kami memiliki layanan test-production-web , tetapi bisa berupa halaman 404 khusus atau semacamnya - Anda putuskan.


--default-ssl-certificate adalah rahasia SSL yang baru saja kita buat. Ini akan mengakhiri SSL pada L7, dan aplikasi akan dapat diakses secara eksternal melalui HTTPS.


Layanan Ingress HAProxy


Ini adalah jenis layanan LoadBalancer yang memungkinkan akses lalu lintas klien ke pengontrol Ingress kami.


LoadBalancer memiliki akses ke jaringan publik dan jaringan internal Kubernetes, dan pada L7 ia mengarahkan lalu lintas ke pengontrol 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 

Mari kita terapkan semua manifes 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 

Ketika semua sumber daya berjalan, tentukan titik akhir 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 

Peta DNS ke URL Aplikasi


Segera setelah kami menentukan titik akhir ELB untuk layanan Ingress, kami perlu memetakan DNS layanan dan URL permintaan (misalnya test-rails-app.com ).


Implementasi masuknya


Bagian tersulit ada di belakang, saatnya untuk mengkonfigurasi aturan Ingress dan Path-based.


Kami membutuhkan aturan berikut.


Permintaan untuk https://test-rails-app.com akan diproses oleh layanan test-production-web .


Permintaan untuk https://test-rails-app.com/websocket akan diproses oleh layanan test-production-websocket .


Permintaan untuk https://test-rails-app.com/api akan diproses oleh layanan test-production-api .


Mari kita membuat manifes Ingress dengan semua aturan ini.


 --- 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 

Dalam hal perubahan konfigurasi, kami memiliki anotasi untuk sumber daya Ingress .


Seperti yang diharapkan, secara default, lalu lintas kami ke / diarahkan ke layanan test-production-web , /api ke test-production-api , dan /websocket ke test-production-websocket .


Kami membutuhkan perutean berbasis jalur dan penghentian SSL pada L7 di Kubernetes, dan implementasi Ingress memecahkan masalah ini.

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


All Articles