Gateway API adalah proyek Kubernetes resmi yang menyediakan API generasi berikutnya untuk routing dan penyeimbangan beban di Kubernetes. Anda dapat menggunakan Gateway API untuk mengonfigurasi aturan trafik. Topik ini menjelaskan cara mengonfigurasi fitur dasar Gateway API yang didukung oleh Gateway dengan Ekstensi Inferensi.
Cara kerja
Komponen Gateway dengan Ekstensi Inferensi dibangun di atas proyek Envoy Gateway. Komponen ini mendukung semua fitur dasar Gateway API serta sumber daya ekstensi Envoy Gateway open source.
Arsitektur Envoy Gateway mencakup komponen-komponen berikut:
Lapisan kontrol: Terdiri dari komponen Envoy Gateway yang mendengarkan aturan trafik dalam kluster, membuat serta mengelola instans proxy Envoy secara dinamis, dan memperbarui aturan pengalihan mereka secara real time. Lapisan kontrol tidak langsung meneruskan lalu lintas layanan.
Lapisan data: Terdiri dari instans proxy Envoy yang sedang berjalan dan memproses serta meneruskan lalu lintas layanan untuk memastikan komunikasi yang efisien dan andal.
Lingkup
Versi kluster ACK yang dikelola Anda adalah 1.30 atau lebih baru. Untuk meningkatkan kluster, lihat Tingkatkan kluster ACK secara manual.
Komponen Gateway dengan Ekstensi Inferensi telah diinstal.
Persiapan
Buat aplikasi uji backend dan backend-2. Simpan konten YAML berikut sebagai backend.yaml, lalu jalankan perintah
kubectl apply -f backend.yaml.CatatanUntuk membuat aplikasi backend-2, ganti semua kemunculan
backenddenganbackend-2dalam file YAML aplikasi backend.apiVersion: v1 kind: ServiceAccount metadata: name: backend --- apiVersion: v1 kind: Service metadata: name: backend labels: app: backend service: backend spec: ports: - name: http port: 3000 targetPort: 3000 selector: app: backend --- apiVersion: apps/v1 kind: Deployment metadata: name: backend spec: replicas: 1 selector: matchLabels: app: backend version: v1 template: metadata: labels: app: backend version: v1 spec: serviceAccountName: backend containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/envoygateway-echo-basic:v20231214-v1.0.0-140-gf544a46e imagePullPolicy: IfNotPresent name: backend ports: - containerPort: 3000 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespaceSaat Anda menginstal komponen Gateway dengan Ekstensi Inferensi, sebuah GatewayClass dibuat secara default. Jalankan perintah berikut untuk memeriksa apakah GatewayClass telah dibuat.
kubectl get gatewayclass NAME CONTROLLER ACCEPTED AGE ack-gateway gateway.envoyproxy.io/gatewayclass-controller True 2m31sJika sumber daya GatewayClass tidak ditemukan, Anda dapat membuatnya secara manual.
Buat sumber daya Gateway. Simpan konten YAML berikut sebagai gateway.yaml, lalu jalankan perintah
kubectl apply -f gateway.yaml.apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: ack-gateway spec: gatewayClassName: ack-gateway listeners: - name: http protocol: HTTP port: 80Lapisan kontrol komponen Gateway dengan Ekstensi Inferensi membuat deployment EnvoyProxy dan Service bertipe LoadBalancer yang sesuai berdasarkan sumber daya Gateway. Komponen ini juga memulai pendengar pada port yang ditentukan. Untuk informasi selengkapnya mengenai penagihan instans Server Load Balancer (SLB), lihat Penagihan SLB.
Anda juga dapat menyesuaikan spesifikasi deployment EnvoyProxy dan parameter Service, atau mengaktifkan Horizontal Pod Autoscaling (HPA) untuk gateway.
Dapatkan alamat gateway.
export GATEWAY_HOST=$(kubectl get gateway/ack-gateway -o jsonpath='{.status.addresses[0].value}')
Routing HTTP berdasarkan pencocokan awalan path
Contoh berikut menunjukkan cara mengonfigurasi HTTPRoute untuk mencocokkan awalan /get dan menguji konfigurasinya.
Buat sumber daya HTTPRoute. Simpan konten YAML berikut sebagai httproute.yaml, lalu jalankan perintah
kubectl apply -f httproute.yaml.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: /getUji akses.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getOutput yang diharapkan:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "953b2f8f-26d3-4ba9-93ba-a482b197b1ff" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }
Tambahkan header permintaan
Perbarui konfigurasi HTTPRoute untuk menambahkan header ke permintaan yang diarahkan.
Perbarui sumber daya HTTPRoute. Simpan konten YAML berikut sebagai httproute.yaml, lalu jalankan perintah
kubectl apply -f httproute.yaml.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 1 filters: - type: RequestHeaderModifier requestHeaderModifier: add: - name: "added-header" value: "foo"Uji akses.
curl -H "Host: www.example.com" http://$GATEWAY_HOST/getOutput yang diharapkan: Aplikasi contoh mengembalikan informasi permintaan dalam tanggapan. Anda dapat melihat
added-headeryang ditambahkan dalam respons, yang menunjukkan bahwa operasi berhasil.{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "Added-Header": [ "foo" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "http" ], "X-Request-Id": [ "d37f19e5-25c1-45cf-90e5-51453e7ae3ed" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }
Distribusikan permintaan berdasarkan proporsi
Perbarui konfigurasi HTTPRoute sekali lagi untuk menambahkan aturan routing bagi backend-2 dan mengonfigurasi bobot untuk layanan backend dan backend-2.
Jumlah bobot semua entri backendRef tidak harus 100. Proporsi trafik yang diarahkan ke suatu Service dihitung menggunakan rumus berikut:
Perbarui sumber daya HTTPRoute. Simpan konten YAML berikut sebagai httproute.yaml, lalu jalankan perintah
kubectl apply -f httproute.yaml.apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: backend spec: parentRefs: - name: ack-gateway hostnames: - "www.example.com" rules: - matches: - path: type: PathPrefix value: /get backendRefs: - group: "" kind: Service name: backend port: 3000 weight: 8 - group: "" kind: Service name: backend-2 port: 3000 weight: 2Uji akses sebanyak 20 kali berturut-turut untuk memeriksa proporsi trafik antara kedua layanan.
Perintah berikut diproses agar hanya menampilkan
backenddanbackend-2dalam output.for i in $(seq 1 20); do curl -sS -H "Host: www.example.com" http://$GATEWAY_HOST/get |grep backend; done | \ sed -E 's/".*"(backend(-2)?)-[0-9a-zA-Z]*-.*/\1/'Output yang diharapkan: Trafik yang diterima oleh kedua layanan kira-kira 80% dan 20%.
backend-2 backend backend backend backend backend backend backend backend backend backend backend-2 backend-2 backend backend backend-2 backend backend backend backend
Proses trafik TLS
Perbarui sumber daya Gateway, konfigurasikan sertifikat, dan tambahkan pendengar TLS untuk memverifikasi bahwa trafik TLS dapat diproses.
Hasilkan sertifikat dan buat Secret.
openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example.com.key -out example.com.crt openssl req -out www.example.com.csr -newkey rsa:2048 -nodes -keyout www.example.com.key -subj "/CN=www.example.com/O=example organization" openssl x509 -req -days 365 -CA example.com.crt -CAkey example.com.key -set_serial 0 -in www.example.com.csr -out www.example.com.crt kubectl create secret tls example-cert --key=www.example.com.key --cert=www.example.com.crtPerbarui sumber daya Gateway. Tambahkan pendengar TLS dan referensikan sertifikat yang telah Anda buat pada langkah sebelumnya.
kubectl patch gateway ack-gateway --type=json --patch ' - op: add path: /spec/listeners/- value: name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - kind: Secret group: "" name: example-cert 'Periksa apakah perubahan telah diterapkan.
kubectl get gateway/ack-gateway -o yaml | grep spec: -A 20Output yang diharapkan:
spec: gatewayClassName: ack-gateway listeners: - allowedRoutes: namespaces: from: Same name: http port: 80 protocol: HTTP - allowedRoutes: namespaces: from: Same name: https port: 443 protocol: HTTPS tls: certificateRefs: - group: "" kind: Secret name: example-cert mode: Terminate status:Output tersebut menunjukkan bahwa perubahan telah diterapkan.
Uji akses.
curl -H Host: www.example.com --resolve "www.example.com:443:${GATEWAY_HOST}" \ --cacert example.com.crt https://www.example.com/getOutput yang diharapkan:
{ "path": "/get", "host": "www.example.com", "method": "GET", "proto": "HTTP/1.1", "headers": { "Accept": [ "*/*" ], "User-Agent": [ "curl/8.9.1" ], "X-Envoy-External-Address": [ "115.XX.XXX.55" ], "X-Forwarded-For": [ "115.XX.XXX.55" ], "X-Forwarded-Proto": [ "https" ], "X-Request-Id": [ "ac539756-3826-474b-be2f-5e57fdd49dac" ] }, "namespace": "default", "ingress": "", "service": "", "pod": "backend-5bff7XXXXX-XXXXX" }