Istio Multicluster Custom CA Issues

I am trying to configure a multicluster mesh topology with replicated controls planes with Istio, as described in https://istio.io/docs/setup/install/multicluster/gateways/. My PKI setup has 3 tiers and looks like the following.

PKI Hierarchy

  1. A Root CA (root-ca.pem)
  2. Intermediate CA to sign each clusters Citadel CA (intermediate-ca.pem)
  3. Each cluster’s Citadel CA (ca-cert.pem)

Following the install instructions, I install the certificates into the istio-system namespace with the following command.

kubectl create secret generic cacerts -n istio-system --from-file=./ca-cert.pem \
--from-file=./ca-key.pem --from-file=./root-cert.pem \
--from-file=./cert-chain.pem

In this command, ca-cert.pem is the cluster’s CA certificate. ca-key.pem is the private key for ca-cert. cert-chain.pem is the full chain of the ca-cert.pem ie. cert-chain.pem=$(cat ca-cert.pem intermediate-ca.pem root-ca.pem) and root-cert.pem is the chain of the intermediate CA ie. root-cert.pem=$(cat intermediate-ca.pem root-ca.pem)

When I install this setup into a cluster, mTLS works fine within the cluster using my custom CA as expected. However, when I go to setup the multicluster environment, calls from cluster A to cluster b fail the root certificate validation.

Does anyone have insight into why these certificates would not be trusted when they share the same root CA structure?

@Oliver Can you take a look?

To assist, I want to add that it seems that the Envoy proxy attached to the ingress-gateway terminates as a result of trying this connection. When I try to curl to the remote service, it spits out the following logs. Additionally, I still get this error when I load both clusters with the same CA in citadel.

