days to Istio 1.5

MTLSPolicyConflict

This message occurs when a destination rule resource and a policy resource are in conflict with regards to mutual TLS. The two resources are in conflict if they each specify incompatible mutual TLS modes to be used; this conflict means traffic matching the destination rule to the specified host will be rejected.

This message is only produced on service meshes that are not using automatic mutual TLS.

An example

Consider an Istio mesh with the following mesh policy:

apiVersion: authentication.istio.io/v1alpha1
kind: MeshPolicy
metadata:
  name: default
spec:
  peers:
  - mtls: {}

The effect of this policy resource is that all services have an authentication policy requiring mutual TLS to be used. However, note that without a corresponding destination rule requiring traffic to use mutual TLS, traffic will be sent to services without using mutual TLS. This conflict means that traffic destined for services in the mesh will ultimately fail.

In this example, you can fix the issue in one of two ways: you could downgrade the mesh policy’s mutual TLS requirements to accept plaintext traffic (which might include removing the mesh policy entirely), or you can create a corresponding destination rule that specifies to use mutual TLS for traffic within the mesh:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: mtls-for-cluster
spec:
  host: *.svc.cluster.local
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

Which destination rules and policies are relevant to a service

To effectively resolve mutual TLS conflicts, it’s helpful to understand how both destination rules and policies affect traffic to a service. Consider an example service named my-service in namespace my-namespace. To determine which policy object is applied to my-service, the following resources are matched in order:

  1. A policy resource in namespace my-namespace that contains a target specifying my-service.
  2. A policy resource named default in namespace my-namespace that does not contain a target. This policy implicitly applies to the entire namespace.
  3. A mesh policy resource named default.

To determine which destination rules are applied to traffic sent to my-service, we must first know which namespace the traffic originates from. For the sake of this example, let’s call that namespace other-namespace. Destination rules are matched in the following order:

  1. A destination rule in namespace other-namespace that specifies a host that matches my-service.my-namespace.svc.cluster.local. This may be an exact match or a wildcard match. Also note that the exportTo field, which controls the visibility of configuration resources, will effectively be ignored as resources within the same namespace as the source service are always visible.
  2. A destination rule in namespace my-namespace that specifies a host that matches my-service.my-namespace.svc.cluster.local. This may be an exact match or a wildcard match. Note that the exportTo field must specify that this resource is public (e.g. it has the value "*" or is not specified) in order for a match to occur.
  3. A destination rule in the “root namespace” (which is, by default, istio-system) that matches my-service.my-namespace.svc.cluster.local. The root namespace is controlled by the rootNamespace property in the MeshConfig resource. Note that the exportTo field must specify that this resource is public (e.g. it has the value "*" or is not specified) in order for a match to occur.

Finally, be aware that Istio doesn’t apply any concept of inheritance when following these rules. The first resources that matches the specified criteria is used.

How to resolve

Look at the output of the message. You should see something like:

Error [IST0113] (DestinationRule default-rule.istio-system) A DestinationRule
and Policy are in conflict with regards to mTLS for host
myhost.my-namespace.svc.cluster.local:8080. The DestinationRule
"istio-system/default-rule" specifies that mTLS must be true but the Policy
object "my-namespace/my-policy" specifies Plaintext.

Contained in this message are the two resources that are in conflict:

  • Policy resource my-namespace/my-policy, which is specifying ‘Plaintext’ as its supported mutual TLS mode.
  • Destination rule resource istio-system/default-rule, which is requiring mutual TLS when sending traffic to host myhost.my-namespace.svc.cluster.local:8080

You can fix the conflict by doing one of the following:

  • Modifying policy resource my-namespace/my-policy to require mutual TLS as an authentication mode. In general this is done by adding a peers attribute to the resource with a child of mtls. You can read more about how this is achieved on the reference page for policy objects.
  • Modifying destination rule istio-system/default-rule to not use mutual TLS by removing the ISTIO_MUTUAL traffic policy. Note that default-rule is in the istio-system namespace - by default, the istio-system namespace is considered the “root namespace” for configuration (although this can be overridden via the rootNamespace property in the MeshConfig resource. That means that this destination rule potentially affects all other services in the mesh.
  • Add a new destination rule in the same namespace as the service (in this case, namespace my-namespace), and do not specify a traffic policy of ISTIO_MUTUAL. Because this rule is located in the same namespace as the service, it will override the global destination rule istio-system/default-rule.