TCP 流量
该任务向您展示了在 Istio 网格中如何为 TCP 流量设置 Istio 授权策略。
开始之前
在您开始之前,请先完成以下内容:
- 阅读 Istio 授权概念。 
- 根据 Istio 安装指南安装 Istio。 
- 在命名空间例如 - foo中部署两个工作负载:- curl和- tcp-echo。 这两个工作负载每个前面都会运行一个 Envoy 代理。- tcp-echo工作负载会监听 9000、9001 和 9002 端口,并以- hello为前缀输出它收到的所有流量。 例如,如果您发送- world给- tcp-echo,那么它将会回复- hello world。- tcp-echo的 Kubernetes Service 对象只声明了 9000 和 9001 端口,并省略了 9002 端口。 透传过滤器链将处理 9002 端口的流量。使用以下命令部署示例命名空间和工作负载:- $ kubectl create ns foo $ kubectl apply -f <(istioctl kube-inject -f @samples/tcp-echo/tcp-echo.yaml@) -n foo $ kubectl apply -f <(istioctl kube-inject -f @samples/curl/curl.yaml@) -n foo
- 使用以下命令验证 - curl可以成功与- tcp-echo的 9000 和 9001 端口通信:- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
- 确认 - curl可以成功与- tcp-echo的 9002 端口通信。 您需要将流量直接发送到- tcp-echo的 Pod IP,因为在- tcp-echo的 Kubernetes Service 对象中未定义端口 9002。 获取 Pod IP 地址,并使用以下命令发送请求:- $ TCP_ECHO_IP=$(kubectl get pod "$(kubectl get pod -l app=tcp-echo -n foo -o jsonpath={.items..metadata.name})" -n foo -o jsonpath="{.status.podIP}") $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9002 connection succeeded
为 TCP 工作负载配置 ALLOW 授权策略
- 在 - foo命名空间中为- tcp-echo工作负载创建- tcp-policy授权策略。 运行以下命令来应用策略以允许请求到 9000 和 9001 端口:- $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: ports: ["9000", "9001"] EOF
- 使用以下命令验证是否允许请求 9000 端口: - $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9000 connection succeeded
- 使用以下命令验证是否允许请求 9001 端口: - $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
- 验证对 9002 端口的请求是否被拒绝。即使未在 - tcp-echoKubernetes Service 对象中显式声明的端口, 授权策略也会将其应用于透传过滤器链。运行以下命令并验证输出:- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
- 使用以下命令为 9000 端口添加一个名为 - methods的 HTTP-only 字段来更新策略:- $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: ALLOW rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
- 验证对 9000 端口的请求是否被拒绝。发生这种情况是因为该规则在对 TCP 流量使用了 HTTP-only 字段( - methods), 这会导致规则无效。Istio 会忽略无效的 ALLOW 规则。最终结果是该请求被拒绝,因为它与任何 ALLOW 规则都不匹配。 运行以下命令并验证输出:- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
- 验证对 9001 端口的请求是否被拒绝。发生这种情况是因为请求与任何 ALLOW 规则都不匹配。运行以下命令并验证输出: - $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
为 TCP 工作负载配置 DENY 授权策略
- 使用以下命令添加具有 HTTP-only 字段的 DENY 策略: - $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] EOF
- 验证到 9000 端口的请求是否被拒绝。发生这种情况是因为 Istio 在为 tcp 端口创建 DENY 规则时不理解 HTTP-only 字段,并且由于这个规则的限制性质,将拒绝所有到 tcp 端口的流量: - $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
- 验证到 9001 端口的请求是否被拒绝。原因同上。 - $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
- 使用以下命令添加同时具有 TCP 和 HTTP 字段的 DENY 策略: - $ kubectl apply -f - <<EOF apiVersion: security.istio.io/v1 kind: AuthorizationPolicy metadata: name: tcp-policy namespace: foo spec: selector: matchLabels: app: tcp-echo action: DENY rules: - to: - operation: methods: ["GET"] ports: ["9000"] EOF
- 验证对 9000 端口的请求是否被拒绝。发生这种情况是因为此类请求与上述 DENY 策略中的 - ports匹配:- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' connection rejected
- 验证是否允许对 9001 端口的请求。发生这种情况是因为请求与 DENY 策略中的 - ports不匹配:- $ kubectl exec "$(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name})" \ -c curl -n foo -- sh -c \ 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected' hello port 9001 connection succeeded
清理
删除 foo 命名空间:
$ kubectl delete namespace foo