MQTT debuggen via websockets op Envoy 1.28.0
Ik heb onze Envoy-installatie gemigreerd van Envoy 1.11.1 naar 1.28.0 en gebruik nu ook SNI voor het selecteren van het juiste certificaat.
Een groot deel van die migratie is het upgraden van de syntax van de configuratie voor Envoy van de v2 API naar de v3 API.
De upgrade ging goed, behalve dat onze websocket-gebaseerde MQTT service (gebaseerd op VerneMQ) niet werkte zoals verwacht.
In eerste instantie nam ik aan dat het probleem in envoy zat. Na veel time-out opties geprobeerd te hebben, en de envoy documentatie bekeken te hebben, heb ik besloten om te experimenteren met een nieuwe route, en een andere broker (Mosquitto) erachter.
De volgende configuratie werkt met Mosquitto als broker, voor het geval iemand anders tegen hetzelfde probleem aanloopt.
Hier is een uittreksel van mijn envoy.yaml (de volledige configuratie is meer dan 87000 regels, gegenereerd door een sjabloon script, vanwege de SNI en het hebben van individuele luisteraars per domein zoals ik hierboven vermeldde):
statische_bronnen:
luisteraars:
- adres:
socket_adres:
address: 0.0.0.0
poort_waarde: 443
per_verbinding_buffer_limiet_bytes: 32768 # 32 KiB
listener_filters:
- naam: tls_inspector
getypt_config:
"@type": type.googleapis.com/envoy.extensions.filters.listener.tls_inspector.v3.TlsInspector
filter_ketens:
- filter_chain_match:
server_namen: ["picockpit.com","www.picockpit.com","picockpit.com:443","www.picockpit.com:443"]
transport_socket:
naam: envoy.transport_sockets.tls
getypt_config:
"@type": type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.DownstreamTlsContext
gemeenschappelijke_tls_context:
tls_certificaten:
- certificate_chain: { bestandsnaam: "/certs/letsencrypt/live/picockpit.com/fullchain.pem" }
private_key: { bestandsnaam: "/certs/letsencrypt/live/picockpit.com/privkey.pem" }
alpn_protocollen: [ "h2,http/1.1" ]
filters:
- naam: envoy.filters.network.http_connection_manager
getypt_config:
'@type': type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
codec_type: AUTO
http_filters:
- naam: envoy.filters.http.compressor
getypt_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.compressor.v3.Compressor
compressor_bibliotheek:
naam: tekst_geoptimaliseerd
getypt_config:
'@type': type.googleapis.com/envoy.extensions.compression.gzip.compressor.v3.Gzip
compressie_niveau: BEST_SPEED
compressie_strategie: STANDAARD_STRATEGIE
geheugenniveau: 9
window_bits: 15
brok_grootte: 16384
- naam: envoy.filters.http.router
getypt_config:
"@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
gemeenschappelijke_http_protocol_opties:
idle_timeout: 3600s # 1 uur
gebruik_remote_adres: waar
xff_num_trusted_hops: 0
route_config:
virtual_hosts:
- naam: backend
domeinen: ["picockpit.com", "www.picockpit.com", "picockpit.com:443", "www.picockpit.com:443"]
routes:
- match: {pad: "/pidoctor"}
redirect:
path_redirect: "/raspberry-pi/pidoctor-raspberry-pi-system-health-monitor/"
- match: { prefix: "/pidoctor/"}
redirect:
path_redirect: "/raspberry-pi/pidoctor-raspberry-pi-system-health-monitor/"
- match: { prefix: "/mqtt/test" }
route:
prefix_rewrite: "/mqtt
cluster: doel_test
timeout: 0s
idle_timeout: 0s
upgrade_configuraties:
- upgrade_type: "websocket".
ingeschakeld: waar
- match: { prefix: "/" }
route:
cluster: doel_hoofd
time-out: 0s
clusters:
- naam: doel_test
verbindingstijd: 5s
per_verbinding_buffer_limiet_bytes: 32768 # 32 KiB
type: STRICT_DNS
lb_beleid: ROUND_ROBIN
load_assignment:
cluster_naam: doel_test
eindpunten:
- lb_endpoints:
- eindpunt:
adres:
socket_adres:
adres: mosquitto-test.test-netwerk
poort_waarde: 8025
Merk op dat ik een groot deel van de configuratie van andere diensten, routes, heb weggelaten en dat ik de target_main clusterinformatie niet heb gegeven (omdat deze irrelevant is voor de MQTT over websockets situatie).
Let op de timeout: 0s waarde, die belangrijk is voor MQTT verbindingen om door te gaan in plaats van te worden getimed na 15sec zoals standaard het geval is.
Ik heb ook andere delen gemarkeerd die naar mijn mening relevant zijn om verbindingen te upgraden naar websockets (zodat MQTT er doorheen kan). Let ook op de poortnummers worden doorgegeven als extra domeinovereenkomsten.
Mosquitto docker-compose.yml:
versie: "3.6
diensten:
mosquitto:
image: eclipse-mosquitto
containernaam: mosquitto-test
hostnaam: mosquitto-test
netwerken:
- test_net
herstarten: "nee
gebruiker: "root:root"
volumes:
- type: binden
bron: ./mosquitto.conf
doel: /mosquitto/config/mosquitto.conf
netwerken:
test_net:
extern:
naam: test-netwerk
mosquitto.conf:
luisteraar 8025
protocol websockets
allow_anonymous true
log_type alle
Tool om de verbinding te controleren:
Update 13.11.2023
MQTT is weer online, ook met VerneMQ:
Hoewel ik VerneMQ verschillende keren opnieuw had opgestart, had ik blijkbaar niet lang genoeg gewacht om het te stabiliseren. Een collega herstartte het vandaag en nu werkt het. Het lijkt erop dat het 10 - 15 minuten duurt (in onze setup) om volledig responsief te worden en goed te werken.
Daarom kan ik bevestigen dat de bovenstaande configuratie voor envoy ook werkt met VerneMQ.
Geleerde les
Als iets niet werkt, probeer het probleem te reproduceren in de wisselwerking met een ander hulpmiddel - Als het daar werkt, dan zit het probleem mogelijk niet in het eerste gereedschap dat u hebt gewijzigd, maar in het tweede gereedschap waarmee het moet werken.
en nog wat extra lekkers:
Online Documentatie
- https://www.envoyproxy.io/docs
- https://www.envoyproxy.io/docs/envoy/v1.28.0/ (specifiek voor de huidige envoy-versie)
- https://github.com/envoyproxy/envoy/blob/main/configs/envoyproxy_io_proxy_http3_downstream.yaml - voorbeeld HTTP3-configuratie
- https://codilime.com/blog/envoy-configuration/ - Begrip Afgezant
- https://pi3g.com/envoy-docker-and-websockets-debugging-and-configuration/ - over websockets en envoy (websockets worden in PiCockpit gebruikt om MQTT te transporteren) - dit vorige artikel is gebaseerd op v1.11.1 van envoy
Handige hulpmiddelen
- https://http3check.net/ - maakt het mogelijk om te controleren op HTTP/3 ondersteuning
- HiveMQ websocket-client