Anda dapat menghubungkan aplikasi Spring Cloud ke Service Mesh (ASM) untuk memanfaatkan kemampuan tata kelola layanan cloud-native tanpa perlu memodifikasi kode aplikasi. Topik ini menjelaskan cara menggunakan ASM untuk mengelola layanan Spring Cloud.
Prasyarat
Sebuah instance ASM Edisi Enterprise atau Edisi Ultimate telah dibuat. Untuk informasi lebih lanjut, lihat Buat instance ASM.
Sebuah klaster ACK dikelola telah dibuat. Untuk informasi lebih lanjut, lihat Buat klaster ACK dikelola.
Sebuah gateway ingress telah diterapkan. Untuk informasi lebih lanjut, lihat Buat gateway ingress.
Informasi latar belakang
Spring Cloud adalah standar dengan berbagai implementasi, seperti Spring Cloud Netflix, Spring Cloud Alibaba, dan Spring Cloud Consul. Dalam konteks ASM, perbedaan utama antara implementasi Spring Cloud terletak pada registri layanan. Tabel berikut menunjukkan apakah aplikasi yang dikembangkan menggunakan implementasi Spring Cloud tertentu dapat bermigrasi ke ASM.
Implementasi Spring Cloud | Registri layanan | Apakah migrasi didukung tanpa modifikasi kode |
Spring Cloud Alibaba | Microservices Engine (MSE) Nacos (sebuah layanan Alibaba Cloud) | Ya |
Spring Cloud Alibaba | Nacos mandiri | Ya |
Spring Cloud Netflix | Eureka | Didukung. Versi instance ASM harus 1.13.4.53 atau lebih baru. |
Spring Cloud Consul | Consul | Didukung. Versi instance ASM harus 1.13.4.53 atau lebih baru. |
Spring Cloud Zookeeper | Zookeeper | Didukung. Versi instance ASM harus 1.13.4.53 atau lebih baru. |
Pengenalan demo
Dalam contoh ini, Spring Cloud dengan registri Nacos digunakan. Anda dapat mengunduh kode contoh demo dari repositori nacos-examples di GitHub.
Layanan Spring Cloud mencakup layanan konsumen dan layanan penyedia. Layanan penyedia memiliki dua versi: V1 dan V2. Kedua versi layanan penyedia terdaftar di registri Nacos. Layanan konsumen mendapatkan titik akhir dari kedua versi layanan penyedia dari registri Nacos dan mengirim permintaan ke titik akhir tersebut secara seimbang beban. Layanan konsumen mengekspos port 8080 dan menyediakan antarmuka echo. Setelah permintaan diteruskan ke layanan penyedia, layanan penyedia mengembalikan respons yang sesuai, lalu layanan konsumen memberikan respons tersebut. Versi layanan penyedia yang berbeda mengembalikan respons yang berbeda.
Layanan penyedia V1 merespons permintaan echo dengan informasi berikut:
Hello Nacos Discovery From v1xxxLayanan penyedia V2 merespons permintaan echo dengan informasi berikut:
Hello Nacos Discovery From v2xxx
String xxx dalam respons menunjukkan parameter spesifik dalam permintaan echo yang sesuai. Sebagai contoh, jika permintaan /echo/world dikirim ke layanan penyedia V1, respons Hello Nacos Discovery From v1world akan dikembalikan.
Jika layanan konsumen dan penyedia tidak diterapkan di instance ASM, yaitu injeksi proxy sidecar tidak diaktifkan untuk pod layanan, Anda dapat mengakses layanan tetapi tidak dapat mengelola layanan menggunakan sumber daya Istio.
Langkah 1: Aktifkan dukungan untuk Spring Cloud di bidang kontrol ASM
Metode 1: Berlaku untuk semua implementasi dan registri Spring Cloud
Versi instance ASM harus 1.13.4.32 atau lebih baru.
Batasan:
Layanan Kubernetes harus dibuat sebagai layanan tujuan. Port layanan dan port tujuan harus merupakan port tempat aplikasi dirutekan melalui instance Server Load Balancer (SLB).
Jika instance ASM versi 1.23.6.32 atau lebih baru digunakan, Anda harus menonaktifkan REGISTRY_ONLY.
Gunakan kubectl untuk terhubung ke klaster di bidang kontrol. Untuk informasi lebih lanjut, lihat Gunakan kubectl di bidang kontrol untuk mengakses sumber daya Istio.
Buat filter Envoy di klaster ACK yang ditambahkan ke instance 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"Modifikasi pengaturan parameter dalam file berdasarkan kebutuhan bisnis Anda. Beberapa parameter dijelaskan sebagai berikut:
portNumber: menentukan nomor port layanan Spring Cloud. Jika ada beberapa port, Anda dapat menghapus parameter ini. Jika port dapat dikonvergen, Anda dapat membuat beberapa filter Envoy dan mengonfigurasi nomor port di setiap filter Envoy.pod_cidrs: menentukan blok CIDR pod dari klaster ACK atau ACK Serverless. Masuk ke Container Service for Kubernetes (ACK) console, buka halaman Clusters dan klik klaster yang diinginkan. Di halaman detail klaster yang muncul, klik tab Cluster Resources. Lalu, klik tautan di bagian VPC untuk melihat blok CIDR dari vSwitch di VPC.
Jalankan perintah berikut untuk mengaktifkan filter
com.aliyun.reverse_dnsuntuk layanan:kubectl apply -f any-spring-cloud-support.yaml
Method 2: Applicable to only Nacos registries
Gunakan kubectl untuk terhubung ke klaster di bidang kontrol. Untuk informasi lebih lanjut, lihat Gunakan kubectl di bidang kontrol untuk mengakses sumber daya Istio.
Buat entri layanan.
Buat file external-nacos-svc.yaml yang berisi konten berikut:
kind: ServiceEntry metadata: name: external-nacos-svc spec: hosts: - "NACOS_SERVER_HOST" ## Ganti variabel ini dengan titik akhir host server Nacos Anda. Contoh: mse-xxx-p.nacos-ans.mse.aliyuncs.com. location: MESH_EXTERNAL ports: - number: 8848 name: http resolution: DNSDalam file YAML sebelumnya, port
8848adalah port default yang digunakan oleh Nacos. Jika Anda menggunakan server Nacos mandiri dan port berbeda, atur parameternumberke nomor port yang Anda gunakan.Jalankan perintah berikut untuk membuat entri layanan:
kubectl apply -f external-nacos-svc.yaml
Buat filter Envoy.
Buat file external-envoyfilter.yaml yang berisi 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: # Patch pertama menambahkan filter lua ke 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: # Spesifikasi filter lua name: envoy.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inlineCode: | -- hak cipta: 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 filter Envoy:
kubectl apply -f external-envoyfilter.yaml
Langkah 2: Terapkan layanan Spring Cloud di klaster ACK
Pastikan filter Envoy dibuat sebelum Anda membuat deployment agar proses pendaftaran dapat dicegat. Jika deployment tertentu dibuat sebelum Anda membuat filter Envoy, Anda harus mengaktifkan pembaruan bergulir untuk deployment tersebut.
Untuk layanan Spring Cloud, Anda harus membuat sumber daya layanan Kubernetes dan menyediakan alamat IP klaster.
Gunakan kubectl untuk terhubung ke klaster di bidang data. Untuk informasi lebih lanjut, lihat Dapatkan file kubeconfig klaster dan gunakan kubectl untuk terhubung ke klaster.
Jalankan perintah berikut untuk menerapkan layanan Spring Cloud:
export NACOS_ADDRESS=xxxx # Ganti xxxx dengan titik akhir registri MSE Nacos atau registri Nacos mandiri. Kami sarankan Anda menggunakan titik akhir virtual private cloud (VPC). 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 gateway Istio dan layanan virtual
Buat gateway Istio.
Buat file test-gateway.yaml yang berisi konten berikut:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: test-gateway spec: selector: istio: ingressgateway # gunakan pengontrol default istio servers: - port: number: 80 name: http protocol: HTTP hosts: - "*"Gunakan kubectl untuk terhubung ke instance ASM berdasarkan informasi dalam file kubeconfig, lalu jalankan perintah berikut untuk membuat gateway Istio:
kubectl apply -f test-gateway.yaml
Buat layanan virtual.
Buat file consumer.yaml yang berisi 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: Periksa apakah ASM dapat mengelola layanan Spring Cloud
Kueri alamat IP gateway ingress.
Masuk ke Konsol ASM. Di panel navigasi kiri, pilih .
Pada halaman Mesh Management, klik nama instance ASM. Di panel navigasi kiri, pilih .
Di halaman Ingress Gateway, periksa Service address dari gateway ingress.
Jalankan perintah berikut untuk memulai permintaan dari gateway ingress ke layanan konsumen Spring Cloud:
curl <Alamat IP gateway ingress>/echo/worldOutput yang diharapkan:
Hello Nacos Discovery From v1world Hello Nacos Discovery From v2world Hello Nacos Discovery From v1world Hello Nacos Discovery From v2worldOutput menunjukkan bahwa lalu lintas dirutekan ke V1 dan V2 layanan penyedia dalam mode polling secara default.
Buat aturan tujuan dan layanan virtual.
Buat file 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 service-provider1.yaml dengan konten berikut.
Layanan virtual yang dibuat akan mendefinisikan bahwa permintaan ke /echo/hello dirutekan ke layanan penyedia V1, sedangkan permintaan lainnya dirutekan ke layanan penyedia 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 memulai permintaan ke layanan konsumen Spring Cloud:
curl <Alamat IP gateway ingress>/echo/helloOutput yang diharapkan:
Hello Nacos Discovery From v1hello Hello Nacos Discovery From v1helloOutput menunjukkan bahwa permintaan
/echo/hellodirutekan ke layanan penyedia V1, sedangkan permintaan lainnya dirutekan ke layanan penyedia V2. Hal ini menunjukkan bahwa lalu lintas Spring Cloud dikelola oleh Istio dan Custom Resource Definitions (CRD) yang disediakan oleh Istio dapat digunakan untuk mengonfigurasi aturan routing. Dengan demikian, ASM dapat mengelola layanan Spring Cloud.
FAQ
Apa yang harus saya lakukan jika layanan Spring Cloud yang saya terapkan tidak berlaku?
Periksa apakah pemblokiran lalu lintas diaktifkan untuk port atau alamat IP Nacos.
Jika menggunakan pencarian DNS terbalik, Anda harus memblokir alamat IP pod.
Jika menggunakan skrip Lua, Anda harus memblokir alamat IP server Nacos dan alamat IP klaster.
Pastikan filter Envoy dibuat sebelum membuat deployment agar proses pendaftaran dapat dicegah. Jika deployment tertentu telah dibuat sebelum filter Envoy, aktifkan pembaruan bergulir untuk deployment tersebut.
Periksa apakah Anda telah membuat sumber daya layanan Kubernetes dan menyediakan alamat IP klaster untuk layanan Spring Cloud.
Lihat metode untuk mengaktifkan dukungan Spring Cloud di bidang kontrol ASM.
Periksa versi sidecar layanan. Jika versi image sidecar lebih awal dari 1.13.4.32, Anda mungkin hanya memperbarui bidang kontrol instance ASM tanpa memperbarui bidang data. Dalam hal ini, aktifkan pembaruan bergulir untuk deployment layanan.