服务网格迁移:Sidecar无法同时接收TLS与明文流量至Pod
问题分析与解决方案
你的核心问题出在三个地方:Service端口映射错误、PeerAuthentication的mTLS配置不符合需求、缺少Sidecar的HTTPS终止配置,导致HTTPS流量直接打到了容器的HTTP端口,引发协议错误。
1. 修正Service端口配置
你当前的Service把443端口的targetPort设为了容器的8080,这会让外部HTTPS流量直接转发到容器的HTTP监听端口——容器无法解析TLS握手数据,自然出现协议错误。
正确的Service配置应该让443端口指向Sidecar监听的Pod端口(443),由Sidecar终止TLS后再转发到容器的8080:
apiVersion: v1 kind: Service metadata: name: hello-world spec: selector: app: hello-world ports: - port: 8080 name: http protocol: TCP targetPort: 8080 appProtocol: HTTP - port: 443 name: https protocol: TCP targetPort: 443 # 指向Sidecar监听的Pod端口 appProtocol: HTTPS
2. 调整PeerAuthentication配置
你全局设置了mtls.mode: STRICT,同时443端口也设为STRICT,这会要求所有到443的流量必须使用Istio的mTLS,但未迁移的应用发送的是普通HTTPS流量,不带有mTLS认证,会被Sidecar拒绝。
需要把443和8080端口的mTLS模式都设为DISABLE,允许普通明文/HTTPS流量:
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: servicetoservice-mesh spec: selector: matchLabels: app: hello-world mtls: mode: PERMISSIVE # 全局允许mTLS和非mTLS流量,避免影响网格内其他服务调用 portLevelMtls: 443: mode: DISABLE # 允许普通HTTPS流量,无需mTLS 8080: mode: DISABLE # 允许明文HTTP流量
3. 配置Sidecar的HTTPS终止
需要显式配置Sidecar在Pod的443端口监听HTTPS,使用你的TLS证书终止加密,再转发到容器的8080端口。首先确保你已经在对应命名空间创建了包含证书和私钥的Secret(比如hello-world-tls),然后添加Sidecar资源:
apiVersion: networking.istio.io/v1beta1 kind: Sidecar metadata: name: hello-world-sidecar namespace: your-namespace # 替换为你的命名空间 spec: workloadSelector: labels: app: hello-world listeners: - port: number: 443 protocol: HTTPS name: https-hello tls: mode: SIMPLE credentialName: hello-world-tls # 你的TLS Secret名称 forwardTo: destination: host: 127.0.0.1 port: number: 8080 # 转发到容器的HTTP端口 captureMode: DEFAULT
验证配置
- 应用所有配置后,重启Pod让Sidecar配置生效:
kubectl rollout restart deployment hello-world -n your-namespace
- 测试8080端口的明文HTTP:
curl http://hello-world.your-namespace.svc.cluster.local:8080
- 测试443端口的HTTPS:
curl https://hello-world.your-namespace.svc.cluster.local:443 --cacert /path/to/your/ca.crt
内容的提问来源于stack exchange,提问作者MikZed
相关产品推荐
相关产品推荐

