1 - 支持 UDP Listener
Istio 并不会处理 UDP 类型的服务,当我们需要在 Ingress Gateway 上对外提供 UDP 服务时,可以通过 EnvoyFilter 来实现。
创建用于测试的 UDP 服务
创建一个 coredns,用于作为后端的测试 UDP 服务。
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: coredns
namespace: default
labels:
app: coredns
spec:
ports:
- name: udp-dns
port: 53
protocol: UDP
targetPort: 53
selector:
app: coredns
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: coredns
labels:
app: coredns
spec:
selector:
matchLabels:
app: coredns
template:
metadata:
labels:
app: coredns
spec:
containers:
- args:
- -conf
- /root/Corefile
image: coredns/coredns
name: coredns
volumeMounts:
- mountPath: /root
name: conf
volumes:
- configMap:
defaultMode: 420
name: coredns
name: conf
---
apiVersion: v1
kind: ConfigMap
metadata:
name: coredns
data:
Corefile: |
.:53 {
forward . 8.8.8.8 9.9.9.9
log
errors
}
foo.bar.com:53 {
whoami
}
EOF
创建一个用于测试的 network-tool pod,该 pod 中包含了 dig 命令行工具。
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
name: network-tool
annotations:
sidecar.istio.io/inject: "true"
spec:
containers:
- name: network-tool
image: zhaohuabing/network-tool
securityContext:
capabilities:
add:
- NET_ADMIN
EOF
此时通过 network-tool 中的 dig 工具去查询 foo.bar.com 这个域名,可以查询成功。
➜ ~ kubectl exec network-tool -- dig @10.244.0.20 -p 53 foo.bar.com
; <<>> DiG 9.18.1-1ubuntu1.3-Ubuntu <<>> @10.244.0.20 -p 53 foo.bar.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48665
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: 79265989d39004a6 (echoed)
;; QUESTION SECTION:
;foo.bar.com. IN A
;; ADDITIONAL SECTION:
foo.bar.com. 0 IN A 10.244.0.21
_udp.foo.bar.com. 0 IN SRV 0 0 37336 .
;; Query time: 1 msec
;; SERVER: 10.244.0.20#53(10.244.0.20) (UDP)
;; WHEN: Tue Apr 11 02:41:01 UTC 2023
;; MSG SIZE rcvd: 114
通过 EnvoyFilter 在 Ingress Gateway 创建 UDP Listener 和 对应的 Cluster
EnvoyFilter 如下所示,该 EnvoyFilter 在 Ingress Gateway 上创建了一个 UDP Listener,该 UDP Listener 在 5300 端口上监听来自客户端的请求,并将请求转发到后端的 Coredns 服务上。
备注: 此处的 EnvoyFilter 中硬编码了 Cluster 中 Endpoint 地址。由于 UDP 服务的 pod 地址会变化,因此在实际使用时,我们需要编写一个 Controller 来监听 UDP 服务,以动态生成该 EnvoyFilter。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: udp-listener
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: LISTENER
match:
context: GATEWAY
patch:
operation: ADD
value:
name: udp_listener
address:
socket_address:
protocol: UDP
address: 0.0.0.0
port_value: 5300
udp_listener_config:
downstream_socket_config:
max_rx_datagram_size: 9000
listener_filters:
- name: envoy.filters.udp_listener.udp_proxy
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.UdpProxyConfig
stat_prefix: coredns
matcher:
on_no_match:
action:
name: route
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.udp.udp_proxy.v3.Route
cluster: coredns
- applyTo: CLUSTER
match:
context: GATEWAY
patch:
operation: ADD
value:
name: coredns
type: STATIC
lb_policy: ROUND_ROBIN
load_assignment:
cluster_name: coredns
endpoints:
- lb_endpoints:
- endpoint:
address:
socket_address:
address: 10.244.0.20
port_value: 53
此时通过 network-tool 中的 dig 命令访问 Ingress Gateway 的 5300 端口,可以查询到 foo.bar.com 的 地址,说明 UDP Listener 创建成功。
➜ ~ kubectl exec network-tool -- dig @10.244.0.14 -p 5300 foo.bar.com
; <<>> DiG 9.18.1-1ubuntu1.3-Ubuntu <<>> @10.244.0.14 -p 5300 foo.bar.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32291
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
; COOKIE: c4486921ff737611 (echoed)
;; QUESTION SECTION:
;foo.bar.com. IN A
;; ADDITIONAL SECTION:
foo.bar.com. 0 IN A 10.244.0.14
_udp.foo.bar.com. 0 IN SRV 0 0 32875 .
;; Query time: 1 msec
;; SERVER: 10.244.0.14#5300(10.244.0.14) (UDP)
;; WHEN: Tue Apr 11 02:51:43 UTC 2023
;; MSG SIZE rcvd: 114
2 - directResoponse
有时候我们希望 gateway/sidecar 能直接向客户端返回一个 HTTP response,而不用交给应用程序处理。
1.15 版本之前
可以通过 EnvoyFilter 来修改 HTTP Route,为匹配某个条件的 HTTP 请求直接返回指定的内容。例如,下面的 EnvoyFilter 为 ingress gateway 收到的 http://*:80/direct 直接返回一个 200 response,消息体为 hello world
。:
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: direct
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: HTTP_ROUTE
match:
context: GATEWAY
routeConfiguration:
portNumber: 80
patch:
operation: INSERT_FIRST
value:
name: direct
match:
path: /direct
directResponse:
body:
inlineString: 'hello world'
status: 200
1.15 及之后版本
1.15 版本开始,VS 支持设置 directResponse,如下所示:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
exact: /v1/getProductRatings
directResponse:
status: 503
body:
string: "unknown error"
...
参考文档
3 - 为 TCP 长链接周期输出访问日志
缺省情况下,TCP 的访问日志只会在链接结束后再输出,对于长链接来说,会在链接建立后很长时间都无法看到访问日志。我们可以通过下面的 EnvoyFilter 来实现周期性的输出访问日志。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: periodical-access-log
namespace: istio-system # apply to all sidecars
spec:
configPatches:
- applyTo: NETWORK_FILTER
match:
listener:
filterChain:
filter:
name: "envoy.filters.network.tcp_proxy"
patch:
operation: MERGE
value:
name: "envoy.filters.network.tcp_proxy"
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.network.tcp_proxy.v3.TcpProxy"
access_log_flush_interval: 5s
应用该 EnvoyFilter 后,Sidecar Proxy 每隔 5s 就会输出一次访问日志。如下所示:
[2023-05-15T10:37:08.842Z] "- - -" 0 - - - "-" 3 0 - - "-" "-" "-" "-" "10.244.0.70:9080" outbound|9080||productpage.default.svc.cluster.local 10.244.0.72:41238 10.96.219.213:9080 10.244.0.72:53492 - -
[2023-05-15T10:37:08.842Z] "- - -" 0 - - - "-" 3 0 - - "-" "-" "-" "-" "10.244.0.70:9080" outbound|9080||productpage.default.svc.cluster.local 10.244.0.72:41238 10.96.219.213:9080 10.244.0.72:53492 - -
[2023-05-15T10:37:08.842Z] "- - -" 0 - - - "-" 3 0 - - "-" "-" "-" "-" "10.244.0.70:9080" outbound|9080||productpage.default.svc.cluster.local 10.244.0.72:41238 10.96.219.213:9080 10.244.0.72:53492 - -
[2023-05-15T10:37:08.842Z] "- - -" 0 - - - "-" 3 0 - - "-" "-" "-" "-" "10.244.0.70:9080" outbound|9080||productpage.default.svc.cluster.local 10.244.0.72:41238 10.96.219.213:9080 10.244.0.72:53492 - -