Istio流量转发与X509证书认证配置技术问询
问题背景
同一命名空间下的Pod A和Pod B(Keycloak)已注入Istio,Pod A需通过X509证书向Pod B认证身份。测试结果:
- 直接用HTTPS+显式指定证书调用时,Pod B主容器可正常接收证书并完成认证
- 用HTTP依赖Istio-proxy封装证书时,Istio-proxy接收HTTPS流量,但转发给Pod B主容器的是无证书的HTTP流量,导致Keycloak报错
x509 client certificate is not available for mutual SSL
1. 让Pod B主容器直接接收HTTPS请求(避免Istio-proxy转HTTP)
通过配置Istio将HTTPS流量透传给Pod B主容器,不终止TLS连接,让Keycloak自行处理证书验证:
配置Service
修改Pod B对应的Service,将端口类型标记为HTTPS,明确流量类型:
apiVersion: v1 kind: Service metadata: name: keycloak-http spec: ports: - name: https port: 443 targetPort: 8443 # Pod B主容器实际监听的HTTPS端口 selector: app: keycloak
配置DestinationRule
设置TLS模式为PASSTHROUGH,告知Istio直接转发HTTPS流量到Pod B主容器,不做TLS终止:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: keycloak-dr spec: host: keycloak-http.default.svc.cluster.local trafficPolicy: tls: mode: PASSTHROUGH
2. 确保Pod A主容器发起HTTP,由Istio-proxy转HTTPS并携带证书
配置Istio-proxy自动将Pod A的HTTP请求转为HTTPS,并附加X509客户端证书发送给Pod B:
配置DestinationRule(配套问题1的透传场景)
设置TLS模式为SIMPLE,指定客户端证书和CA证书路径,让Istio-proxy发起HTTPS请求:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: keycloak-dr spec: host: keycloak-http.default.svc.cluster.local trafficPolicy: tls: mode: SIMPLE clientCertificate: /etc/istio/certs/tls.crt # 客户端证书路径 privateKey: /etc/istio/certs/tls.key # 客户端密钥路径 caCertificates: /etc/istio/ca/keycloak-ca.crt # Pod B证书的CA根证书路径
挂载证书到Pod A的Istio-proxy
在Pod A的Deployment中添加证书挂载,确保Istio-proxy能访问到客户端证书和CA证书:
apiVersion: apps/v1 kind: Deployment metadata: name: pod-a-deployment spec: template: spec: containers: - name: istio-proxy volumeMounts: - name: client-cert mountPath: /etc/istio/certs readOnly: true - name: keycloak-ca mountPath: /etc/istio/ca readOnly: true volumes: - name: client-cert secret: secretName: pod-a-x509-cert # 存储Pod A客户端证书的Secret - name: keycloak-ca secret: secretName: keycloak-ca-cert # 存储Pod B CA证书的Secret
修正Pod A的curl命令
无需在curl中显式指定证书,由Istio-proxy自动处理证书和HTTPS转换:
curl --location --request POST 'http://keycloak-http/auth/realms/sample/protocol/openid-connect/token' \ --header 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'client_id=Test_certAuth' \ --data-urlencode 'grant_type=client_credentials' -v
3. 各CRD在流程中的作用
DestinationRule:核心作用是定义目标服务的流量策略,本场景中:
- 配置
PASSTHROUGH模式,让Istio-proxy直接透传HTTPS流量到Pod B主容器 - 配置
SIMPLE模式,指定客户端证书和CA证书,让Istio-proxy将HTTP转为HTTPS请求并携带证书
- 配置
PeerAuthentication:用于强制服务间的双向TLS认证,如果需要限制只有携带有效证书的请求才能访问Pod B,可配置命名空间级的
STRICT模式,确保Istio自动处理证书的合法性校验:
apiVersion: security.istio.io/v1beta1 kind: PeerAuthentication metadata: name: default namespace: default spec: mtls: mode: STRICT
Sidecar:控制Pod的流量进出规则,本场景中:
- 对于Pod B,Sidecar根据
PASSTHROUGH配置,跳过TLS终止,直接转发HTTPS流量到主容器 - 对于Pod A,Sidecar读取挂载的证书,将HTTP请求转为符合要求的HTTPS请求发送
- 对于Pod B,Sidecar根据
ServiceEntry:本场景中Pod A和Pod B属于同一命名空间的内部服务,无需使用。如果Pod B是外部服务,ServiceEntry用于将其纳入Istio服务网格,让Istio-proxy处理到该服务的TLS和认证逻辑。
内容的提问来源于stack exchange,提问作者Neha Verma

