From a0e19bdef995d28342c3f61b86a3952be0069085 Mon Sep 17 00:00:00 2001 From: Frank Budinsky Date: Tue, 5 Jul 2022 15:35:28 -0400 Subject: [PATCH] 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 --- .../multicluster/before-you-begin/index.md | 11 ++- .../multicluster/primary-remote/index.md | 88 ++++++++++------- .../multicluster/primary-remote/snips.sh | 24 +++-- .../multicluster/primary-remote/test.sh | 6 +- .../primary-remote_multi-network/index.md | 95 ++++++++++++------- .../primary-remote_multi-network/snips.sh | 29 +++--- .../primary-remote_multi-network/test.sh | 7 +- 7 files changed, 163 insertions(+), 97 deletions(-) diff --git a/content/en/docs/setup/install/multicluster/before-you-begin/index.md b/content/en/docs/setup/install/multicluster/before-you-begin/index.md index 7984b4693d..f12abb3c35 100644 --- a/content/en/docs/setup/install/multicluster/before-you-begin/index.md +++ b/content/en/docs/setup/install/multicluster/before-you-begin/index.md @@ -56,8 +56,17 @@ detailed descriptions and instructions for all available options. Depending on which option you choose, the installation instructions for 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 -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` clusters. diff --git a/content/en/docs/setup/install/multicluster/primary-remote/index.md b/content/en/docs/setup/install/multicluster/primary-remote/index.md index f73e7908e7..685a173a7a 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote/index.md +++ b/content/en/docs/setup/install/multicluster/primary-remote/index.md @@ -32,16 +32,6 @@ traffic. 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 Create the Istio configuration for `cluster1`: @@ -63,9 +53,15 @@ EOF Apply the configuration to `cluster1`: {{< 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 >}} +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 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@ {{< /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 -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`. - -To provide API Server access to `cluster2`, we generate a remote secret and -apply it to `cluster1`: +We need identify the external control plane cluster that should manage `cluster2` by annotating the +istio-system namespace: {{< text bash >}} -$ istioctl x create-remote-secret \ - --context="${CTX_CLUSTER2}" \ - --name=cluster2 | \ - kubectl apply -f - --context="${CTX_CLUSTER1}" +$ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system +$ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1 {{< /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 Save the address of `cluster1`’s east-west gateway. @@ -143,22 +131,58 @@ $ cat < cluster2.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: + profile: external values: + istiodRemote: + injectionPath: /inject/cluster/cluster2/net/network1 global: - meshID: mesh1 - multiCluster: - clusterName: cluster2 - network: network1 remotePilotAddress: ${DISCOVERY_ADDRESS} EOF {{< /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`: {{< text bash >}} $ istioctl install --context="${CTX_CLUSTER2}" -f cluster2.yaml {{< /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 and remote clusters! diff --git a/content/en/docs/setup/install/multicluster/primary-remote/snips.sh b/content/en/docs/setup/install/multicluster/primary-remote/snips.sh index 5061cc21c2..9908b95570 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote/snips.sh +++ b/content/en/docs/setup/install/multicluster/primary-remote/snips.sh @@ -35,7 +35,7 @@ EOF } 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() { @@ -58,11 +58,9 @@ kubectl apply --context="${CTX_CLUSTER1}" -n istio-system -f \ samples/multicluster/expose-istiod.yaml } -snip_enable_api_server_access_to_cluster2_1() { -istioctl x create-remote-secret \ - --context="${CTX_CLUSTER2}" \ - --name=cluster2 | \ - kubectl apply -f - --context="${CTX_CLUSTER1}" +snip_set_the_control_plane_cluster_for_cluster2_1() { +kubectl --context="${CTX_CLUSTER2}" create namespace istio-system +kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1 } snip_configure_cluster2_as_a_remote_1() { @@ -77,12 +75,11 @@ cat < cluster2.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: + profile: external values: + istiodRemote: + injectionPath: /inject/cluster/cluster2/net/network1 global: - meshID: mesh1 - multiCluster: - clusterName: cluster2 - network: network1 remotePilotAddress: ${DISCOVERY_ADDRESS} EOF } @@ -90,3 +87,10 @@ EOF snip_configure_cluster2_as_a_remote_3() { 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}" +} diff --git a/content/en/docs/setup/install/multicluster/primary-remote/test.sh b/content/en/docs/setup/install/multicluster/primary-remote/test.sh index 391de61a96..ee5858252a 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote/test.sh +++ b/content/en/docs/setup/install/multicluster/primary-remote/test.sh @@ -41,20 +41,20 @@ function install_istio_on_cluster1 { } 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 { 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_2 echo y | snip_configure_cluster2_as_a_remote_3 } -time configure_trust time install_istio_on_cluster1 -time enable_api_server_access time install_istio_on_cluster2 +time enable_api_server_access time verify_load_balancing # @cleanup diff --git a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/index.md b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/index.md index 241007d971..23bfd807b7 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/index.md +++ b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/index.md @@ -16,6 +16,8 @@ between pods across cluster boundaries. Before proceeding, be sure to complete the steps under [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 both clusters for endpoints. In this way, the control plane will be able to provide service discovery for workloads in both clusters. @@ -32,16 +34,6 @@ same east-west gateway. 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` 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`: {{< 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 >}} +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 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@ {{< /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 >}} -$ kubectl --context="${CTX_CLUSTER2}" get namespace istio-system && \ - kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 +$ kubectl --context="${CTX_CLUSTER2}" create namespace istio-system +$ kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1 {{< /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 -plane in `cluster1` access to the API Server in `cluster2`. This will do the -following: +## Set the default network for `cluster2` -- 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`: +Set the network for `cluster2` by adding a label to the istio-system namespace: {{< text bash >}} -$ istioctl x create-remote-secret \ - --context="${CTX_CLUSTER2}" \ - --name=cluster2 | \ - kubectl apply -f - --context="${CTX_CLUSTER1}" +$ kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 {{< /text >}} ## Configure `cluster2` as a remote @@ -173,16 +162,23 @@ $ cat < cluster2.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: + profile: external values: + istiodRemote: + injectionPath: /inject/cluster/cluster2/net/network2 global: - meshID: mesh1 - multiCluster: - clusterName: cluster2 - network: network2 remotePilotAddress: ${DISCOVERY_ADDRESS} EOF {{< /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`: {{< text bash >}} @@ -217,6 +213,35 @@ $ kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \ @samples/multicluster/expose-services.yaml@ {{< /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 and remote clusters on different networks! diff --git a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/snips.sh b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/snips.sh index 5b37ef1736..cc0527f526 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/snips.sh +++ b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/snips.sh @@ -40,7 +40,7 @@ EOF } 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() { @@ -68,16 +68,13 @@ kubectl --context="${CTX_CLUSTER1}" apply -n istio-system -f \ samples/multicluster/expose-services.yaml } -snip_set_the_default_network_for_cluster2_1() { -kubectl --context="${CTX_CLUSTER2}" get namespace istio-system && \ - kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 +snip_set_the_control_plane_cluster_for_cluster2_1() { +kubectl --context="${CTX_CLUSTER2}" create namespace istio-system +kubectl --context="${CTX_CLUSTER2}" annotate namespace istio-system topology.istio.io/controlPlaneClusters=cluster1 } -snip_enable_api_server_access_to_cluster2_1() { -istioctl x create-remote-secret \ - --context="${CTX_CLUSTER2}" \ - --name=cluster2 | \ - kubectl apply -f - --context="${CTX_CLUSTER1}" +snip_set_the_default_network_for_cluster2_1() { +kubectl --context="${CTX_CLUSTER2}" label namespace istio-system topology.istio.io/network=network2 } snip_configure_cluster2_as_a_remote_1() { @@ -92,12 +89,11 @@ cat < cluster2.yaml apiVersion: install.istio.io/v1alpha1 kind: IstioOperator spec: + profile: external values: + istiodRemote: + injectionPath: /inject/cluster/cluster2/net/network2 global: - meshID: mesh1 - multiCluster: - clusterName: cluster2 - network: network2 remotePilotAddress: ${DISCOVERY_ADDRESS} EOF } @@ -125,3 +121,10 @@ snip_expose_services_in_cluster2_1() { kubectl --context="${CTX_CLUSTER2}" apply -n istio-system -f \ 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}" +} diff --git a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/test.sh b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/test.sh index 3d4838c6ef..465007f8ac 100644 --- a/content/en/docs/setup/install/multicluster/primary-remote_multi-network/test.sh +++ b/content/en/docs/setup/install/multicluster/primary-remote_multi-network/test.sh @@ -43,11 +43,13 @@ function install_istio_on_cluster1 { } 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 { 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_2 echo y | snip_configure_cluster2_as_a_remote_3 @@ -62,10 +64,9 @@ function install_istio_on_cluster2 { snip_expose_services_in_cluster2_1 } -time configure_trust time install_istio_on_cluster1 -time enable_api_server_access time install_istio_on_cluster2 +time enable_api_server_access time verify_load_balancing # @cleanup