1什么是tcp_proxy
tcp_proxy是envoy用来处理tcp协议的一个network类型的filter。它和http_connection_manager一样是envoy中两个最重要的network filter。名称为 envoy.filters.network.tcp_proxy 。
2配置
{"stat_prefix": "...",stat前缀"cluster": "...",cluster名称"weighted_clusters": "{...}",加权cluster配置"metadata_match": "{...}",匹配元数据"idle_timeout": "{...}",空闲超时时间,默认1h"access_log": [],访问日志"max_connect_attempts": "{...}",最大失败尝试连接次数,默认1"hash_policy": [],hash策略"tunneling_config": "{...}",隧道配置"max_downstream_connection_duration": "{...}"最大下游连接时间}
weighted_clusters:
{"clusters": []集群配置}
clusters:
{"name": "...",集群名称"weight": "...",权重"metadata_match": "{...}"匹配元数据}
access_log:
{"name": "...",名称"filter": "{...}",过滤"typed_config": "{...}"配置}
hash_policy:
{"source_ip": "{...}"计算hash时使用源ip}
tunneling_config:
{"hostname": "...",主机名"use_post": "...",是否使用post方法"headers_to_add": []额外添加的头}
3实战
3.1准备工作
部署tcp echo
apiVersion: v1kind: Servicemetadata:name: tcp-echolabels:app: tcp-echoservice: tcp-echospec:ports:- name: tcpport: 9000- name: tcp-otherport: 9001# Port 9002 is omitted intentionally for testing the pass through filter chain.selector:app: tcp-echo---apiVersion: apps/v1kind: Deploymentmetadata:name: tcp-echo-v1labels:app: tcp-echoversion: v1spec:replicas: 1selector:matchLabels:app: tcp-echoversion: v1template:metadata:labels:app: tcp-echoversion: v1spec:containers:- name: tcp-echoimage: docker.io/istio/tcp-echo-server:1.2imagePullPolicy: IfNotPresentargs: [ "9000,9001,9002", "one" ]ports:- containerPort: 9000- containerPort: 9001---apiVersion: apps/v1kind: Deploymentmetadata:name: tcp-echo-v2labels:app: tcp-echoversion: v2spec:replicas: 1selector:matchLabels:app: tcp-echoversion: v2template:metadata:labels:app: tcp-echoversion: v2spec:containers:- name: tcp-echoimage: docker.io/istio/tcp-echo-server:1.2imagePullPolicy: IfNotPresentargs: [ "9000,9001,9002", "two" ]ports:- containerPort: 9000- containerPort: 9001
应用规则:
apiVersion: networking.istio.io/v1alpha3kind: Gatewaymetadata:name: tcp-echo-gatewayspec:selector:istio: ingressgatewayservers:- port:number: 31400name: tcpprotocol: TCPhosts:- "*"---apiVersion: networking.istio.io/v1alpha3kind: DestinationRulemetadata:name: tcp-echo-destinationspec:host: tcp-echosubsets:- name: v1labels:version: v1- name: v2labels:version: v2---apiVersion: networking.istio.io/v1alpha3kind: VirtualServicemetadata:name: tcp-echospec:hosts:- "*"gateways:- tcp-echo-gatewaytcp:- match:- port: 31400route:- destination:host: tcp-echoport:number: 9000subset: v1
3.1cluster
ef-tcp_proxy-cluster.yaml
kubectl apply -f ef-tcp_proxy-cluster.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxycluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localstatPrefix: outbound|9000|v2|tcp-echo.istio.svc.cluster.local
3.2weighted_clusters
ef-tcp_proxy-weighted_clusters.yaml
kubectl apply -f ef-tcp_proxy-weighted_clusters.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxyweighted_clusters:clusters:- name: outbound|9000|v2|tcp-echo.istio.svc.cluster.localweight: 50- name: outbound|9000|v1|tcp-echo.istio.svc.cluster.localweight: 50statPrefix: tcp-echo.istio.svc.cluster.local
3.3metadata_match
metadata测试不成功
3.3.1 metadata_match
ef-tcp_proxy-metadata_match.yaml
kubectl apply -f ef-tcp_proxy-metadata_match.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxycluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localstatPrefix: outbound|9000|v2|tcp-echo.istio.svc.cluster.localmetadata_match:filter_metadata:envoy.lb:version: 1.0
3.3.2 weighted_clusters metadata_match
ef-tcp_proxy-weighted_clusters-metadata_match.yaml
kubectl apply -f ef-tcp_proxy-weighted_clusters-metadata_match.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxyweighted_clusters:clusters:- name: outbound|9000|v2|tcp-echo.istio.svc.cluster.localweight: 50metadata_match:filter_metadata:envoy.lb:version: 1.0- name: outbound|9000|v1|tcp-echo.istio.svc.cluster.localweight: 50metadata_match:filter_metadata:envoy.lb:version: 1.0statPrefix: tcp-echo.istio.svc.cluster.local
3.4access_log
ef-tcp_proxy-access_log.yaml
kubectl apply -f ef-tcp_proxy-access_log.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxyaccessLog:- name: envoy.access_loggers.filetypedConfig:'@type': type.googleapis.com/envoy.extensions.access_loggers.file.v3.FileAccessLoglogFormat:textFormat: |[%START_TIME%] "%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%" %RESPONSE_CODE% %RESPONSE_FLAGS% %RESPONSE_CODE_DETAILS% %CONNECTION_TERMINATION_DETAILS% "%UPSTREAM_TRANSPORT_FAILURE_REASON%" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% "%REQ(X-FORWARDED-FOR)%" "%REQ(USER-AGENT)%" "%REQ(X-REQUEST-ID)%" "%REQ(:AUTHORITY)%" "%UPSTREAM_HOST%" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%path: /dev/stdoutcluster: outbound|9000|v1|tcp-echo.istio.svc.cluster.localstatPrefix: outbound|9000|v1|tcp-echo.istio.svc.cluster.local
3.5hash_policy
ef-tcp_proxy-hash_policy.yaml
kubectl apply -f ef-tcp_proxy-hash_policy.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxycluster: outbound|9000|v1|tcp-echo.istio.svc.cluster.localstatPrefix: tcp-echo.istio.svc.cluster.localhash_policy:- source_ip: {}- applyTo: CLUSTERmatch:cluster:name: outbound|9000|v1|tcp-echo.istio.svc.cluster.localpatch:operation: MERGEvalue:lb_policy: RING_HASHring_hash_lb_config:minimum_ring_size: 1024
一致性hash,是每个子集的多个节点的一致性hash
kubectl scale deploy -n istio tcp-echo-v1 --replicas=3
查看三个pod的日志:
kubectl logs -f -n istio tcp-echo-v1-65875b4c8c-zt5m4
3.6其他参数配置
ef-tcp_proxy-general.yaml
kubectl apply -f ef-tcp_proxy-general.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxycluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localstatPrefix: outbound|9000|v2|tcp-echo.istio.svc.cluster.localidle_timeout: 1hmax_connect_attempts: 1max_downstream_connection_duration: 10s
3.7tunneling_config
3.7.1 HTTP/1.1 CONNECT
ef-tcp_proxy-tunneling_config-hostname.yaml
kubectl apply -f ef-tcp_proxy-tunneling_config-hostname.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxystat_prefix: tcp_statscluster: "cluster_0"tunneling_config:hostname: host.com:443- applyTo: CLUSTERpatch:operation: ADDvalue:name: cluster_0connect_timeout: 5styped_extension_protocol_options:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicit_http_config:http_protocol_options: {}load_assignment:cluster_name: cluster_0endpoints:- lb_endpoints:- endpoint:address:socket_address:address: 127.0.0.1port_value: 10001- applyTo: LISTENERmatch:context: GATEWAYpatch:operation: ADDvalue:name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10001filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains:- "*"routes:- match:connect_matcher:{}route:cluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localupgrade_configs:- upgrade_type: CONNECTconnect_config:{}http_filters:- name: envoy.filters.http.routerhttp_protocol_options: {}upgrade_configs:- upgrade_type: CONNECT
3.7.2 HTTP/2 CONNECT
ef-tcp_proxy-http2_connect.yaml
kubectl apply -f ef-tcp_proxy-http2_connect.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxystat_prefix: tcp_statscluster: "cluster_0"tunneling_config:hostname: host.com:443- applyTo: CLUSTERpatch:operation: ADDvalue:name: cluster_0connect_timeout: 5styped_extension_protocol_options:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicit_http_config:http2_protocol_options: {}load_assignment:cluster_name: cluster_0endpoints:- lb_endpoints:- endpoint:address:socket_address:address: 127.0.0.1port_value: 10001- applyTo: LISTENERmatch:context: GATEWAYpatch:operation: ADDvalue:name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10001filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains:- "*"routes:- match:connect_matcher:{}route:cluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localupgrade_configs:- upgrade_type: CONNECTconnect_config:{}http_filters:- name: envoy.filters.http.routerhttp2_protocol_options:allow_connect: trueupgrade_configs:- upgrade_type: CONNECT
3.7.3 HTTP/2 POST
ef-tcp_proxy-http2_post.yaml
kubectl apply -f ef-tcp_proxy-http2_post.yaml -n istio-system
apiVersion: networking.istio.io/v1alpha3kind: EnvoyFiltermetadata:name: tcpspec:workloadSelector:labels:istio: ingressgatewayconfigPatches:- applyTo: NETWORK_FILTERmatch:context: GATEWAYlistener:portNumber: 31400filterChain:filter:name: "envoy.filters.network.tcp_proxy"patch:operation: REPLACEvalue:name: envoy.filters.network.tcp_proxytypedConfig:'@type': type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxystat_prefix: tcp_statscluster: "cluster_0"tunneling_config:hostname: host.com:443use_post: true- applyTo: CLUSTERpatch:operation: ADDvalue:name: cluster_0connect_timeout: 5styped_extension_protocol_options:envoy.extensions.upstreams.http.v3.HttpProtocolOptions:"@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptionsexplicit_http_config:http2_protocol_options: {}load_assignment:cluster_name: cluster_0endpoints:- lb_endpoints:- endpoint:address:socket_address:address: 127.0.0.1port_value: 10001- applyTo: LISTENERmatch:context: GATEWAYpatch:operation: ADDvalue:name: listener_0address:socket_address:protocol: TCPaddress: 0.0.0.0port_value: 10001filter_chains:- filters:- name: envoy.filters.network.http_connection_managertyped_config:"@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManagerstat_prefix: ingress_httproute_config:name: local_routevirtual_hosts:- name: local_servicedomains:- "*"routes:- match:prefix: "/"headers:- name: ":method"string_match:exact: "POST"route:cluster: outbound|9000|v2|tcp-echo.istio.svc.cluster.localupgrade_configs:- upgrade_type: CONNECTconnect_config:allow_post: truehttp_filters:- name: envoy.filters.http.routerhttp2_protocol_options:allow_connect: true




