WebAssembly untuk Proxies adalah spesifikasi baru yang memungkinkan pengembang menulis plug-in portabel menggunakan WebAssembly (Wasm). Plug-in ini dapat berjalan pada berbagai server proxy. Service Mesh (ASM) mendukung spesifikasi WebAssembly untuk Proxies. Topik ini menjelaskan cara menulis plug-in Wasm dalam Go untuk proxy Envoy di ASM.
Prasyarat
Sebuah kluster telah ditambahkan ke instance ASM versi 1.18 atau lebih baru. Untuk informasi lebih lanjut tentang cara menambahkan kluster ke instance ASM, lihat Tambahkan kluster ke instance ASM.
Injeksi proxy sidecar otomatis telah diaktifkan. Untuk informasi lebih lanjut, lihat Konfigurasikan kebijakan injeksi proxy sidecar.
Gateway masuk telah diterapkan. Untuk informasi lebih lanjut, lihat Buat gateway masuk.
Aplikasi HTTPBin telah diterapkan dan dapat diakses. Untuk informasi lebih lanjut tentang cara menerapkan aplikasi HTTPBin, lihat Terapkan aplikasi HTTPBin.
Sebuah instance Container Registry Enterprise Edition telah dibuat. Instance Container Registry Enterprise Edition mendukung gambar Open Container Initiative (OCI). Untuk informasi lebih lanjut, lihat Buat instance Container Registry Enterprise Edition.
Informasi latar belakang
Wasm adalah format biner yang sedang berkembang dan portabel untuk kode yang dapat dieksekusi. Kode tersebut dijalankan dengan kecepatan hampir asli dalam sandbox yang aman dari segi memori (untuk host). Sandbox memiliki batasan sumber daya yang jelas dan menyediakan API yang terdefinisi dengan baik untuk berkomunikasi dengan lingkungan host penyematan (di sini mengacu pada proxy).
Plug-in Wasm memberikan manfaat sebagai berikut:
Kelincahan: Anda dapat memperbarui plug-in tanpa memulai ulang proxy Envoy, sehingga permintaan dapat ditangani sesuai harapan.
Keandalan dan isolasi: Karena plug-in diterapkan di dalam sandbox dengan batasan sumber daya, mereka dapat gagal tanpa membuat proxy Envoy down.
Keamanan: Karena plug-in diterapkan di dalam sandbox dengan API yang terdefinisi dengan baik untuk berkomunikasi dengan proxy, mereka dikendalikan dengan baik.
Keragaman: Plug-in dapat ditulis dalam beberapa bahasa pemrograman, seperti C++, Go, dan Rust.
Untuk informasi lebih lanjut tentang plug-in Wasm, lihat WebAssembly-in-Envoy.md dan OVERVIEW.md.
Contoh konfigurasi
Dalam contoh ini, sebuah plug-in Wasm ditulis dalam Go. Setelah plug-in selesai ditulis, file biner Wasm dihasilkan, kemudian dikemas menjadi gambar. Gambar tersebut harus diunggah ke repositori gambar OCI. Setelah gambar diunggah, konfigurasikan sumber daya WasmPlugin di ASM dan terapkan plug-in ke proxy Envoy yang ditentukan.
Dalam contoh ini, sebuah plug-in dikembangkan untuk memeriksa apakah permintaan berisi header allow: true. Jika tidak, kode status 403 dan body yang ditentukan akan dikembalikan. Jika ya, aplikasi HTTPBin dapat diakses sesuai harapan.
Langkah 1: Siapkan lingkungan pengembangan
Untuk mengembangkan plug-in Wasm dalam Go untuk proxy Envoy, Anda harus menginstal alat-alat berikut terlebih dahulu:
Go: Kompiler Go dan alat terkait digunakan untuk menulis proyek Go. Untuk informasi lebih lanjut, lihat Bahasa Pemrograman Go.
Docker: Dalam contoh ini, Docker digunakan untuk membangun dan mendorong gambar OCI.
TinyGo: Go digunakan untuk menulis plug-in Wasm. Namun, Anda tidak dapat menggunakan kompiler Go resmi untuk mengompilasi kode Go ke format Wasm. Anda harus menggunakan TinyGo. Untuk informasi lebih lanjut tentang cara menginstal TinyGo, lihat Panduan instalasi cepat.
Untuk informasi lebih lanjut tentang SDK tempat plug-in Wasm bergantung, lihat proxy-wasm-go-sdk di situs web GitHub. Anda dapat menemukan kode lengkap dari Go SDK untuk Proxy-Wasm di situs web tersebut. Jika Anda ingin menggunakan SDK lainnya, rujuklah kode dari Go SDK untuk Proxy-Wasm.
Langkah 2: Tulis kode plug-in
Buat folder dan buat file main.go yang berisi konten berikut:
Jalankan perintah berikut di folder yang dibuat untuk mendapatkan dependensi SDK:
go mod init go mod tidyJalankan perintah berikut untuk mengompilasi kode menjadi file biner Wasm:
tinygo build -o plugin.wasm -scheduler=none -target=wasi main.goFile plugin.wasm dihasilkan. File ini adalah file biner Wasm yang dapat dieksekusi.
Langkah 3: Buat gambar OCI dari plug-in Wasm dan dorong ke instance Container Registry Enterprise Edition
Di folder yang dibuat di Langkah 2, buat file Dockerfile yang berisi konten berikut:
FROM scratch ADD ./plugin.wasm ./plugin.wasmJalankan perintah berikut untuk membuat gambar:
docker build -t header-authorization:v0.0.1 .Buat repositori gambar. Untuk informasi lebih lanjut, lihat sublangkah 2.a dan 2.b dari Langkah 1 dalam topik Gunakan plug-in Wasm Coraza untuk mengimplementasikan kemampuan WAF pada gateway ASM.
Dalam contoh ini, namespace adalah
test-ocidan nama repositori adalahheader-authorization. Gambar berikut menunjukkan repositori yang dibuat.
Untuk informasi lebih lanjut tentang cara mendorong gambar ke instance Container Registry Enterprise Edition, lihat Dorong gambar ke registri pada gambar sebelumnya.
Langkah 4: Terapkan plug-in Wasm ke gateway masuk
Konfigurasikan izin untuk menarik gambar. Untuk informasi lebih lanjut, lihat Langkah 2: Konfigurasikan izin untuk menarik gambar.
Jalankan perintah berikut untuk membuat Secret bernama
wasm-secret:kubectl create secret docker-registry -n istio-system wasm-secret --docker-server=${Nama domain instance Container Registry Enterprise Edition} --docker-username =${Username} --docker-password =${Password}Buat file asm-plugin.yaml yang berisi konten berikut:
apiVersion: extensions.istio.io/v1alpha1 kind: WasmPlugin metadata: name: header-authorization namespace: istio-system spec: imagePullPolicy: IfNotPresent imagePullSecret: wasm-secret selector: matchLabels: istio: ingressgateway url: oci://${Nama domain instance Container Registry Enterprise Edition}/test-oci/header-authorization:v0.0.1 phase: AUTHNGunakan kubectl untuk terhubung ke instance ASM berdasarkan informasi dalam file kubeconfig. Kemudian, jalankan perintah berikut untuk menerapkan plug-in Wasm ke instance ASM:
kubectl apply -f wasm-plugin.yaml
Langkah 5: Verifikasi bahwa plug-in Wasm berlaku
Gunakan file kubeconfig dari kluster pada bidang data tempat gateway masuk berada dan jalankan perintah berikut untuk mengaktifkan fitur pencatatan debug untuk plug-in Wasm yang diterapkan ke gateway masuk:
kubectl -n istio-system exec ${Nama pod tempat gateway masuk berada} -c istio-proxy -- curl -XPOST "localhost:15000/logging?wasm=debug"Jalankan perintah berikut untuk mengakses aplikasi HTTPBin yang diekspos melalui gateway masuk:
curl ${Alamat IP gateway masuk}/status/418Output yang diharapkan:
Forbidden by ASM Wasm PluginLihat log dari pod tempat gateway masuk berada.
Contoh log:
2024-03-08T08:16:46.747394Z debug envoy wasm external/envoy/source/extensions/common/wasm/context.cc:1168 wasm log istio-system.header-authorization: request header: 'allow' is , only true can passthrough thread=24 {"bytes_received":"0","bytes_sent":"28","downstream_local_address":"xxxxxxx","downstream_remote_address":"xxxxxxxx","duration":"0","istio_policy_status":"-","method":"GET","path":"/status/418","protocol":"HTTP/1.1","request_id":"780c8493-13e4-4f97-9771-486efe30347c","requested_server_name":"-","response_code":"403","response_flags":"-","route_name":"httpbin","start_time":"2024-03-08T08:16:46.747Z","trace_id":"-","upstream_cluster":"outbound|8000||httpbin.default.svc.cluster.local","upstream_host":"-","upstream_local_address":"-","upstream_service_time":"-","upstream_response_time":"-","upstream_transport_failure_reason":"-","user_agent":"curl/8.4.0","x_forwarded_for":"xxxxxx","authority_for":"xxxxxx"}Jalankan perintah berikut untuk mengakses aplikasi HTTPBin yang diekspos melalui gateway masuk:
curl ${Alamat IP gateway masuk}/status/418 -H "allow: true"Output yang diharapkan:
-=[ teapot ]=- _...._ .' _ _ `. | ."` ^ `". _, \_;`"---"`|// | ;/ \_ _/ `"""`Output tersebut menunjukkan bahwa aplikasi HTTPBin dapat diakses sesuai harapan.
Kebocoran memori di TinyGo
Kebocoran memori ada dalam plug-in Wasm untuk proxy Envoy yang dikompilasi menggunakan TinyGo. Komunitas proxy-wasm-go-sdk merekomendasikan agar Anda menggunakan nottinygc untuk optimasi kompilasi. Lakukan langkah-langkah berikut untuk menggunakan nottinygc untuk optimasi kompilasi:
Tambahkan kode
importberikut di awal file main.go:import _ "github.com/wasilibs/nottinygc"Jika tidak ada dependensi yang ditemukan, Anda dapat menjalankan perintah
go mod tidyuntuk secara otomatis mengunduh dependensi.Jalankan perintah berikut untuk mengompilasi kode:
tinygo build -o plugin.wasm -gc=custom -tags='custommalloc nottinygc_envoy' -target=wasi -scheduler=none main.goPerintah di atas menetapkan parameter
-gcdan-tags. Untuk informasi lebih lanjut, lihat nottinygc.