Proxy sidecar Alibaba Cloud Service Mesh (ASM) mendukung protokol WebSocket (RFC 6455) tanpa konfigurasi mesh tambahan untuk HTTP/1.1. WebSocket adalah protokol komunikasi yang memungkinkan komunikasi dua arah antara klien dan server. WebSocket melalui HTTP/2 memerlukan aturan tujuan (destination rule) dan Filter Envoy.
Topik ini memandu Anda menyebar (deploy) server dan klien WebSocket di ASM, lalu membuat koneksi WebSocket baik melalui HTTP/1.1 maupun HTTP/2.
HTTP/1.1 vs. HTTP/2: pilih mode yang tepat
Koneksi WebSocket dimulai sebagai permintaan HTTP standar dengan header Upgrade. Istio tidak dapat langsung mengenali protokol WebSocket, tetapi proxy sidecar menyediakan dukungan out-of-the-box. Cara mesh menangani upgrade tersebut bergantung pada versi HTTP:
| Mode | Perilaku | Konfigurasi | Kapan digunakan |
|---|---|---|---|
| HTTP/1.1 | Setiap koneksi WebSocket menggunakan satu koneksi TCP. Setelah respons dikembalikan untuk permintaan tersebut, koneksi ditutup. | Tidak diperlukan selain injeksi sidecar. | Sebagian besar kasus penggunaan. Jalur paling sederhana. |
| HTTP/2 | Beberapa permintaan dapat diproses secara paralel melalui satu koneksi. Permintaan yang lambat tidak memblokir permintaan lainnya. | Destination rule + Envoy filter. | Mesh HTTP/2 seragam atau ketika multiplexing koneksi menjadi penting. |
Envoy memperlakukan koneksi WebSocket sebagai aliran byte TCP. Envoy menghasilkan satu entri log akses per koneksi (bukan per pesan) dan hanya menulis entri tersebut setelah koneksi ditutup.
Prasyarat
Instans ASM dengan kluster Container Service for Kubernetes (ACK) yang telah ditambahkan. Untuk informasi lebih lanjut, lihat Buat instans ASM dan Tambahkan kluster ke instans ASM.
Injeksi sidecar diaktifkan untuk namespace target. Untuk informasi lebih lanjut, lihat Konfigurasikan kebijakan injeksi proxy sidecar. Semua contoh di bawah menggunakan namespace
default.
Langkah 1: Sebarkan server dan client WebSocket
Hubungkan ke kluster ACK
Hubungkan ke kluster ACK menggunakan kubectl. Untuk informasi lebih lanjut, lihat Dapatkan file kubeconfig kluster dan gunakan kubectl untuk terhubung ke kluster.
Menerapkan server WebSocket
Contoh ini menggunakan server WebSocket Python dari komunitas WebSocket. Untuk informasi lebih lanjut tentang menyesuaikan penyebaran server, lihat Deploy to Kubernetes.
Buat file bernama
websockets-server.yamldengan konten berikut:apiVersion: v1 kind: Service metadata: name: websockets-server labels: app: websockets-server spec: type: ClusterIP ports: - port: 8080 targetPort: 80 name: http-websocket selector: app: websockets-server --- apiVersion: apps/v1 kind: Deployment metadata: name: websockets-server labels: app: websockets-server spec: selector: matchLabels: app: websockets-server template: metadata: labels: app: websockets-server spec: containers: - name: websockets-test image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/istio-websockets-test:1.0 ports: - containerPort: 80Terapkan manifes ke namespace
default:kubectl apply -f websockets-server.yaml -n default
Menerapkan klien WebSocket
Citra klien WebSocket dibuat dari Dockerfile berikut:
FROM python:3.9-alpine
RUN pip3 install websocketsBuat file bernama
websockets-client.yamldengan konten berikut:apiVersion: v1 kind: Service metadata: name: websockets-client labels: app: websockets-client spec: type: ClusterIP ports: - port: 8080 targetPort: 80 name: http-websockets-client selector: app: websockets-client --- apiVersion: apps/v1 kind: Deployment metadata: name: websockets-client-sleep labels: app: websockets-client spec: selector: matchLabels: app: websockets-client template: metadata: labels: app: websockets-client spec: containers: - name: websockets-client image: registry.cn-beijing.aliyuncs.com/aliacs-app-catalog/istio-websockets-client-test:1.0 command: ["sleep", "14d"]Terapkan manifes ke namespace
default:kubectl apply -f websockets-client.yaml -n default
Langkah 2: Buat koneksi WebSocket melalui HTTP/1.1
WebSocket melalui HTTP/1.1 tidak memerlukan konfigurasi mesh tambahan. Setelah server dan klien diterapkan, uji koneksi secara langsung.
Buka shell di pod client
Gunakan salah satu metode berikut:
Opsi A: Konsol ACK
Masuk ke Konsol ACK. Di panel navigasi sebelah kiri, klik Clusters.
Pada halaman Clusters, temukan kluster target dan klik namanya. Di panel sebelah kiri, pilih .
Pada halaman Pods, temukan
websockets-clientdan klik Terminal di kolom Actions. Lalu, klik websockets-client.
Opsi B: kubectl
kubectl exec -it -n <namespace> websockets-client-sleep... -c websockets-client -- shGanti <namespace> dengan namespace tempat klien diterapkan (misalnya, default).
Uji koneksi WebSocket
Hubungkan ke server WebSocket:
python3 -m websockets ws://websockets-server.<namespace>.svc.cluster.local:8080Output yang diharapkan:
Connected to ws://websockets-server.default.svc.cluster.local:8080.Ketik hello dan world untuk memverifikasi bahwa server echo mengembalikan setiap pesan:
> hello
< hello
> world
< world
Connection closed: 1000 (OK).Verifikasi log proxy sidecar
Periksa log kedua proxy sidecar untuk memastikan koneksi WebSocket menggunakan HTTP/1.1.
Log proxy sidecar sisi klien:
Pada halaman Pods, klik nama pod klien WebSocket.
Klik tab Logs dan pilih istio-proxy dari daftar drop-down Container.
Log berisi entri dengan protocol: HTTP/1.1:
{..."upstream_host":"10.208.0.105:80","bytes_sent":23,"protocol":"HTTP/1.1",...}Log proxy sidecar sisi server:
Pada halaman Pods, klik nama pod server WebSocket.
Klik tab Logs dan pilih istio-proxy dari daftar drop-down Container.
Log juga menampilkan protocol: HTTP/1.1:
{..."downstream_local_address":"10.208.0.105:80","upstream_local_address":"127.0.**.**:53983","protocol":"HTTP/1.1",...}Langkah 3: Buat koneksi WebSocket melalui HTTP/2
Untuk melakukan multiplexing aliran WebSocket melalui HTTP/2, konfigurasikan destination rule dan Envoy filter. Alur transformasi protokol bekerja sebagai berikut:
Client (HTTP/1.1 Upgrade) --> Client sidecar --> HTTP/2 CONNECT --> Server sidecar --> HTTP/1.1 Upgrade --> ServerKlien mengirim permintaan upgrade WebSocket HTTP/1.1 standar. Sidecar sisi klien meningkatkannya ke HTTP/2 dan meneruskannya ke sidecar sisi server, yang kemudian meneruskannya ke aplikasi.
Pada versi Istio sebelum 1.12, koneksi WebSocket tidak dapat ditingkatkan dari HTTP/1.1 ke HTTP/2. Mesh akan mengembalikan kode status HTTP 503. Jika Anda melihat error 503 saat menghubungkan, periksa versi Istio Anda. Pada versi sebelum 1.12, atur h2UpgradePolicy ke DO_NOT_UPGRADE dalam destination rule agar WebSocket tetap menggunakan HTTP/1.1:
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
labels:
provider: asm
name: websockets-server
spec:
host: websockets-server
trafficPolicy:
connectionPool:
http:
h2UpgradePolicy: DO_NOT_UPGRADEUntuk Istio 1.12 atau versi yang lebih baru, ikuti langkah-langkah berikut.
Buat aturan tujuan
Masuk ke Konsol ASM.
Di panel navigasi sebelah kiri, pilih .
Pada halaman Mesh Management, temukan instans ASM target. Klik nama instans atau klik Manage di kolom Actions.
Di panel navigasi sebelah kiri halaman detail, pilih . Pada halaman yang muncul, klik Create from YAML.
Pilih default dari daftar drop-down Namespace, tempel YAML berikut ke editor kode, lalu klik Create: Mengatur
h2UpgradePolicykeUPGRADEmengaktifkan HTTP/2 untuk koneksi ke server WebSocket.apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: labels: provider: asm name: websockets-server spec: host: websockets-server trafficPolicy: connectionPool: http: h2UpgradePolicy: UPGRADE
Buat Envoy filter
Secara default, WebSocket tidak berfungsi dengan protokol HTTP/2. Namun, Envoy mendukung tunneling WebSocket melalui HTTP/2. Atur parameter allow_connect ke true pada sidecar sisi server agar koneksi HTTP/2 didukung oleh server WebSocket.
Masuk ke Konsol ASM.
Di panel navigasi sebelah kiri, pilih .
Pada halaman Mesh Management, temukan instans ASM target. Klik nama instans atau klik Manage di kolom Actions.
Di panel navigasi sebelah kiri halaman detail, pilih .
Pada halaman Market Place, klik Template that sets the allow_connect parameter to true to allow updated protocol connections.
Pada halaman Plugin Detail, klik tab Plugin Config. Di bagian Plugin Effective scope, pilih Workload Scope, lalu klik Add workloads to effective scope.
Pada kotak dialog Add workloads to effective scope, atur parameter sebagai berikut:
Namespace: default
Workload Type: Deployment
Di bagian Select workloads, pilih websockets-server, klik ikon
untuk memindahkannya ke bagian selected, lalu klik OK.
Di editor kode YAML bagian Plugin Config, masukkan
patch_context: SIDECAR_INBOUND, aktifkan Plugin Switch, lalu tunggu hingga plug-in diaktifkan.
Setelah plug-in diaktifkan, ASM secara otomatis membuat Envoy filter. YAML yang dihasilkan mirip dengan berikut:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: h2-upgrade-wss
labels:
asm-system: 'true'
provider: asm
spec:
workloadSelector:
labels:
app: websockets-server
configPatches:
- applyTo: NETWORK_FILTER
match:
context: SIDECAR_INBOUND
proxy:
proxyVersion: '^1\.*.*'
listener:
filterChain:
filter:
name: "envoy.filters.network.http_connection_manager"
patch:
operation: MERGE
value:
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
http2_protocol_options:
allow_connect: trueUji koneksi WebSocket melalui HTTP/2
Jalankan perintah berikut dari pod klien:
python3 -m websockets ws://websockets-server.<namespace>.svc.cluster.local:8080Output yang diharapkan:
Connected to ws://websockets-server.default.svc.cluster.local:8080.Ketik hello dan world untuk memverifikasi respons echo:
> hello
< hello
> world
< world
Connection closed: 1000 (OK).Verifikasi upgrade protokol dalam log proxy sidecar
Log proxy sidecar sisi klien:
Pada halaman Pods, klik nama pod klien WebSocket.
Klik tab Logs dan pilih istio-proxy dari daftar drop-down Container.
Log sisi klien menampilkan protocol: HTTP/1.1 karena klien menginisiasi permintaan sebagai HTTP/1.1:
{..."authority":"websockets-server.default.svc.cluster.local:8080","upstream_service_time":null,"protocol":"HTTP/1.1",...}Log proxy sidecar sisi server:
Pada halaman Pods, klik nama pod server WebSocket.
Klik tab Logs dan pilih istio-proxy dari daftar drop-down Container.
Log sisi server menampilkan protocol: HTTP/2, yang mengonfirmasi bahwa sidecar telah meningkatkan koneksi tersebut:
{..."method":"GET","upstream_local_address":"127.0.**.**:34477","protocol":"HTTP/2",...}