Resolve connection issues for server-first protocol applications in ASM

更新时间:
复制 MD 格式

Server-first protocols such as MySQL, SMTP, and DNS require the server to send the first data packet after a TCP connection is established. By default, the sidecar proxy in Alibaba Cloud Service Mesh (ASM) inspects the initial bytes of each connection to auto-detect the protocol. Because the proxy waits for the client to send data first, server-first protocols stall and eventually time out. The fix is to explicitly declare the port as TCP so the proxy skips protocol detection.

Symptoms

When a server-first protocol application runs in ASM, you may observe:

  • Connection timeouts: Client connections to the server hang and eventually fail.

  • Unexpected delays: Connections take noticeably longer than expected before data begins to flow.

These symptoms occur because the sidecar proxy and the server-first application each wait for the other side to send data first, creating a deadlock.

Why the deadlock happens

The ASM sidecar proxy intercepts all inbound traffic and inspects the initial bytes to auto-detect the protocol. This auto-detection relies on the client sending data first.

Server-first protocols work in the opposite direction: the server sends data first. The result is a deadlock:

  1. The client completes the TCP handshake and waits for the server to send data.

  2. The server-side sidecar proxy intercepts the connection and waits for the client to send data so it can detect the protocol.

  3. Neither side sends data. The connection stalls until it times out.

Choose a fix based on your deployment scenario

The fix in every scenario is the same: configure the sidecar proxy to treat the traffic as plain TCP so it skips protocol detection. The specific steps depend on where your client and server are deployed relative to the mesh.

ScenarioFix
Both client and server are in the meshUse a recognized port, declare TCP in the Service spec, or enable TLS
Client is in the mesh, server is outsideCreate a ServiceEntry with protocol: TCP
Client is outside the mesh, server is in the meshDisable mTLS on the server port

Both client and server are in the mesh

Option 1: Use a standard port (recommended)

ASM automatically treats the following standard ports as TCP, which bypasses protocol detection. If your server runs on one of these ports, no additional configuration is needed.

ProtocolStandard port
MySQL3306
SMTP25
DNS53
MongoDB27017

Option 2: Declare TCP in the Service spec

If the server runs on a non-standard port, explicitly declare the protocol as TCP in the Kubernetes Service definition by prefixing the port name with tcp-.

Prefix the port name with tcp-

Add the tcp- prefix to the ports.name field. ASM recognizes this naming convention and skips protocol detection for the port.

apiVersion: v1
kind: Service
metadata:
  name: my-mysql-svc
spec:
  ports:
  - name: tcp-mysql-port
    port: 3307
    targetPort: 3307
  selector:
    app: my-mysql-server

Option 3: Enable TLS on the server

A TLS handshake requires the client to send a ClientHello message first. This satisfies the sidecar proxy's protocol detection requirement, so the connection proceeds without a deadlock.

Enabling TLS also encrypts traffic, which is the recommended configuration for production workloads.

Client in the mesh, server outside the mesh

When the server is an external service (for example, an ApsaraDB RDS for MySQL instance), the in-mesh client's sidecar proxy still needs to know the traffic is TCP.

  1. Enable the DNS proxy feature in ASM, then restart all client pods that access the external service to apply the proxy configuration.

  2. Create a ServiceEntry that declares the port protocol as TCP.

    Example: ServiceEntry for an external RDS for MySQL instance

    The target service has the domain name rm-xxxx.mysql.rds.aliyuncs.com and listens on port 3306.

    apiVersion: networking.istio.io/v1
    kind: ServiceEntry
    metadata:
      name: external-mysql-rds
    spec:
      # Domain name of the external service
      hosts:
      - rm-xxxx.mysql.rds.aliyuncs.com
      location: MESH_EXTERNAL
      ports:
      # Declare the port protocol as TCP to skip detection
      - name: tcp-mysql
        number: 3306
        protocol: TCP
      # Use DNS resolution for the external host
      resolution: DNS

    Replace rm-xxxx.mysql.rds.aliyuncs.com with the actual domain name of your external service.

    After you apply this ServiceEntry, the client can connect to the external database without timeouts.

Client outside the mesh, server in the mesh

A client without a sidecar proxy cannot negotiate mutual TLS (mTLS) with the server's sidecar proxy. To resolve this, disable mTLS for the specific port on the server workload by configuring a PeerAuthentication resource. For details, see Example 4: Disable mTLS for port 8080.

Important

Disabling mTLS exposes the server port without encryption. Where possible, enable TLS on the server to maintain transport security.

Related topics