[Envoy (Epoch 0)] [2020-04-07 14:22:26.538][30][critical][main] [external/envoy/source/exe/terminate_handler.cc:13] std::terminate called! (possible uncaught exception, see trace)
[Envoy (Epoch 0)] [2020-04-07 14:22:26.538][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:70] Backtrace (use tools/stack_decode.py to get line numbers):
[Envoy (Epoch 0)] [2020-04-07 14:22:26.538][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:71] Envoy version: 73f240a29bece92a8882a36893ccce07b4a54664/1.13.1-
dev/Clean/RELEASE/BoringSSL
[Envoy (Epoch 0)] [2020-04-07 14:22:26.550][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #0: Envoy::TerminateHandler::logOnTerminate()::$_0::operator()(
) [0x55b768630dae]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.564][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:77] #1: [0x55b768630cb9]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.576][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #2: std::__terminate() [0x55b768b93a73]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.586][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #3: Envoy::Tcp::TcpClusterRewrite::TcpClusterRewriteFilter::onNewConnection() [0x55b766d52c4d]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.596][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #4: Envoy::Network::FilterManagerImpl::onContinueReading() [0x55b768173582]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.608][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #5: Envoy::Network::FilterManagerImpl::initializeReadFilters() [0x55b7681734e5]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.619][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #6: Envoy::Server::ConnectionHandlerImpl::ActiveTcpListener::newConnection() [0x55b768163547]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.629][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #7: Envoy::Server::ConnectionHandlerImpl::ActiveTcpSocket::continueFilterChain() [0x55b7681631fb]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.641][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #8: Envoy::Server::ConnectionHandlerImpl::ActiveTcpListener::onAcceptWorker() [0x55b7681632f1]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.653][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #9: Envoy::Network::ListenerImpl::listenCallback() [0x55b768176d4c]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.665][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #10: listener_read_cb [0x55b76849d7c3]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.675][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #11: event_process_active_single_queue [0x55b76849b9ab]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.685][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #12: event_base_loop [0x55b76849a23e]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.695][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #13: Envoy::Server::WorkerImpl::threadRoutine() [0x55b768160278]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #14: Envoy::Thread::ThreadImplPosix::ThreadImplPosix()::$_0::__invoke() [0x55b768666953]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #15: start_thread [0x7f8415e306db]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:83] Caught Aborted, suspect faulting address 0x14
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:70] Backtrace (use tools/stack_decode.py to get line numbers):
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:71] Envoy version: 73f240a29bece92a8882a36893ccce07b4a54664/1.13.1-dev/Clean/RELEASE/BoringSSL
[Envoy (Epoch 0)] [2020-04-07 14:22:26.705][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #0: __restore_rt [0x7f8415e3b890]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:77] #1: [0x55b768630cb9]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #2: std::__terminate() [0x55b768b93a73]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #3: Envoy::Tcp::TcpClusterRewrite::TcpClusterRewriteFilter::onNewConnection() [0x55b766d52c4d]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #4: Envoy::Network::FilterManagerImpl::onContinueReading() [0x55b768173582]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #5: Envoy::Network::FilterManagerImpl::initializeReadFilters() [0x55b7681734e5]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #6: Envoy::Server::ConnectionHandlerImpl::ActiveTcpListener::newConnection() [0x55b768163547]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #7: Envoy::Server::ConnectionHandlerImpl::ActiveTcpSocket::continueFilterChain() [0x55b7681631fb]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #8: Envoy::Server::ConnectionHandlerImpl::ActiveTcpListener::onAcceptWorker() [0x55b7681632f1]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #9: Envoy::Network::ListenerImpl::listenCallback() [0x55b768176d4c]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #10: listener_read_cb [0x55b76849d7c3]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #11: event_process_active_single_queue [0x55b76849b9ab]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #12: event_base_loop [0x55b76849a23e]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #13: Envoy::Server::WorkerImpl::threadRoutine() [0x55b768160278]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #14: Envoy::Thread::ThreadImplPosix::ThreadImplPosix()::$_0::__invoke() [0x55b768666953]
[Envoy (Epoch 0)] [2020-04-07 14:22:26.715][30][critical][backtrace] [bazel-out/k8-opt/bin/external/envoy/source/server/_virtual_includes/backtrace_lib/server/backtrace.h:75] #15: start_thread [0x7f8415e306db]
2020-04-07T14:22:26.744655Z     error   Epoch 0 exited with error: signal: aborted (core dumped)
2020-04-07T14:22:26.744680Z     info    No more active epochs, terminating

Which version of Istio are you using? How you install Istio? How you set up the multicluster and configure custom CA?

Thanks for getting back to me @leitang.

This is Istio 1.5.1. I am installing Istio via helm in AWS EKS.

In my values file, I define the following configuration.

gateways:
  enabled: true
  istio-ingressgateway:
    serviceAnnotations:
      service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
  istio-egressgateway:
    enabled: true
    env:
      # Needed to route traffic via egress gateway if desired.
      ISTIO_META_REQUESTED_NETWORK_VIEW: "external"
security:
  enabled: true
  selfSigned: false
global:
  mtls:
    # Default setting for service-to-service mtls. Can be set explicitly using
    # destination rules or service annotations.
    enabled: true
    # If set to true, and a given service does not have a corresponding DestinationRule configured,
    # or its DestinationRule does not have TLSSettings specified, Istio configures client side
    # TLS configuration automatically, based on the server side mTLS authentication policy and the
    # availibity of sidecars.
    auto: true
  podDNSSearchNamespaces:
  - global
  - "{{ valueOrDefault .DeploymentMeta.Namespace \"default\" }}.global"
  meshExpansion:
    enabled: false
    # If set to true, the pilot and citadel mtls and the plaintext pilot ports
    # will be exposed on an internal gateway
    useILB: false
  multiCluster:
    # Set to true to connect two kubernetes clusters via their respective
    # ingressgateway services when pods in each cluster cannot directly
    # talk to one another. All clusters should be using Istio mTLS and must
    # have a shared root CA for this model to work.
    enabled: true

    # Should be set to the name of the cluster this installation will run in. This is required for sidecar injection
    # to properly label proxies
    clusterName: ${myCluster}

To configure the custom CA, I ported the Makefile on the Github.

.SUFFIXES: .csr .pem .conf
.PRECIOUS: %/ca-key.pem %/ca-cert.pem %/cert-chain.pem
.PRECIOUS: root-cert.csr root-ca.conf %/cluster-ca.csr %/intermediate.conf
.SECONDARY: root-cert.csr root-ca.conf %/cluster-ca.csr %/intermediate.conf

.DEFAULT_GOAL := help

#------------------------------------------------------------------------
# variables: root CA
ROOTCA_DAYS ?= 3650
ROOTCA_KEYSZ ?= 4096
ROOTCA_ORG ?= MyCompany
ROOTCA_CN ?= Root CA
# Additional variables are defined in root-ca.conf target below.

#------------------------------------------------------------------------
# variables: Intermediate CA
INT_SERIAL ?= $(shell echo $$RANDOM) 	# certificate serial number (uses current PID)
INT_DAYS ?= 3650
INT_KEYSZ ?= 4096
INT_ORG ?= MyCompany
INT_CN ?= Intermediate CA
INT_SAN_DNS ?= localhost
# Additional variables are defined in %/intermediate.conf target below.

#------------------------------------------------------------------------
# variables: intermediate CA (Istio)
ISTIO_SERIAL ?= $(shell echo $$RANDOM) 	# certificate serial number (uses current PID)
ISTIO_DAYS ?= 3650
ISTIO_KEYSZ ?= 4096
ISTIO_ORG ?= MyCompany
ISTIO_SAN_DNS ?= localhost
# Additional variables are defined in %/intermediate.conf target below.

#------------------------------------------------------------------------
##help:		print this help message
.PHONY: help

help: Makefile
  @sed -n 's/^##//p' $<

#------------------------------------------------------------------------
##root-ca:	generate root CA files (key and certifcate) in current directory
.PHONY: root-ca

root-ca: root-key.pem root-cert.pem

root-cert.pem: root-cert.csr root-key.pem
  @echo "generating $@"
  @openssl x509 -req -days $(ROOTCA_DAYS) -signkey root-key.pem \
    -extensions req_ext -extfile root-ca.conf \
    -in $< -out $@

root-cert.csr: root-key.pem root-ca.conf
  @echo "generating $@"
  @openssl req -new -key $< -config root-ca.conf -out $@ 

root-ca.conf: 
  @echo "[ req ]" > $@
  @echo "encrypt_key = no" >> $@
  @echo "prompt = no" >> $@
  @echo "utf8 = yes" >> $@
  @echo "default_md = sha256" >> $@
  @echo "default_bits = $(ROOTCA_KEYSZ)" >> $@
  @echo "req_extensions = req_ext" >> $@
  @echo "x509_extensions = req_ext" >> $@
  @echo "distinguished_name = req_dn" >> $@
  @echo "[ req_ext ]" >> $@
  @echo "subjectKeyIdentifier = hash" >> $@
  @echo "basicConstraints = critical, CA:true" >> $@
  @echo "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign" >> $@
  @echo "[ req_dn ]" >> $@
  @echo "O = $(ROOTCA_ORG)" >> $@
  @echo "CN = $(ROOTCA_CN)" >> $@

root-key.pem:
  @echo "generating $@"
  @openssl genrsa -out $@ 4096

#------------------------------------------------------------------------
##intermediate-ca:	generate intermediate certificate authority. Includes all PEM files needed.
.PHONY: intermediate-ca

intermediate-ca: int/int-cert-chain.pem root-cert.pem
  @echo "int inputs stored in $(dir $<)"
  @cp root-cert.pem $(dir $<)

int/int-cert-chain.pem: int/int-ca-cert.pem root-cert.pem
  @echo "generating $@"
  @cat $^ > $@

int/int-ca-cert.pem: int/int-ca.csr root-key.pem root-cert.pem
  @echo "generating $@"
  @openssl x509 -req -days $(INT_DAYS) \
    -CA root-cert.pem -CAkey root-key.pem -set_serial $(INT_SERIAL) \
    -extensions req_ext -extfile $(dir $<)/int-intermediate.conf \
    -in $< -out $@

int/int-ca.csr: L=$(dir $@)
int/int-ca.csr: int/int-ca-key.pem int/int-intermediate.conf
  @echo "generating $@"
  @openssl req -new -config $(L)/int-intermediate.conf -key $< -out $@ 

int/int-ca-key.pem:
  @echo "generating $@"
  @mkdir -p $(dir $@)
  @openssl genrsa -out $@ 4096

int/int-intermediate.conf: L=$(dir $@)
int/int-intermediate.conf:
  @echo "[ req ]" > $@
  @echo "encrypt_key = no" >> $@
  @echo "prompt = no" >> $@
  @echo "utf8 = yes" >> $@
  @echo "default_md = sha256" >> $@
  @echo "default_bits = $(INT_KEYSZ)" >> $@
  @echo "req_extensions = req_ext" >> $@
  @echo "x509_extensions = req_ext" >> $@
  @echo "distinguished_name = req_dn" >> $@
  @echo "[ req_ext ]" >> $@
  @echo "subjectKeyIdentifier = hash" >> $@
  @echo "basicConstraints = critical, CA:true" >> $@
  @echo "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign" >> $@
  @echo "subjectAltName=@san" >> $@
  @echo "[ san ]" >> $@
  @echo "DNS.1 = $(INT_SAN_DNS)" >> $@
  @echo "[ req_dn ]" >> $@
  @echo "O = $(INT_ORG)" >> $@
  @echo "CN = $(INT_CN)" >> $@
  @echo "L = $(L:/=)" >> $@

#------------------------------------------------------------------------
##<name>-certs:	generate Istio certificate authority for <name>. Includes all PEM files needed.
.PHONY: %-certs

%-certs: %/cert-chain.pem int/int-ca-cert.pem int/int-cert-chain.pem int/root-cert.pem
  @echo "ISTIO inputs stored in $(dir $<)"
  @cp int/int-ca-cert.pem $(dir $<)
  @cp int/root-cert.pem $(dir $<)/root-cert.pem

%/cert-chain.pem: %/ca-cert.pem int/int-ca-cert.pem int/root-cert.pem
  @echo "generating $@"
  @cat $^ > $@

%/ca-cert.pem: %/cluster-ca.csr int/int-ca-key.pem int/int-ca-cert.pem
  @echo "generating $@"
  @openssl x509 -req -days $(ISTIO_DAYS) \
    -CA int/int-ca-cert.pem -CAkey int/int-ca-key.pem -set_serial $(ISTIO_SERIAL) \
    -extensions req_ext -extfile $(dir $<)/intermediate.conf \
    -in $< -out $@

%/cluster-ca.csr: L=$(dir $@)
%/cluster-ca.csr: %/ca-key.pem %/intermediate.conf
  @echo "generating $@"
  @openssl req -new -config $(L)/intermediate.conf -key $< -out $@ 

%/ca-key.pem:
  @echo "generating $@"
  @mkdir -p $(dir $@)
  @openssl genrsa -out $@ 4096

%/intermediate.conf: L=$*_eks_cluster
%/intermediate.conf:
  @echo "[ req ]" > $@
  @echo "encrypt_key = no" >> $@
  @echo "prompt = no" >> $@
  @echo "utf8 = yes" >> $@
  @echo "default_md = sha256" >> $@
  @echo "default_bits = $(ISTIO_KEYSZ)" >> $@
  @echo "req_extensions = req_ext" >> $@
  @echo "x509_extensions = req_ext" >> $@
  @echo "distinguished_name = req_dn" >> $@
  @echo "[ req_ext ]" >> $@
  @echo "subjectKeyIdentifier = hash" >> $@
  @echo "basicConstraints = critical, CA:true" >> $@
  @echo "keyUsage = critical, digitalSignature, nonRepudiation, keyEncipherment, keyCertSign" >> $@
  @echo "subjectAltName=@san" >> $@
  @echo "[ san ]" >> $@
  @echo "URI.1 = spiffe://cluster.local/ns/istio-system/sa/citadel" >> $@
  @echo "URI.2 = spiffe://$(L:/=)/ns/istio-system/sa/citadel" >> $@
  @echo "URI.3 = spiffe://cluster.global/ns/istio-system/sa/citadel" >> $@
  @echo "DNS.1 = $(ISTIO_SAN_DNS)" >> $@
  @echo "[ req_dn ]" >> $@
  @echo "O = $(ISTIO_ORG)" >> $@
  @echo "CN = $*_eks_cluster Intermediate CA" >> $@
  @echo "L = $(L:/=)" >> $@

When this is setup in both cluster, I create a service entry for a remote service for Cluster B in cluster A.

apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
  name: details
spec:
  hosts:
  # must be of form name.namespace.global
  - details.default.global
  # Treat remote cluster services as part of the service mesh
  # as all clusters in the service mesh share the same root of trust.
  location: MESH_INTERNAL
  ports:
  - name: http
    number: 9080
    protocol: http
  resolution: DNS
  addresses:
  # the IP address to which httpbin.bar.global will resolve to
  # must be unique for each remote service, within a given cluster.
  # This address need not be routable. Traffic for this IP will be captured
  # by the sidecar and routed appropriately.
  - 240.0.1.4
  endpoints:
  # This is the routable address of the ingress gateway in cluster2 that
  # sits in front of sleep.foo service. Traffic from the sidecar will be
  # routed to this address.
  - address: ${DNS OF INGRESS CONTROLLER NLB}
    ports:
      http: 15443 # Do not change this port value
  EOF

I just took this same configuration and it works in 1.4.7 interestingly enough.

I’m running into the same thing here on 1.5.0. I’m following the multi-cluster setup as well and running into the same problem. I can try to downgrade and see if it resolve it but I’d rather know more about what the issue is. Is there anything I can do to help figure out what’s going on?

1.5.0 has an issues with multicluster setup. Upgrade to 1.5.1

Yes, I’ve confirmed that upgrading to 1.5.1 it is now working. Thanks!

+1, this is documented in our 1.5 notes: https://istio.io/news/releases/1.5.x/announcing-1.5/upgrade-notes/#multicluster-setup

Please use 1.5.1 instead.