TCP 流量

    在您开始之前,请先完成以下内容:

    • 阅读 。

    • 按照 Istio 安装指南安装 Istio。

    • 在命名空间例如 中部署两个工作负载,sleeptcp-echo。 这两个工作负载每个前面都会运行一个 Envoy 代理。 tcp-echo 工作负载会监听端口 9000、9001 和 9002,并以前缀 hello 输出它收到的所有流量。 例如,如果你发送 “world” 给 tcp-echo,那么它将会回复 hello worldtcp-echo 的 Kubernetes 服务对象只声明了端口 9000 和 9001,而省略了端口 9002。直通过滤器链将处理端口 9002 的流量。 使用以下命令部署示例命名空间和工作负载:

      Zip

    • 使用以下命令确认 sleep 可以成功与 tcp-echo 的端口 9000 和 9001 交互:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. hello port 9000
      3. connection succeeded
      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. hello port 9001
      3. connection succeeded
      1. $ 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}")
      2. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      3. hello port 9002
      4. connection succeeded

    如果看不到预期的输出,请在几秒钟后重试,因为缓存和其他传播开销可能会导致有些延迟。

    1. foo 命名空间中为 tcp-echo 工作负载创建 tcp-policy 授权策略。 运行以下命令来应用策略以允许请求到端口 9000 和 9001:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. name: tcp-policy
      6. namespace: foo
      7. spec:
      8. selector:
      9. matchLabels:
      10. app: tcp-echo
      11. action: ALLOW
      12. - to:
      13. - operation:
      14. ports: ["9000", "9001"]
      15. EOF
    2. 使用以下命令验证是否允许请求端口 9000:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection succeeded
    3. 使用以下命令验证是否允许请求端口 9001:

    4. 验证对端口 9002 的请求是否被拒绝。即使未在 tcp-echo Kubernetes 服务对象中显式声明的端口,授权策略也将其应用于直通过滤器链。 运行以下命令并验证输出:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c "echo \"port 9002\" | nc $TCP_ECHO_IP 9002" | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection rejected
    5. 使用以下命令为端口 9000 添加一个名为 methods 的 HTTP-only 字段来更新策略:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. name: tcp-policy
      6. namespace: foo
      7. spec:
      8. selector:
      9. matchLabels:
      10. app: tcp-echo
      11. action: ALLOW
      12. rules:
      13. - to:
      14. - operation:
      15. methods: ["GET"]
      16. ports: ["9000"]
      17. EOF
      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection rejected
    6. 验证对端口 9001 的请求是否被拒绝。 发生这种情况是因为请求与任何 ALLOW 规则都不匹配。 运行以下命令并验证输出:

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection rejected
    1. 使用以下命令添加具有 HTTP-only 字段的 DENY 策略:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. namespace: foo
      6. spec:
      7. selector:
      8. app: tcp-echo
      9. action: DENY
      10. rules:
      11. - to:
      12. - operation:
      13. methods: ["GET"]
      14. EOF
    2. 验证到 port 9000 的请求是否被拒绝。发生这种情况是因为 Istio 在为 tcp 端口创建 DENY 规则时不理解 HTTP-only 字段,并且由于这个规则的限制性质,将拒绝所有到 tcp 端口的流量:

    3. 验证到 port 9001 的请求是否被拒绝。原因同上。

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection rejected
    4. 使用以下命令添加同时具有 TCP 和 HTTP 字段的 DENY 策略:

      1. $ kubectl apply -f - <<EOF
      2. apiVersion: security.istio.io/v1beta1
      3. kind: AuthorizationPolicy
      4. metadata:
      5. name: tcp-policy
      6. namespace: foo
      7. spec:
      8. selector:
      9. matchLabels:
      10. app: tcp-echo
      11. action: DENY
      12. rules:
      13. - to:
      14. - operation:
      15. methods: ["GET"]
      16. ports: ["9000"]
      17. EOF
    5. 验证对端口 9000 的请求是否被拒绝。发生这种情况是因为此类请求与上述 DENY 策略中的 ports 匹配。

      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9000" | nc tcp-echo 9000' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. connection rejected
      1. $ kubectl exec "$(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name})" -c sleep -n foo -- sh -c 'echo "port 9001" | nc tcp-echo 9001' | grep "hello" && echo 'connection succeeded' || echo 'connection rejected'
      2. hello port 9001
      3. connection succeeded
    1. 删除命名空间 foo: