Change multicluster docs to use istiodless remotes (#11155)

* Change multicluster docs to use istiodless remotes

* regen

* workaround mwh bug

* manifest gen

* undo

* fix net

* regen

* remove workaround

* control plane annotation

* regen

* fix lint

* fix

* fix test failure

* address review comments
This commit is contained in:
Frank Budinsky 2022-07-05 15:35:28 -04:00 committed by GitHub
parent 4475f8e6ca
commit a0e19bdef9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 163 additions and 97 deletions

View File

@ -56,8 +56,17 @@ detailed descriptions and instructions for all available options.
Depending on which option you choose, the installation instructions for Depending on which option you choose, the installation instructions for
Istio may change slightly. Istio may change slightly.
{{< tip >}}
If you are planning to deploy only one primary cluster (i.e., one of the
Primary-Remote installations, below), you will only have a single CA
(i.e., `istiod` on `cluster1`) issuing certificates for both clusters.
In that case, you can skip the following CA certificate generation step
and simply use the default self-signed CA for the installation.
{{< /tip >}}
This guide will assume that you use a common root to generate intermediate This guide will assume that you use a common root to generate intermediate
certificates for each cluster. Follow the [instructions](/docs/tasks/security/cert-management/plugin-ca-cert/) certificates for each primary cluster.
Follow the [instructions](/docs/tasks/security/cert-management/plugin-ca-cert/)
to generate and push a CA certificate secret to both the `cluster1` and `cluster2` to generate and push a CA certificate secret to both the `cluster1` and `cluster2`
clusters. clusters.

View File

@ -32,16 +32,6 @@ traffic.
caption="Primary and remote clusters on the same network" caption="Primary and remote clusters on the same network"
>}} >}}
{{< tip >}}
Today, the remote profile will install an istiod server in the remote
cluster which will be used for CA and webhook injection for workloads
in that cluster. Service discovery, however, will be directed to the
control plane in the primary cluster.
Future releases will remove the need for having an istiod in the
remote cluster altogether. Stay tuned!
{{< /tip >}}
## Configure `cluster1` as a primary ## Configure `cluster1` as a primary
Create the Istio configuration for `cluster1`: Create the Istio configuration for `cluster1`:
@ -63,9 +53,15 @@ EOF
Apply the configuration to `cluster1`: Apply the configuration to `cluster1`:
{{< text bash >}} {{< text bash >}}
$ istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml $ istioctl install --set values.pilot.env.EXTERNAL_ISTIOD=true --context="${CTX_CLUSTER1}" -f cluster1.yaml
{{< /text >}} {{< /text >}}
Notice that `values.pilot.env.EXTERNAL_ISTIOD` is set to `true`. This enables the control plane
installed on `cluster1` to also serve as an external control plane for other remote clusters.
When this feature is enabled, `istiod` will attempt to acquire the leadership lock, and consequently manage,
[appropriately annotated](#set-the-control-plane-cluster-for-cluster2) remote clusters that will be
attached to it (`cluster2` in this case).
## Install the east-west gateway in `cluster1` ## Install the east-west gateway in `cluster1`
Install a gateway in `cluster1` that is dedicated to Install a gateway in `cluster1` that is dedicated to
@ -103,28 +99,20 @@ $ kubectl apply --context="${CTX_CLUSTER1}" -n istio-system -f \
@samples/multicluster/expose-istiod.yaml@ @samples/multicluster/expose-istiod.yaml@
{{< /text >}} {{< /text >}}
## Enable API Server Access to `cluster2` ## Set the control plane cluster for `cluster2`
Before we can configure the remote cluster, we first have to give the control We need identify the external control plane cluster that should manage `cluster2` by annotating the
plane in `cluster1` access to the API Server in `cluster2`. This will do the istio-system namespace:
following:
- Enables the control plane to authenticate connection requests from
workloads running in `cluster2`. Without API Server access, the control
plane will reject the requests.
- Enables discovery of service endpoints running in `cluster2`.
To provide API Server access to `cluster2`, we generate a remote secret and
apply it to `cluster1`:
{{< text bash >}} {{< text bash >}}
$ istioctl x create-remote-secret \ $ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
--context="${CTX_CLUSTER2}" \ $ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
{{< /text >}} {{< /text >}}
Setting the `topology.istio.io/controlPlaneClusters` namespace annotation to `cluster1` instructs the `istiod`
running in the same namespace (istio-system in this case) on `cluster1` to manage `cluster2` when it
is [attached as a remote cluster](#attach-cluster2-as-a-remote-cluster-of-cluster1).
## Configure `cluster2` as a remote ## Configure `cluster2` as a remote
Save the address of `cluster1`s east-west gateway. Save the address of `cluster1`s east-west gateway.
@ -143,22 +131,58 @@ $ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1 apiVersion: install.istio.io/v1alpha1
kind: IstioOperator kind: IstioOperator
spec: spec:
profile: external
values: values:
istiodRemote:
injectionPath: /inject/cluster/cluster2/net/network1
global: global:
meshID: mesh1
multiCluster:
clusterName: cluster2
network: network1
remotePilotAddress: ${DISCOVERY_ADDRESS} remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF EOF
{{< /text >}} {{< /text >}}
{{< tip >}}
Here we're configuring the location of the control plane using the `injectionPath` and
`remotePilotAddress` parameters. Although convenient for demonstration, in a production
environment it is recommended to instead configure the `injectionURL` parameter using
properly signed DNS certs similar to the configuration shown in the
[external control plane instructions](/docs/setup/install/external-controlplane/#register-the-new-cluster).
{{< /tip >}}
Apply the configuration to `cluster2`: Apply the configuration to `cluster2`:
{{< text bash >}} {{< text bash >}}
$ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml $ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml
{{< /text >}} {{< /text >}}
## Attach `cluster2` as a remote cluster of `cluster1`
To attach the remote cluster to its control plane, we give the control
plane in `cluster1` access to the API Server in `cluster2`. This will do the
following:
- Enables the control plane to authenticate connection requests from
workloads running in `cluster2`. Without API Server access, the control
plane will reject the requests.
- Enables discovery of service endpoints running in `cluster2`.
Because it has been included in the `topology.istio.io/controlPlaneClusters` namespace
annotation, the control plane on `cluster1` will also:
- Patch certs in the webhooks in `cluster2`.
- Start the namespace controller which writes configmaps in namespaces in `cluster2`.
To provide API Server access to `cluster2`, we generate a remote secret and
apply it to `cluster1`:
{{< text bash >}}
$ istioctl x create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
{{< /text >}}
**Congratulations!** You successfully installed an Istio mesh across primary **Congratulations!** You successfully installed an Istio mesh across primary
and remote clusters! and remote clusters!

View File

@ -35,7 +35,7 @@ EOF
} }
snip_configure_cluster1_as_a_primary_2() { snip_configure_cluster1_as_a_primary_2() {
istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml istioctl install --set values.pilot.env.EXTERNAL_ISTIOD=true --context="${CTX_CLUSTER1}" -f cluster1.yaml
} }
snip_install_the_eastwest_gateway_in_cluster1_1() { snip_install_the_eastwest_gateway_in_cluster1_1() {
@ -58,11 +58,9 @@ kubectl apply --context="${CTX_CLUSTER1}" -n istio-system -f \
samples/multicluster/expose-istiod.yaml samples/multicluster/expose-istiod.yaml
} }
snip_enable_api_server_access_to_cluster2_1() { snip_set_the_control_plane_cluster_for_cluster2_1() {
istioctl x create-remote-secret \ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
--context="${CTX_CLUSTER2}" \ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
} }
snip_configure_cluster2_as_a_remote_1() { snip_configure_cluster2_as_a_remote_1() {
@ -77,12 +75,11 @@ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1 apiVersion: install.istio.io/v1alpha1
kind: IstioOperator kind: IstioOperator
spec: spec:
profile: external
values: values:
istiodRemote:
injectionPath: /inject/cluster/cluster2/net/network1
global: global:
meshID: mesh1
multiCluster:
clusterName: cluster2
network: network1
remotePilotAddress: ${DISCOVERY_ADDRESS} remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF EOF
} }
@ -90,3 +87,10 @@ EOF
snip_configure_cluster2_as_a_remote_3() { snip_configure_cluster2_as_a_remote_3() {
istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml
} }
snip_attach_cluster2_as_a_remote_cluster_of_cluster1_1() {
istioctl x create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
}

View File

@ -41,20 +41,20 @@ function install_istio_on_cluster1 {
} }
function enable_api_server_access { function enable_api_server_access {
snip_enable_api_server_access_to_cluster2_1 snip_attach_cluster2_as_a_remote_cluster_of_cluster1_1
} }
function install_istio_on_cluster2 { function install_istio_on_cluster2 {
echo "Installing Istio on Remote cluster: ${CTX_CLUSTER2}" echo "Installing Istio on Remote cluster: ${CTX_CLUSTER2}"
snip_set_the_control_plane_cluster_for_cluster2_1
snip_configure_cluster2_as_a_remote_1 snip_configure_cluster2_as_a_remote_1
snip_configure_cluster2_as_a_remote_2 snip_configure_cluster2_as_a_remote_2
echo y | snip_configure_cluster2_as_a_remote_3 echo y | snip_configure_cluster2_as_a_remote_3
} }
time configure_trust
time install_istio_on_cluster1 time install_istio_on_cluster1
time enable_api_server_access
time install_istio_on_cluster2 time install_istio_on_cluster2
time enable_api_server_access
time verify_load_balancing time verify_load_balancing
# @cleanup # @cleanup

View File

@ -16,6 +16,8 @@ between pods across cluster boundaries.
Before proceeding, be sure to complete the steps under Before proceeding, be sure to complete the steps under
[before you begin](/docs/setup/install/multicluster/before-you-begin). [before you begin](/docs/setup/install/multicluster/before-you-begin).
{{< boilerplate multi-cluster-with-metallb >}}
In this configuration, cluster `cluster1` will observe the API Servers in In this configuration, cluster `cluster1` will observe the API Servers in
both clusters for endpoints. In this way, the control plane will be able to both clusters for endpoints. In this way, the control plane will be able to
provide service discovery for workloads in both clusters. provide service discovery for workloads in both clusters.
@ -32,16 +34,6 @@ same east-west gateway.
caption="Primary and remote clusters on separate networks" caption="Primary and remote clusters on separate networks"
>}} >}}
{{< tip >}}
Today, the remote profile will install an istiod server in the remote
cluster which will be used for CA and webhook injection for workloads
in that cluster. Service discovery, however, will be directed to the
control plane in the primary cluster.
Future releases will remove the need for having an istiod in the
remote cluster altogether. Stay tuned!
{{< /tip >}}
## Set the default network for `cluster1` ## Set the default network for `cluster1`
If the istio-system namespace is already created, we need to set the cluster's network there: If the istio-system namespace is already created, we need to set the cluster's network there:
@ -72,9 +64,15 @@ EOF
Apply the configuration to `cluster1`: Apply the configuration to `cluster1`:
{{< text bash >}} {{< text bash >}}
$ istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml $ istioctl install --set values.pilot.env.EXTERNAL_ISTIOD=true --context="${CTX_CLUSTER1}" -f cluster1.yaml
{{< /text >}} {{< /text >}}
Notice that `values.pilot.env.EXTERNAL_ISTIOD` is set to `true`. This enables the control plane
installed on `cluster1` to also serve as an external control plane for other remote clusters.
When this feature is enabled, `istiod` will attempt to acquire the leadership lock, and consequently manage,
[appropriately annotated](#set-the-control-plane-cluster-for-cluster2) remote clusters that will be
attached to it (`cluster2` in this case).
## Install the east-west gateway in `cluster1` ## Install the east-west gateway in `cluster1`
Install a gateway in `cluster1` that is dedicated to east-west traffic. By Install a gateway in `cluster1` that is dedicated to east-west traffic. By
@ -124,35 +122,26 @@ $ kubectl --context="${CTX_CLUSTER1}" apply -n istio-system -f \
@samples/multicluster/expose-services.yaml@ @samples/multicluster/expose-services.yaml@
{{< /text >}} {{< /text >}}
## Set the default network for `cluster2` ## Set the control plane cluster for `cluster2`
If the istio-system namespace is already created, we need to set the cluster's network there: We need identify the external control plane cluster that should manage `cluster2` by annotating the
istio-system namespace:
{{< text bash >}} {{< text bash >}}
$ kubectl --context="${CTX_CLUSTER2}" get namespace istio-system && \ $ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 $ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1
{{< /text >}} {{< /text >}}
## Enable API Server Access to `cluster2` Setting the `topology.istio.io/controlPlaneClusters` namespace annotation to `cluster1` instructs the `istiod`
running in the same namespace (istio-system in this case) on `cluster1` to manage `cluster2` when it
is [attached as a remote cluster](#attach-cluster2-as-a-remote-cluster-of-cluster1).
Before we can configure the remote cluster, we first have to give the control ## Set the default network for `cluster2`
plane in `cluster1` access to the API Server in `cluster2`. This will do the
following:
- Enables the control plane to authenticate connection requests from Set the network for `cluster2` by adding a label to the istio-system namespace:
workloads running in `cluster2`. Without API Server access, the control
plane will reject the requests.
- Enables discovery of service endpoints running in `cluster2`.
To provide API Server access to `cluster2`, we generate a remote secret and
apply it to `cluster1`:
{{< text bash >}} {{< text bash >}}
$ istioctl x create-remote-secret \ $ kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
{{< /text >}} {{< /text >}}
## Configure `cluster2` as a remote ## Configure `cluster2` as a remote
@ -173,16 +162,23 @@ $ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1 apiVersion: install.istio.io/v1alpha1
kind: IstioOperator kind: IstioOperator
spec: spec:
profile: external
values: values:
istiodRemote:
injectionPath: /inject/cluster/cluster2/net/network2
global: global:
meshID: mesh1
multiCluster:
clusterName: cluster2
network: network2
remotePilotAddress: ${DISCOVERY_ADDRESS} remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF EOF
{{< /text >}} {{< /text >}}
{{< tip >}}
Here we're configuring the location of the control plane using the `injectionPath` and
`remotePilotAddress` parameters. Although convenient for demonstration, in a production
environment it is recommended to instead configure the `injectionURL` parameter using
properly signed DNS certs similar to the configuration shown in the
[external control plane instructions](/docs/setup/install/external-controlplane/#register-the-new-cluster).
{{< /tip >}}
Apply the configuration to `cluster2`: Apply the configuration to `cluster2`:
{{< text bash >}} {{< text bash >}}
@ -217,6 +213,35 @@ $ kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \
@samples/multicluster/expose-services.yaml@ @samples/multicluster/expose-services.yaml@
{{< /text >}} {{< /text >}}
## Attach `cluster2` as a remote cluster of `cluster1`
To attach the remote cluster to its control plane, we give the control
plane in `cluster1` access to the API Server in `cluster2`. This will do the
following:
- Enables the control plane to authenticate connection requests from
workloads running in `cluster2`. Without API Server access, the control
plane will reject the requests.
- Enables discovery of service endpoints running in `cluster2`.
Because it has been included in the `topology.istio.io/controlPlaneClusters` namespace
annotation, the control plane on `cluster1` will also:
- Patch certs in the webhooks in `cluster2`.
- Start the namespace controller which writes configmaps in namespaces in `cluster2`.
To provide API Server access to `cluster2`, we generate a remote secret and
apply it to `cluster1`:
{{< text bash >}}
$ istioctl x create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
{{< /text >}}
**Congratulations!** You successfully installed an Istio mesh across primary **Congratulations!** You successfully installed an Istio mesh across primary
and remote clusters on different networks! and remote clusters on different networks!

View File

@ -40,7 +40,7 @@ EOF
} }
snip_configure_cluster1_as_a_primary_2() { snip_configure_cluster1_as_a_primary_2() {
istioctl install --context="${CTX_CLUSTER1}" -f cluster1.yaml istioctl install --set values.pilot.env.EXTERNAL_ISTIOD=true --context="${CTX_CLUSTER1}" -f cluster1.yaml
} }
snip_install_the_eastwest_gateway_in_cluster1_1() { snip_install_the_eastwest_gateway_in_cluster1_1() {
@ -68,16 +68,13 @@ kubectl --context="${CTX_CLUSTER1}" apply -n istio-system -f \
samples/multicluster/expose-services.yaml samples/multicluster/expose-services.yaml
} }
snip_set_the_default_network_for_cluster2_1() { snip_set_the_control_plane_cluster_for_cluster2_1() {
kubectl --context="${CTX_CLUSTER2}" get namespace istio-system && \ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system
kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1
} }
snip_enable_api_server_access_to_cluster2_1() { snip_set_the_default_network_for_cluster2_1() {
istioctl x create-remote-secret \ kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
} }
snip_configure_cluster2_as_a_remote_1() { snip_configure_cluster2_as_a_remote_1() {
@ -92,12 +89,11 @@ cat <<EOF > cluster2.yaml
apiVersion: install.istio.io/v1alpha1 apiVersion: install.istio.io/v1alpha1
kind: IstioOperator kind: IstioOperator
spec: spec:
profile: external
values: values:
istiodRemote:
injectionPath: /inject/cluster/cluster2/net/network2
global: global:
meshID: mesh1
multiCluster:
clusterName: cluster2
network: network2
remotePilotAddress: ${DISCOVERY_ADDRESS} remotePilotAddress: ${DISCOVERY_ADDRESS}
EOF EOF
} }
@ -125,3 +121,10 @@ snip_expose_services_in_cluster2_1() {
kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \ kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \
samples/multicluster/expose-services.yaml samples/multicluster/expose-services.yaml
} }
snip_attach_cluster2_as_a_remote_cluster_of_cluster1_1() {
istioctl x create-remote-secret \
--context="${CTX_CLUSTER2}" \
--name=cluster2 | \
kubectl apply -f - --context="${CTX_CLUSTER1}"
}

View File

@ -43,11 +43,13 @@ function install_istio_on_cluster1 {
} }
function enable_api_server_access { function enable_api_server_access {
snip_enable_api_server_access_to_cluster2_1 snip_attach_cluster2_as_a_remote_cluster_of_cluster1_1
} }
function install_istio_on_cluster2 { function install_istio_on_cluster2 {
echo "Installing Istio on Remote cluster: ${CTX_CLUSTER2}" echo "Installing Istio on Remote cluster: ${CTX_CLUSTER2}"
snip_set_the_control_plane_cluster_for_cluster2_1
snip_set_the_default_network_for_cluster2_1
snip_configure_cluster2_as_a_remote_1 snip_configure_cluster2_as_a_remote_1
snip_configure_cluster2_as_a_remote_2 snip_configure_cluster2_as_a_remote_2
echo y | snip_configure_cluster2_as_a_remote_3 echo y | snip_configure_cluster2_as_a_remote_3
@ -62,10 +64,9 @@ function install_istio_on_cluster2 {
snip_expose_services_in_cluster2_1 snip_expose_services_in_cluster2_1
} }
time configure_trust
time install_istio_on_cluster1 time install_istio_on_cluster1
time enable_api_server_access
time install_istio_on_cluster2 time install_istio_on_cluster2
time enable_api_server_access
time verify_load_balancing time verify_load_balancing
# @cleanup # @cleanup