Anda dapat mengintegrasikan aplikasi Spring Cloud dengan Service Mesh (ASM) untuk memanfaatkan kemampuan tata kelola layanan cloud-native tanpa mengubah kode aplikasi. Topik ini menjelaskan cara menggunakan ASM untuk mengelola layanan Spring Cloud.
Prasyarat
Anda memiliki instans ASM Edisi Enterprise atau Ultimate. Untuk informasi selengkapnya, lihat Buat instans ASM.
Kluster ACK yang dikelola telah dibuat. Untuk informasi selengkapnya, lihat Buat kluster ACK yang dikelola.
Gerbang masuk telah diterapkan. Untuk informasi selengkapnya, lihat Buat gerbang masuk.
Latar Belakang
Spring Cloud adalah standar dengan berbagai implementasi, seperti Spring Cloud Netflix, Spring Cloud Alibaba, dan Spring Cloud Consul. Perbedaan utama antarimplementasi tersebut dalam konteks ASM terletak pada service registry yang digunakan. Tabel berikut mencantumkan dukungan migrasi ASM untuk berbagai versi Spring Cloud.
Versi Spring Cloud | Service registry | Dukungan migrasi |
Spring Cloud Alibaba | Microservices Engine (MSE) Nacos (layanan Alibaba Cloud) | Didukung |
Spring Cloud Alibaba | Nacos (self-managed) | Didukung |
Spring Cloud Netflix | Eureka | Didukung. Versi instans ASM harus 1.13.4.53 atau lebih baru. |
Spring Cloud Consul | Consul | Didukung. Versi instans ASM harus 1.13.4.53 atau lebih baru. |
Spring Cloud Zookeeper | Zookeeper | Didukung. Versi instans ASM harus 1.13.4.53 atau lebih baru. |
Ikhtisar demo
Topik ini menggunakan aplikasi yang dibangun dengan Spring Cloud dan Nacos sebagai contoh. Anda dapat mengunduh kode contoh dari repositori nacos-example.
Aplikasi ini terdiri atas layanan consumer dan layanan provider. Layanan provider memiliki dua versi, v1 dan v2, keduanya terdaftar di registri Nacos. Layanan consumer mengambil alamat layanan provider dari registri Nacos dan melakukan load-balancing permintaan di antara keduanya. Ketika menerima permintaan, layanan consumer meneruskan permintaan tersebut ke salah satu provider dan mengembalikan respons dari provider tersebut. Dua versi provider tersebut mengembalikan respons yang berbeda:
Provider v1 merespons permintaan echo dengan
Hello Nacos Discovery From v1xxx.Provider v2 merespons permintaan echo dengan
Hello Nacos Discovery From v2xxx.
Dalam respons tersebut, .xxx merupakan placeholder untuk parameter yang dikirimkan ke API echo. Sebagai contoh, jika permintaan ke /echo/world dikirimkan ke provider v1, respons yang dikembalikan adalah Hello Nacos Discovery From v1world.
Jika Anda tidak mengaktifkan kemampuan service mesh untuk layanan consumer dan provider—artinya tidak ada sidecar yang diinjeksikan ke dalam pod aplikasi—permintaan tetap akan diproses, namun tidak akan memiliki kemampuan tata kelola layanan yang disediakan oleh Istio. Langkah-langkah berikut menunjukkan cara menggunakan ASM untuk mengelola layanan Spring Cloud.
Langkah 1: Aktifkan dukungan Spring Cloud
Metode 1: Untuk semua versi dan registri
Versi instans ASM harus 1.13.4.32 atau lebih baru.
Batasan:
Anda harus membuat Kubernetes Service untuk layanan tujuan. Port layanan dan target port harus diatur ke port pendengar aplikasi.
Pada versi ASM sebelum 1.23.6.32, Anda harus menonaktifkan REGISTRY_ONLY saat menggunakan solusi ini.
Sambungkan ke kluster lapisan kontrol menggunakan kubectl. Untuk informasi selengkapnya, lihat Akses sumber daya Istio pada lapisan kontrol menggunakan kubectl.
Buat EnvoyFilter di kluster ASM.
Buat file bernama any-spring-cloud-support.yaml dengan konten berikut.
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: labels: provider: "asm" asm-system: "true" name: any-spring-cloud-support namespace: istio-system spec: configPatches: - applyTo: HTTP_FILTER match: proxy: proxyVersion: "^1.*" context: SIDECAR_OUTBOUND listener: portNumber: 8070 filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: # reverse_dns filter specification name: com.aliyun.reverse_dns typed_config: "@type": "type.googleapis.com/udpa.type.v1.TypedStruct" type_url: type.googleapis.com/envoy.config.filter.reverse_dns.v3alpha.CommonConfig value: pod_cidrs: - "10.0.128.0/18"Ubah parameter dalam file YAML sesuai kebutuhan bisnis Anda. Penjelasan parameter sebagai berikut:
portNumber: Port layanan Spring Cloud. Jika port-port tersebut tidak seragam, Anda dapat menghapus parameter ini. Jika port-port tersebut dapat dikonsolidasi, Anda dapat mengonfigurasi beberapa sumber daya EnvoyFilter, masing-masing mengikat keportNumbertertentu.pod_cidrs: CIDR pod dari kluster ACK atau ACK Serverless. Untuk menemukan nilai ini, login ke Container Service Management Console dan buka halaman Cluster Information. Pada tab Cluster Resources, temukan blok Pod CIDR di bawah VPC dan gunakan nilai tersebut untuk parameter ini.
Jalankan perintah berikut untuk menerapkan
EnvoyFilter.kubectl apply -f any-spring-cloud-support.yaml
Metode 2: Hanya untuk registri Nacos
Sambungkan ke kluster lapisan kontrol menggunakan kubectl. Untuk informasi selengkapnya, lihat Akses sumber daya Istio pada lapisan kontrol menggunakan kubectl.
Buat ServiceEntry.
Buat file bernama external-nacos-svc.yaml dengan konten berikut.
kind: ServiceEntry metadata: name: external-nacos-svc spec: hosts: - "NACOS_SERVER_HOST" ## Ganti ini dengan HOST Server Nacos Anda, misalnya, "mse-xxx-p.nacos-ans.mse.aliyuncs.com". location: MESH_EXTERNAL ports: - number: 8848 name: http resolution: DNSPada file YAML di atas,
8848adalah port default untuk Nacos. Jika Anda menggunakan server Nacos self-managed dan telah mengubah port tersebut, Anda juga harus mengubah parameternumbersesuai kebutuhan.Jalankan perintah berikut untuk membuat ServiceEntry.
kubectl apply -f external-nacos-svc.yaml
Buat EnvoyFilter.
Buat file bernama external-envoyfilter.yaml dengan konten berikut.
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: labels: provider: "asm" asm-system: "true" name: nacos-subscribe-lua namespace: istio-system spec: configPatches: # The first patch adds the lua filter to the listener/http connection manager. - applyTo: HTTP_FILTER match: proxy: proxyVersion: "^1.*" context: SIDECAR_OUTBOUND listener: portNumber: 8848 filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: # lua filter specification name: envoy.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | -- copyright: ASM (Alibaba Cloud ServiceMesh) function envoy_on_request(request_handle) local request_headers = request_handle:headers() -- /nacos/v1/ns/instance/list?healthyOnly=false&namespaceId=public&clientIP=10.122.63.81&serviceName=DEFAULT_GROUP%40%40service-provider&udpPort=53174&encoding=UTF-8 local path = request_headers:get(":path") if string.match(path,"^/nacos/v1/ns/instance/list") then local servicename = string.gsub(path,".*&serviceName.*40([%w.\\_\\-]+)&.*","%1") request_handle:streamInfo():dynamicMetadata():set("context", "request.path", path) request_handle:streamInfo():dynamicMetadata():set("context", "request.servicename", servicename) request_handle:logInfo("subscribe for serviceName: " .. servicename) else request_handle:streamInfo():dynamicMetadata():set("context", "request.path", "") end end function envoy_on_response(response_handle) local request_path = response_handle:streamInfo():dynamicMetadata():get("context")["request.path"] if request_path == "" then return end local servicename = response_handle:streamInfo():dynamicMetadata():get("context")["request.servicename"] response_handle:logInfo("modified response ip to serviceName:" .. servicename) local bodyObject = response_handle:body(true) local body= bodyObject:getBytes(0,bodyObject:length()) body = string.gsub(body,"%s+","") body = string.gsub(body,"(ip\":\")(%d+.%d+.%d+.%d+)","%1"..servicename) response_handle:body():setBytes(body) endJalankan perintah berikut untuk membuat EnvoyFilter.
kubectl apply -f external-envoyfilter.yaml
Langkah 2: Terapkan layanan Spring Cloud
Untuk mengintersepsi proses registrasi, Anda harus membuat EnvoyFilter sebelum membuat workload. Jika workload dibuat sebelum EnvoyFilter, Anda harus melakukan rolling update pada workload tersebut.
Anda harus membuat Kubernetes Service bertipe ClusterIP untuk setiap layanan.
Sambungkan ke kluster bidang data menggunakan kubectl. Untuk informasi selengkapnya, lihat Dapatkan file kubeconfig kluster dan gunakan kubectl untuk menyambung ke kluster.
Jalankan perintah berikut untuk menerapkan layanan Spring Cloud.
export NACOS_ADDRESS=xxxx # Ganti xxxx dengan alamat MSE atau Nacos self-managed Anda. Disarankan menggunakan alamat VPC internal. wget https://alibabacloudservicemesh.oss-cn-beijing.aliyuncs.com/asm-labs/springcloud/demo.yaml -O demo.yaml sed -e "s/NACOS_SERVER_CLUSTERIP/$NACOS_ADDRESS/g" demo.yaml |kubectl apply -f -Jalankan perintah berikut untuk memeriksa layanan Spring Cloud.
kubectl get podsOutput yang diharapkan:
consumer-bdd464654-jn8q7 2/2 Running 0 25h provider-v1-66bc67fb6d-46pgl 2/2 Running 0 25h provider-v2-76568c45f6-85z87 2/2 Running 0 25h
Langkah 3: Buat gerbang dan layanan virtual
Buat gateway Istio.
Buat file bernama test-gateway.yaml dengan konten berikut.
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: test-gateway spec: selector: istio: ingressgateway # use istio default controller servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"Gunakan file kubeconfig instans ASM dan jalankan perintah berikut untuk membuat gateway Istio.
kubectl apply -f test-gateway.yaml
Buat layanan virtual.
Buat file bernama consumer.yaml dengan konten berikut.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: consumer spec: hosts: - "*" gateways: - test-gateway http: - match: - uri: prefix: / route: - destination: host: consumer.default.svc.cluster.local port: number: 8080Jalankan perintah berikut untuk membuat layanan virtual.
kubectl apply -f consumer.yaml
Langkah 4: Verifikasi pengelolaan layanan
Dapatkan alamat IP gerbang masuk.
-
Login ke Konsol ASM. Di panel navigasi kiri, pilih .
-
Di halaman Mesh Management, klik nama instans ASM. Di panel navigasi kiri, pilih .
Di halaman Ingress Gateway, lihat Service address gerbang masuk.
-
Jalankan perintah berikut untuk mengirim permintaan ke layanan consumer Spring Cloud melalui gerbang masuk.
curl <alamat IP gerbang masuk>/echo/worldOutput yang diharapkan:
Hello Nacos Discovery From v1world Hello Nacos Discovery From v2world Hello Nacos Discovery From v1world Hello Nacos Discovery From v2worldOutput tersebut menunjukkan bahwa permintaan diarahkan ke provider v1 dan v2 secara round-robin secara default.
Buat aturan tujuan dan layanan virtual.
Buat file bernama service-provider.yaml dengan konten berikut.
--- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: service-provider spec: host: service-provider subsets: - name: v1 labels: label: v1 - name: v2 labels: label: v2Jalankan perintah berikut untuk membuat aturan tujuan.
kubectl apply -f service-provider.yamlBuat file bernama service-provider1.yaml dengan konten berikut.
Layanan virtual berikut mengarahkan permintaan ke /echo/hello ke provider v1 dan mengarahkan semua permintaan lainnya ke provider v2.
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: service-provider spec: hosts: - service-provider http: - name: "hello-v1" match: - uri: prefix: "/echo/hello" route: - destination: host: service-provider subset: v1 - name: "default" route: - destination: host: service-provider subset: v2Jalankan perintah berikut untuk membuat layanan virtual.
kubectl apply -f service-provider1.yaml
Jalankan perintah berikut untuk mengirim permintaan ke layanan consumer Spring Cloud.
curl <alamat IP gerbang masuk>/echo/helloOutput yang diharapkan:
Hello Nacos Discovery From v1hello Hello Nacos Discovery From v1helloOutput tersebut menunjukkan bahwa semua permintaan ke
/echo/hellodiarahkan ke provider v1, sedangkan permintaan lainnya diarahkan ke provider v2. Hal ini mengonfirmasi bahwa Istio kini mengontrol traffic Spring Cloud, sehingga Anda dapat mengelola layanan menggunakan aturan routing Istio.
FAQ
Pemecahan masalah layanan Spring Cloud
Periksa apakah intersepsi traffic diaktifkan untuk port atau alamat IP Nacos.
Jika Anda menggunakan metode reverse_dns, Anda harus mengintersepsi alamat IP pod.
Jika Anda menggunakan metode skrip Lua, Anda harus mengintersepsi alamat IP Server Nacos dan alamat IP cluster.
Untuk mengintersepsi proses registrasi, Anda harus membuat EnvoyFilter sebelum workload dibuat. Jika workload sudah dibuat terlebih dahulu, Anda harus melakukan rolling update pada workload tersebut.
Pastikan Kubernetes Service bertipe ClusterIP tersedia untuk setiap layanan.
Periksa metode yang Anda gunakan untuk mengaktifkan dukungan Spring Cloud pada lapisan kontrol ASM.
Periksa versi sidecar layanan. Jika versi gambar sidecar lebih lama dari 1.13.4.32, hanya lapisan kontrol instans ASM yang telah ditingkatkan, bukan lapisan data. Anda perlu melakukan rolling update pada deployment layanan yang terpengaruh.