From 42180aedb08b30663e079a4431fc1bb0b6c5ec7b Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Tue, 2 Jun 2026 15:30:53 -0400 Subject: [PATCH 01/22] docs: PEM-11038: ImagePullSecret for DHI --- .../configure-image-pull-secret.md | 12 ++++++++++++ .../configure-image-pull-secret.md | 12 ++++++++++++ 2 files changed, 24 insertions(+) create mode 100644 docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md create mode 100644 docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md new file mode 100644 index 00000000000..bf4b4b3cc6c --- /dev/null +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -0,0 +1,12 @@ +--- +sidebar_label: "Configure Image Pull Secret" +title: "Configure Image Pull Secret for Security-Hardened Images" +description: + "Learn how to request and configure an image pull secret from Spectro Cloud, used for retrieving security hardened + images." +icon: "" +hide_table_of_contents: false +sidebar_position: 5 +tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] +keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] +--- diff --git a/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md new file mode 100644 index 00000000000..9509bbb3d82 --- /dev/null +++ b/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md @@ -0,0 +1,12 @@ +--- +sidebar_label: "Configure Image Pull Secret" +title: "Configure Image Pull Secret for Security-Hardened Images" +description: + "Learn how to request and configure an image pull secret from Spectro Cloud, used for retrieving security hardened + images." +icon: "" +hide_table_of_contents: false +sidebar_position: 5 +tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] +keywords: ["self-hosted", "vertex", "image pull secret", "hardened images", "security"] +--- From bc2d92d8c0c9d1cc3985bcd91dfaa48a5395169b Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 10 Jun 2026 21:34:46 +0100 Subject: [PATCH 02/22] Gathering details --- .../configure-image-pull-secret.md | 146 +++++++++++++++++- 1 file changed, 145 insertions(+), 1 deletion(-) diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md index bf4b4b3cc6c..845842365e6 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -2,7 +2,7 @@ sidebar_label: "Configure Image Pull Secret" title: "Configure Image Pull Secret for Security-Hardened Images" description: - "Learn how to request and configure an image pull secret from Spectro Cloud, used for retrieving security hardened + "Learn how to request and configure an image pull secret from Spectro Cloud, used for retrieving security-hardened images." icon: "" hide_table_of_contents: false @@ -10,3 +10,147 @@ sidebar_position: 5 tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] --- + +Spectro Cloud is transitioning to security-hardened container images to strengthen the security posture of Palette and +VerteX deployments. These images are hosted in private registries and require an image pull secret for authenticated +access. + +An image pull secret is a credential that allows your Palette or VerteX instance to authenticate with private registries +that host security-hardened images. Once configured, the secret is distributed to the management plane and all managed +workload clusters so they can pull the required images. + +:::info + +Configuring an image pull secret is optional in the current release. In a future release, providing an image pull secret +will become mandatory for all self-hosted connected environments. We recommend configuring it now to prepare for the +transition. + +::: + +## Who Needs to Configure an Image Pull Secret + +You need to configure an image pull secret if your Palette or VerteX instance is a self-hosted, connected deployment. +The following environments do **not** require configuration: + +- **SaaS deployments** — Image pull secrets are managed automatically on the backend. + +- **Airgapped or disconnected deployments** — Images are obtained through + [Artifact Studio](../../enterprise-version/install-palette/airgap.md) or a similar offline workflow, and the secret is + configured on the backend. + +- **Environments with configured mirror registries or image swaps** — Images are pulled from your own private registry, + which bypasses the need for a Spectro Cloud image pull secret. + +- **Workload clusters that pull Spectro Cloud images from a private registry** — The secret is only needed when pulling + directly from Spectro Cloud-hosted registries. + +## Request an Image Pull Secret + +Image pull secrets are issued by Spectro Cloud. Contact your Spectro Cloud support representative to request one. Your +representative will generate the secret and provide it to you. + +Image pull secrets are intended for long-term use and typically require only a one-time configuration. If you need to +rotate the secret, whether due to a security incident or as part of your organization's security policy, contact support +to request a new one. + +## Prerequisites + +- A self-hosted instance of Palette. For help installing Palette, refer to the + [Installation](../install-palette/install-palette.md) guide. + +- Access to the [system console](../system-management/system-management.md#access-the-system-console). + +- An image pull secret provided by Spectro Cloud support. + +## Configure the Image Pull Secret in the System Console + +After you receive your image pull secret from Spectro Cloud support, use the system console to configure it. + +1. Log in to the Palette system console. Refer to the + [Access the System Console](../system-management/system-management.md#access-the-system-console) guide. + +2. From the left main menu, select **Administration**. + +3. Select the **Docker Hardened Images** tab. + +4. In the **Image Pull Secret** field, paste the image pull secret you received from Spectro Cloud support. + +5. Select **Save**. + + Palette validates the secret immediately. If the secret is invalid or expired, the following error message is + displayed: _"The Image Pull Secret is invalid or expired. Please check it again. If an existing Image Pull Secret + exists, it was not replaced."_ + + If the secret is valid, it is saved and distributed to the management plane and all managed workload clusters. + +## Configure the Image Pull Secret During Installation + +You can also provide the image pull secret during the initial Palette installation for certain deployment methods. This +configures the secret at install time so that it is available when the system console first starts. + +### Helm Chart Installation + +If you install Palette using a Helm chart, provide the image pull secret in your `values.yaml` file. For more +information, refer to the [Helm Configuration Reference](../install-palette/install-on-kubernetes/palette-helm-ref.md). + + + +### Enterprise Cluster Installation + +If you install Palette using an Enterprise Cluster (EC), you can include the image pull secret in the `spectro-mgmt` +pack values at install time. + + + +:::warning + +If you installed Palette using an Enterprise Cluster and you configured the image pull secret in the `spectro-mgmt` pack +values, you must also update the pack values during Palette upgrades. If you do not, the pack values overwrite the +system-console-configured secret with an empty value, which results in an upgrade failure. + +This does not apply to Helm chart installations, where the system console manages the secret independently after the +initial install. + +::: + +### Appliance Installation + +Day-0 configuration of the image pull secret during Appliance installation is not supported in the current release. If +you deploy Palette using an Appliance, configure the image pull secret through the system console after installation +completes. + +## Rotate an Image Pull Secret + +If you need to replace an existing image pull secret, for example due to a security incident or as part of a scheduled +rotation, use the system console. + +1. Log in to the Palette system console. + +2. From the left main menu, select **Administration**. + +3. Select the **Docker Hardened Images** tab. + +4. In the **Image Pull Secret** field, paste the new image pull secret. + +5. Select **Save**. + + A confirmation dialog is displayed with the message: _"An Image Pull Secret is already configured. Updating it now + will replace it with the new one in Palette/VerteX and your workload clusters. Are you sure you want to proceed?"_ + +6. Select **Confirm** to proceed with the rotation. + + Palette validates the new secret. If valid, it replaces the previous secret and distributes the updated secret to the + management plane and all managed workload clusters. + +To request a new image pull secret, contact your Spectro Cloud support representative. + +## Validate + +1. Log in to the Palette system console. + +2. From the left main menu, select **Administration**. + +3. Select the **Docker Hardened Images** tab. + +4. Verify that the **Image Pull Secret** field displays a configured secret. From 4e67953f8f177c52ff3134d2e1d2aa08eeb27673 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 17 Jun 2026 19:59:12 -0400 Subject: [PATCH 03/22] Updating install guides WIP; rough draft w/ questions for anirudh --- .../configure-image-pull-secret.md | 175 +++++------ .../airgap-install/install.md | 17 +- .../install-on-kubernetes/install.md | 281 ++++++++++-------- .../install-on-kubernetes/palette-helm-ref.md | 41 ++- .../upgrade/upgrade-k8s/airgap.md | 101 +++---- .../upgrade/upgrade-k8s/non-airgap.md | 271 ++++++++--------- .../release-notes/announcements.md | 7 +- .../release-notes/release-notes.md | 20 ++ .../central-management/palette-edge.md | 8 +- .../airgap-install/install.md | 158 ++++++---- .../vertex/upgrade/upgrade-k8s/airgap.md | 4 +- .../vertex/upgrade/upgrade-k8s/non-airgap.md | 4 +- ...tall-on-vmware_palette-system-console.webp | Bin 10280 -> 51034 bytes 13 files changed, 568 insertions(+), 519 deletions(-) diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md index 845842365e6..2d952bb8746 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -11,146 +11,117 @@ tags: ["self-hosted", "account", "image pull secret", "hardened images", "securi keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] --- -Spectro Cloud is transitioning to security-hardened container images to strengthen the security posture of Palette and -VerteX deployments. These images are hosted in private registries and require an image pull secret for authenticated -access. +Beginning in 4.9.b, Spectro Cloud is initiating the shift to security-hardened images. While images have a smaller +attack surface compared to physical and virtual machines, security-hardened images are built to reduce the attack +surface further by containing only the essential runtime components an application needs. They have strict Software +Lifecycle Agreements (SLAs) that require the images to be regularly scanned for vulnerabilities, rebuilt, and patched, +keeping the number of CVEs to a minimum. These images also contain artifacts such as Software Bill of Materials (SBOMs) +and cryptographic signatures to verify the image has not been tampered with. + +As a result of this transition, all images hosted Spectro Cloud's private repositories must now be authenticated and +retrieved using +[image pull secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets-1). Like +activation keys, these secrets are obtained from your Spectro Cloud customer support representative; they are intended +for long-term use and only need to be configured once as part of your initial setup process. If you need to rotate the +secret, whether due to a security incident or as part of your organization's security policy, contact support to request +a new one. + +Once configured, the secret is distributed to the management plane, PCGs, and all managed workload clusters so they can +pull the required images. -An image pull secret is a credential that allows your Palette or VerteX instance to authenticate with private registries -that host security-hardened images. Once configured, the secret is distributed to the management plane and all managed -workload clusters so they can pull the required images. - -:::info +:::warning -Configuring an image pull secret is optional in the current release. In a future release, providing an image pull secret -will become mandatory for all self-hosted connected environments. We recommend configuring it now to prepare for the -transition. +As of 4.9.b, configuring an image pull secret is optional; however, it will be mandatory in an upcoming release. +Therefore, we recommend configuring your image pull secret as soon as possible to avoid service disruptions. Refer to +the [Announcements](../../release-notes/announcements.md#upcoming-breaking-changes) page for the latest updates. ::: -## Who Needs to Configure an Image Pull Secret - -You need to configure an image pull secret if your Palette or VerteX instance is a self-hosted, connected deployment. -The following environments do **not** require configuration: - -- **SaaS deployments** — Image pull secrets are managed automatically on the backend. - -- **Airgapped or disconnected deployments** — Images are obtained through - [Artifact Studio](../../enterprise-version/install-palette/airgap.md) or a similar offline workflow, and the secret is - configured on the backend. - -- **Environments with configured mirror registries or image swaps** — Images are pulled from your own private registry, - which bypasses the need for a Spectro Cloud image pull secret. - -- **Workload clusters that pull Spectro Cloud images from a private registry** — The secret is only needed when pulling - directly from Spectro Cloud-hosted registries. - -## Request an Image Pull Secret - -Image pull secrets are issued by Spectro Cloud. Contact your Spectro Cloud support representative to request one. Your -representative will generate the secret and provide it to you. - -Image pull secrets are intended for long-term use and typically require only a one-time configuration. If you need to -rotate the secret, whether due to a security incident or as part of your organization's security policy, contact support -to request a new one. - -## Prerequisites - -- A self-hosted instance of Palette. For help installing Palette, refer to the - [Installation](../install-palette/install-palette.md) guide. - -- Access to the [system console](../system-management/system-management.md#access-the-system-console). - -- An image pull secret provided by Spectro Cloud support. - -## Configure the Image Pull Secret in the System Console - -After you receive your image pull secret from Spectro Cloud support, use the system console to configure it. +## Image Pull Secret Requirements -1. Log in to the Palette system console. Refer to the - [Access the System Console](../system-management/system-management.md#access-the-system-console) guide. +While pulling any image hosted in a Spectro Cloud-owned repository requires an image pull secret, this secret is +preconfigured in certain Spectro Cloud-maintained environments. -2. From the left main menu, select **Administration**. - -3. Select the **Docker Hardened Images** tab. +### Configuration Required -4. In the **Image Pull Secret** field, paste the image pull secret you received from Spectro Cloud support. +Connected self-hosted Palette and Palette VerteX environments that pull images directly from Spectro Cloud-owned +registries must have an image pull secret configured. This includes environments that do not use +[mirror registries](../system-management/registry-override.md) or +[image swap](../../clusters/cluster-management/image-swap.md) configurations to redirect image pulls to a private +registry. -5. Select **Save**. +### Configuration Not Required - Palette validates the secret immediately. If the secret is invalid or expired, the following error message is - displayed: _"The Image Pull Secret is invalid or expired. Please check it again. If an existing Image Pull Secret - exists, it was not replaced."_ +The following environments do not require you to configure Spectro Cloud's image pull secret: - If the secret is valid, it is saved and distributed to the management plane and all managed workload clusters. +- **SaaS deployments** — Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action + is needed; for dedicated SaaS customers with access to the system console, consult with your customer support + representative. -## Configure the Image Pull Secret During Installation +- **Airgapped self-hosted Palette and Palette VerteX environments** - Assets downloaded from + [Artifact Studio](../../downloads/artifact-studio.md) are automatically authenticated using Spectro Cloud's image pull + secret. When you upload the packs and images to your private registry, you can use your _personal_ image pull secret + to authenticate and retrieve the images from your private registry. [CHECKING WITH ANIRUDH IF THERE IS CURRENTLY A WAY + TO CONFIGURE AN IMAGE PULL SECRET OUTSIDE OF THE HELM INSTALL METHOD] -You can also provide the image pull secret during the initial Palette installation for certain deployment methods. This -configures the secret at install time so that it is available when the system console first starts. - -### Helm Chart Installation +- **Environments with configured mirror registries or image swaps** - Images are pulled from your own private registry, + which bypasses the need for a Spectro Cloud image pull secret. -If you install Palette using a Helm chart, provide the image pull secret in your `values.yaml` file. For more -information, refer to the [Helm Configuration Reference](../install-palette/install-on-kubernetes/palette-helm-ref.md). +- **Workload clusters that pull Spectro Cloud images from a private registry** - The secret is only needed when pulling + directly from Spectro Cloud-hosted registries. - +## Configure Image Pull Secret During Installation -### Enterprise Cluster Installation +Certain installation methods allow you to include the image pull secret during your Palette installation. -If you install Palette using an Enterprise Cluster (EC), you can include the image pull secret in the `spectro-mgmt` -pack values at install time. +- **Helm Chart** - Use the + [`global.imagePullSecret.dockerConfigJson`](../install-palette/install-on-kubernetes/palette-helm-ref.md#image-pull-secret) + field in your `palette/values.yaml` file. - +- **Management Appliance** - Not supported. Configure the secret + [post-installation](#configure-image-pull-secret-post-installation) using the system console. -:::warning +- **Palette CLI** - [APPARENTLY WITH THE SPECTRO-MGMT PACK? I WASN'T AWARE YOU COULD MODIFY THAT WITH THE CLI? CONFIRM + WITH ANIRUDH] -If you installed Palette using an Enterprise Cluster and you configured the image pull secret in the `spectro-mgmt` pack -values, you must also update the pack values during Palette upgrades. If you do not, the pack values overwrite the -system-console-configured secret with an empty value, which results in an upgrade failure. +## Configure Image Pull Secret Post-Installation -This does not apply to Helm chart installations, where the system console manages the secret independently after the -initial install. +Alternatively, you can configure the image pull secret once Palette is installed. This method is the same for all +installation methods. -::: +### Prerequisites -### Appliance Installation +- A self-hosted instance of Palette installed using the Palette CLI, Helm chart, or management appliance. -Day-0 configuration of the image pull secret during Appliance installation is not supported in the current release. If -you deploy Palette using an Appliance, configure the image pull secret through the system console after installation -completes. +- Access to the [system console](../system-management/system-management.md#access-the-system-console). -## Rotate an Image Pull Secret +- An image pull secret provided by Spectro Cloud support. -If you need to replace an existing image pull secret, for example due to a security incident or as part of a scheduled -rotation, use the system console. +### Enablement -1. Log in to the Palette system console. +1. Log in to the Palette [system console](../system-management/system-management.md#access-the-system-console). Refer to + the [Access the System Console](../system-management/system-management.md#access-the-system-console) guide. 2. From the left main menu, select **Administration**. -3. Select the **Docker Hardened Images** tab. - -4. In the **Image Pull Secret** field, paste the new image pull secret. - -5. Select **Save**. +3. Select the **Hardened Images** tab. - A confirmation dialog is displayed with the message: _"An Image Pull Secret is already configured. Updating it now - will replace it with the new one in Palette/VerteX and your workload clusters. Are you sure you want to proceed?"_ +4. In the **Pull secret** field, paste the image pull secret you received from Spectro Cloud support. -6. Select **Confirm** to proceed with the rotation. +5. Select **Validate and Save**. - Palette validates the new secret. If valid, it replaces the previous secret and distributes the updated secret to the - management plane and all managed workload clusters. +If the secret is valid, it is saved and distributed to the management plane, workload clusters, and PCGs. If you need to +rotate your image pull secret for any reason, repeat these steps, and paste your new secret into the **Pull secret** +field. -To request a new image pull secret, contact your Spectro Cloud support representative. +### Validate -## Validate +[INCLUDE TERMINAL STEPS?] 1. Log in to the Palette system console. 2. From the left main menu, select **Administration**. -3. Select the **Docker Hardened Images** tab. +3. Select the **Hardened Images** tab. -4. Verify that the **Image Pull Secret** field displays a configured secret. +4. Verify that the **Pull secret** field displays a masked secret. diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md index c48f16a2fba..dc88c51acd1 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md @@ -111,17 +111,17 @@ The following instructions are agnostic to the Kubernetes distribution you are u infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your environment. Reach out to our support team if you need assistance. -1. Open a terminal session and navigate to the directory where you downloaded the Palette installation zip file - provided by our support. Unzip the file to a directory named **palette-install**. +1. Open a terminal session and navigate to the directory where you downloaded the Palette install zip file provided by + our support team. Unzip the file to a directory named `palette-install`. ```shell - unzip release-*.zip -d palette-install + unzip charts.zip -d palette-install ``` -2. Navigate to the release folder inside the **palette-install** directory. +2. Navigate to the `palette-install` directory. ```shell - cd palette-install/charts/release-* + cd palette-install ``` 3. Open the file **extras/cert-manager/values.yaml** in a text editor and append the URL to your OCI registry, which @@ -137,18 +137,17 @@ environment. Reach out to our support team if you need assistance. amceResolverImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" ``` -4. Install Cert Manager using the following command. Replace the actual file name of the Cert Manager Helm Chart with - the one you downloaded, as the version number may be different. +4. Install Cert-Manager using the following command. ```shell helm upgrade --values extras/cert-manager/values.yaml \ cert-manager extras/cert-manager/cert-manager-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "cert-manager" does not exist. Installing it now. NAME: cert-manager - LAST DEPLOYED: Mon Jan 29 16:32:33 2024 + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 NAMESPACE: default STATUS: deployed REVISION: 1 diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md index e350c7344e0..b23efa22016 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md @@ -104,34 +104,32 @@ underlying infrastructure provider and your Kubernetes distribution, you may nee your environment. Reach out to our support team if you need assistance. 1. Open a terminal session and navigate to the directory where you downloaded the Palette install zip file provided by - our support. Unzip the file to a directory named **palette-install**. + our support team. Unzip the file to a directory named `palette-install`. ```shell unzip charts.zip -d palette-install ``` -2. Navigate to the **palette-install** directory. +2. Navigate to the `palette-install` directory. ```shell cd palette-install ``` -3. Install Cert Manager using the following command. Replace the actual file name of the Cert Manager Helm Chart with - the one you downloaded, as the version number may be different. +3. Install Cert-Manager using the following command. ```shell helm upgrade --values extras/cert-manager/values.yaml \ cert-manager extras/cert-manager/cert-manager-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "cert-manager" does not exist. Installing it now. NAME: cert-manager - LAST DEPLOYED: Fri Jan 30 18:40:57 2026 + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 NAMESPACE: default STATUS: deployed REVISION: 1 - DESCRIPTION: Install complete TEST SUITE: None ``` @@ -146,52 +144,71 @@ your environment. Reach out to our support team if you need assistance. ```shell hideClipboard title="Example output" Release "spectro-mgmt-crds" does not exist. Installing it now. NAME: spectro-mgmt-crds - LAST DEPLOYED: Fri Jan 30 18:42:30 2026 + LAST DEPLOYED: Wed Jun 17 12:55:23 2026 NAMESPACE: default STATUS: deployed REVISION: 1 - DESCRIPTION: Install complete TEST SUITE: None ``` -5. Open the **values.yaml** in the **palette/spectro-mgmt-plane** folder with a text editor of your choice. The - **values.yaml** contains the default values for the Palette installation parameters, however, you must populate the - following parameters before installing Palette. You can learn more about the parameters in the **values.yaml** file - in the [Helm Configuration Reference](palette-helm-ref.md) page. +5. Open the file `values.yaml` in the `palette` directory with a text editor of your choice. This example uses Vim. + + ```shell + vim palette/values.yaml + ``` + +6. The file `values.yaml` contains the default values for the Palette installation parameters. You must populate the + following parameters before installing Palette. For a complete list of fields and additional information, refer to + [Helm Configuration Reference](palette-helm-ref.md) page. + + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | The image pull secret provided by your Spectro Cloud customer support representative. This secret is required if you plan to pull images hosted in a Spectro Cloud-owned registry. If you omit this during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information.

Alternately, if you plan to pull images from your own private registry, use the base64-encoded contents of your `config.json` containing the registry credentials. | string | + | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + ### Self-Hosted OCI Registries + + The following parameters are required if you pull Palette images from a self-hosted OCI registry instead of a + Spectro Cloud-owned registry or AWS ECR. + + | **Parameter** | **Description** | **Type** | + | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](palette-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](palette-helm-ref.md#oci-image-registry) page for examples. | string | + | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | + | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | :::info - If you are installing Palette by pulling required images from a private mirror registry, you will need to provide - the credentials to your registry in the **values.yaml** file. For more information, refer to - [Helm Configuration Reference](palette-helm-ref.md#image-pull-secret). + Include `/v2` in your mirror registry endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. ::: - Save the **values.yaml** file after you have populated the required parameters mentioned in the table. Expand the - following sections to review an example of the **values.yaml** file with the required parameters highlighted. +7. Save the completed `values.yaml` file. Expand the following sections to review an example of the `values.yaml` file + with the required parameters highlighted. - ```yaml {60,84-92} + ```yaml hideClipboard title="Example values.yaml" {60,84-92} ######################### # Spectro Cloud Palette # ######################### global: imagePullSecret: - create: false # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # MongoDB Configuration mongo: @@ -212,7 +229,7 @@ your environment. Reach out to our support team if you need assistance. storageClass: "" # leave empty to use the default storage class config: - installationMode: "central" #values can be connected or airgap. + installationMode: "connected" #values can be connected or airgap. # SSO SAML Configuration (Optional for self-hosted type) sso: @@ -300,8 +317,8 @@ your environment. Reach out to our support team if you need assistance. # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.8.a-v2" - imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.8.a-v2" + imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" imageSwapConfig: isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false @@ -396,16 +413,15 @@ your environment. Reach out to our support team if you need assistance. - ```yaml {61,76-83,95-103} + ```yaml hideClipboard title="Example values.yaml" {61,76-83,95-103} ######################### # Spectro Cloud Palette # ######################### global: imagePullSecret: - create: false # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # MongoDB Configuration mongo: @@ -515,8 +531,8 @@ your environment. Reach out to our support team if you need assistance. # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.8.a-v2" - imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.8.a-v2" + imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" imageSwapConfig: isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false @@ -611,25 +627,35 @@ your environment. Reach out to our support team if you need assistance. - :::warning - - Ensure you have configured the **values.yaml** file with the required parameters before proceeding to the next - steps. +8. (Self-hosted OCI registry only) If you configured `ociImageRegistry` in `values.yaml`, install the Image Swap Helm + chart before installing Palette. Image Swap rewrites pod image references to pull from your mirror registry. Palette + ignores the `mirrorRegistries` configuration unless the Image Swap chart is installed. - ::: + ```shell + helm upgrade --values palette/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install + ``` -6. This step is only required if you are installing Palette in an environment where a network proxy must be configured - for Palette to access the internet. If you are not using a network proxy, skip to the next step. + ```shell hideClipboard title="Example output" + Release "image-swap" does not exist. Installing it now. + NAME: image-swap + LAST DEPLOYED: Wed Jun 17 14:44:13 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` - Install the reach-system chart using the following command. Point to the **values.yaml** file you configured in - step 5. Make sure you configure the `reach-system.enable` section in the **values.yaml** file. +9. (Proxy environments only) If you are installing Palette in an environment where a network proxy must be configured + for Palette to access the internet, install the reach-system chart using the following command. Ensure you set + `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `values.yaml`. ```shell helm upgrade --values palette/values.yaml \ reach-system extras/reach-system/reach-system-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "reach-system" does not exist. Installing it now. NAME: reach-system LAST DEPLOYED: Fri Jan 30 18:40:57 2026 @@ -641,7 +667,7 @@ your environment. Reach out to our support team if you need assistance.
- How to update containerd to use proxy configurations + Update containerd to use proxy configurations If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy settings. You can do this by updating the containerd configuration file on each node in the cluster. The @@ -658,25 +684,24 @@ your environment. Reach out to our support team if you need assistance.
-7. Install the Palette Helm Chart using the following command. +10. Install the Palette Helm chart using the following command. ```shell helm upgrade --values palette/values.yaml \ hubble palette/spectro-mgmt-plane-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "hubble" does not exist. Installing it now. NAME: hubble - LAST DEPLOYED: Fri Jan 30 18:46:53 2026 + LAST DEPLOYED: Wed Jun 17 13:32:33 2026 NAMESPACE: default STATUS: deployed REVISION: 1 - DESCRIPTION: Install complete TEST SUITE: None ``` -8. Track the installation process using the command below. Palette is ready when the deployments in the namespaces +11. Track the installation process using the command below. Palette is ready when the deployments in the namespaces `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The installation takes between two to three minutes to complete. @@ -693,7 +718,7 @@ your environment. Reach out to our support team if you need assistance. ::: -9. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the +12. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the following command to retrieve the load balancer IP address. You may require the assistance of your network administrator to create the DNS record. @@ -713,11 +738,10 @@ your environment. Reach out to our support team if you need assistance. ::: -10. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. system - console, open a web browser and paste the custom domain URL in the address bar and append the value `/system`. - Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. - Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system - console. +13. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. Open a web + browser and paste the custom domain URL in the address bar and append the value `/system`. Replace the domain name + in the URL with your custom domain name or the IP address of the load balancer. Alternatively, you can use the load + balancer IP address with the appended value `/system` to access the system console. The first time you visit the Palette system console, a warning message about a not trusted SSL certificate may appear. This is expected, as you have not yet uploaded your SSL certificate to Palette. You can ignore this warning @@ -725,7 +749,7 @@ your environment. Reach out to our support team if you need assistance. ![Screenshot of the Palette system console showing Username and Password fields.](/palette_installation_install-on-vmware_palette-system-console.webp) -11. Log in to the system console using the following default credentials. Refer to the +14. Log in to the system console using the default credentials. Refer to the [password requirements](../../system-management/account-management/credentials.md#password-requirements-and-security) documentation page to learn more about password requirements @@ -734,13 +758,13 @@ your environment. Reach out to our support team if you need assistance. | Username | `admin` | | Password | `admin` | - After login, you will be prompted to create a new password. Enter a new password and save your changes. You will be + After logging in, you are prompted to create a new password. Enter a new password and save your changes. You will be redirected to the Palette system console. Use the username `admin` and your new password to log in to the system console. You can create additional system administrator accounts and assign roles to users in the system console. Refer to the [Account Management](../../system-management/account-management/account-management.md) documentation page for more information. -12. After login, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a +15. After logging in, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority files to Palette. You can upload the files using the Palette system console. Refer to the [Configure HTTPS Encryption](../../system-management/ssl-certificate-management.md) page for instructions on how to @@ -754,78 +778,89 @@ your environment. Reach out to our support team if you need assistance. ::: -You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the -**values.yaml** file as you may need it for future upgrades. +You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the `values.yaml` +file, as you can refer to it for future upgrades. ## Validate Use the following steps to validate the Palette installation. + + + + 1. Open up a web browser and navigate to the Palette system console. To access the system console, open a web browser and paste the `env.rootDomain` value you provided in the address bar and append the value `/system`. You can also use the IP address of the load balancer. -2. Log in using the credentials you received from our support team. After login, you will be prompted to create a new - password. Enter a new password and save your changes. You will be redirected to the Palette system console. - -3. Open a terminal session and issue the following command to verify the Palette installation. The command should return - a list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` - namespaces. - - ```shell - kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ - | grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' - ``` - - Your output should look similar to the following. - - ```shell hideClipboard - cp-system spectro-cp-ui-78c9b7dcc5-q8ln4 Running - hubble-system auth-58bc56bc79-68lbg Running - hubble-system auth-58bc56bc79-r2md8 Running - hubble-system cloud-8475845cff-dnq27 Running - hubble-system cloud-8475845cff-v2cww Running - hubble-system configserver-74dd648bf5-6tvmv Running - hubble-system event-68cfb57f6d-9dx5b Running - hubble-system event-68cfb57f6d-g5zrl Running - hubble-system event-68cfb57f6d-rz4sz Running - hubble-system foreq-6c75b84554-x4f7h Running - hubble-system hashboard-7b69cc685f-d8mmw Running - hubble-system hashboard-7b69cc685f-mbb57 Running - hubble-system hutil-5456dfbdd7-68p4m Running - hubble-system hutil-5456dfbdd7-dllfj Running - hubble-system memstore-8654b49cfd-npqbv Running - hubble-system mgmt-55985b7ccb-gpvnr Running - hubble-system mongo-0 Running - hubble-system mongo-1 Running - hubble-system mongo-2 Pending - hubble-system mongodb-key-manager-helm-4z2mw Running - hubble-system msgbroker-0 Running - hubble-system msgbroker-1 Running - hubble-system oci-proxy-787fd499d4-f772t Running - hubble-system specman-0 Running - hubble-system spectro-tunnel-69448888-qn7kk Running - hubble-system spectrocluster-54fb864b48-8fhkr Running - hubble-system spectrocluster-54fb864b48-9hkgg Running - hubble-system spectrocluster-54fb864b48-w5dwr Running - hubble-system spectrocluster-jobs-6ddfbddcd6-j9xb8 Running - hubble-system spectrocluster-reconciler-d448fc8cf-qr6bp Running - hubble-system spectroclusterop-89968785d-6n48l Running - hubble-system spectroclusterop-89968785d-gzd5w Running - hubble-system spectrossh-d5fd6b49-wfcgc Running - hubble-system system-6f7767845d-lm5zn Running - hubble-system system-6f7767845d-xf2hl Running - hubble-system timeseries-6f5bf98c5c-fcqnh Running - hubble-system timeseries-6f5bf98c5c-vmb5h Running - hubble-system timeseries-6f5bf98c5c-xm8s6 Running - hubble-system user-796c877b57-6rcdp Running - hubble-system user-796c877b57-ptbg4 Running - ingress-traefik traefik-ingress-controller-9dmzq Running - ingress-traefik traefik-ingress-controller-tpwtf Running - ingress-traefik traefik-ingress-controller-xz4jf Running - jet-system jet-555cdf78f5-4l2s2 Running - ui-system spectro-ui-8658f85c85-9lkhs Running - ``` +2. Log in using the default credentials. After logging in, you are prompted to create a new password. Enter a new + password and save your changes. You are redirected to the Palette system console. + + + + + +Open a terminal session and issue the following command to verify the Palette installation. The command should return a +list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` namespaces. + +```shell +kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ +| grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' +``` + +Your output should look similar to the following. + +```shell hideClipboard + cp-system spectro-cp-ui-78c9b7dcc5-q8ln4 Running + hubble-system auth-58bc56bc79-68lbg Running + hubble-system auth-58bc56bc79-r2md8 Running + hubble-system cloud-8475845cff-dnq27 Running + hubble-system cloud-8475845cff-v2cww Running + hubble-system configserver-74dd648bf5-6tvmv Running + hubble-system event-68cfb57f6d-9dx5b Running + hubble-system event-68cfb57f6d-g5zrl Running + hubble-system event-68cfb57f6d-rz4sz Running + hubble-system foreq-6c75b84554-x4f7h Running + hubble-system hashboard-7b69cc685f-d8mmw Running + hubble-system hashboard-7b69cc685f-mbb57 Running + hubble-system hutil-5456dfbdd7-68p4m Running + hubble-system hutil-5456dfbdd7-dllfj Running + hubble-system memstore-8654b49cfd-npqbv Running + hubble-system mgmt-55985b7ccb-gpvnr Running + hubble-system mongo-0 Running + hubble-system mongo-1 Running + hubble-system mongo-2 Pending + hubble-system mongodb-key-manager-helm-4z2mw Running + hubble-system msgbroker-0 Running + hubble-system msgbroker-1 Running + hubble-system oci-proxy-787fd499d4-f772t Running + hubble-system specman-0 Running + hubble-system spectro-tunnel-69448888-qn7kk Running + hubble-system spectrocluster-54fb864b48-8fhkr Running + hubble-system spectrocluster-54fb864b48-9hkgg Running + hubble-system spectrocluster-54fb864b48-w5dwr Running + hubble-system spectrocluster-jobs-6ddfbddcd6-j9xb8 Running + hubble-system spectrocluster-reconciler-d448fc8cf-qr6bp Running + hubble-system spectroclusterop-89968785d-6n48l Running + hubble-system spectroclusterop-89968785d-gzd5w Running + hubble-system spectrossh-d5fd6b49-wfcgc Running + hubble-system system-6f7767845d-lm5zn Running + hubble-system system-6f7767845d-xf2hl Running + hubble-system timeseries-6f5bf98c5c-fcqnh Running + hubble-system timeseries-6f5bf98c5c-vmb5h Running + hubble-system timeseries-6f5bf98c5c-xm8s6 Running + hubble-system user-796c877b57-6rcdp Running + hubble-system user-796c877b57-ptbg4 Running + ingress-traefik traefik-ingress-controller-9dmzq Running + ingress-traefik traefik-ingress-controller-tpwtf Running + ingress-traefik traefik-ingress-controller-xz4jf Running + jet-system jet-555cdf78f5-4l2s2 Running + ui-system spectro-ui-8658f85c85-9lkhs Running +``` + + + + ## Next Steps diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index fd5d3b7c829..ef583e55c78 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -36,20 +36,38 @@ The global block allows you to provide configurations that apply globally to the ### Image Pull Secret -The `imagePullSecret` block allows you to provide image pull secrets that will be used to authenticate with private -registries to obtain the images required for Palette installation. This is relevant if you have your own mirror -registries you use for Palette installation. +:::warning + +Spectro Cloud's image pull secret will be required in an upcoming release for any users pulling images from a Spectro +Cloud-owned registry. This is a breaking change. We recommend obtaining your secret as soon as possible to avoid service +disruptions. Refer to +[Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) +for more information. + +::: + +The `imagePullSecret` block configures the image pull secret used to authenticate with private registries. Palette +always creates a Kubernetes Secret named `spectro-image-pull-secret` from this value and distributes it to the +management plane, workload clusters, and PCGs. The secret serves the following purposes: + +- **Spectro Cloud registry authentication** - Authenticates with Spectro Cloud's registries to pull security-hardened + images. These images are used by the management plane, workload clusters, and PCGs. To obtain this secret, contact + your Spectro Cloud customer support representative. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. + +- **Private registry authentication** - If you host Palette images in your own private registry, the secret provides the + credentials needed to pull those images. -| **Parameters** | **Description** | **Type** | **Default value** | -| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | -| `create` | Specifies whether to create a secret containing credentials to your own private image registry. | Boolean | `false` | -| `dockerConfigJson` | The **config.json** file value containing the registry URL and credentials for your image registry in base64 encoded format on a single line. For more information about the **config.json** file, refer to [Kubernetes Documentation](https://kubernetes.io/docs/concepts/containers/images/#config-json). | String | None | +| **Parameters** | **Description** | **Type** | **Default value** | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | +| `dockerConfigJson` | The values of the `config.json` file encoded in base64 as a single string, containing the registry URL and credentials for your image registry. For more information about the `config.json` file, refer to the [Kubernetes Documentation](https://kubernetes.io/docs/concepts/containers/images/#config-json). | String | `""` | :::info -To obtain the base-64 encoded version of the credential `config.json` file, you can issue the following command. Replace +To obtain the base64-encoded version of your `config.json` file, use the following command. Replace `` with the path to your `config.json` file. The `tr -d '\n'` removes new line characters -and produce the output on a single line. +and produces the output on a single line. ```shell cat | base64 | tr -d '\n' @@ -60,7 +78,6 @@ cat | base64 | tr -d '\n' ```yaml global: imagePullSecret: - create: true dockerConfigJson: ewoJImF1dGhzHsKCQkiaG9va3......MiOiAidHJ1ZSIKCX0KfQ # Base64 encoded config.json ``` @@ -316,8 +333,8 @@ config: ### Image Swap Configuration You can configure Palette to use image swap to download the required images. This is an advanced configuration option, -and it is only required for air-gapped deployments. You must also install the Palette Image Swap Helm chart to use this -option, otherwise, Palette will ignore the configuration. +and it is only required for airgapped deployments or when you use a self-hosted OCI registry. You must also install the +Palette Image Swap Helm chart to use this option, otherwise, Palette will ignore the configuration. | **Parameters** | **Description** | **Type** | **Default value** | | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------- | diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md index 4804174770e..6105e4365d0 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md @@ -251,54 +251,53 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet ::: -8. Navigate to the directory with the Palette installation zip file. Unzip the file to a **palette-install** directory. +8. Navigate to the directory where you downloaded the Palette install zip file provided by our support team. Unzip the + file to a directory named `palette-install`. ```shell - unzip release-*.zip -d palette-install + unzip charts.zip -d palette-install ``` -9. Navigate to the release directory inside **palette-install**. +9. Navigate to the `palette-install` directory. ```shell - cd palette-install/charts/release-* + cd palette-install ``` -10. In a code editor of your choice, open the **extras/cert-manager/values.yaml** file and replace the - `cainjectorImage`,`controllerImage`, `webhookImage`, and `amceResolverImage` image URLs and with your OCI image - registry URL and the `/spectro-images/` namespace. +10. Open the file `extras/cert-manager/values.yaml` with a text editor of your choice. This example uses Vim. - ```yaml {2-5} - image: - cainjectorImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" - - featureGates: "AdditionalCertificateOutputFormats=true" + ```shell + vim extras/cert-manager/values.yaml ``` - Consider the following example for reference. +11. Append `` to each image, along with the `` where you want to store your images. - ```yaml {2-5} + ```yaml {2-5} hideClipboard title="Example output" image: - cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` + + In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. - featureGates: "AdditionalCertificateOutputFormats=true" + ```yaml {2-5} hideClipboard title="Example output" + image: + cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" ``` -11. Update the cert-manager chart using the following command. +12. Update the cert-manager chart using the following command. ```shell helm upgrade --values extras/cert-manager/values.yaml \ cert-manager extras/cert-manager/cert-manager-*.tgz --install ``` - You should receive an output similar to the following. - - ```shell + ```shell hideClipboard title="Example output" Release "cert-manager" has been upgraded. Happy Helming! NAME: cert-manager LAST DEPLOYED: Thu Feb 22 19:42:33 2024 @@ -308,29 +307,27 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -12. Prepare the Palette configuration file `values.yaml`. If you saved `values.yaml` used during the Palette - installation, you can reuse it for the upgrade. Alternatively, follow the - [Kubernetes Installation Instructions](../../install-palette/install-on-kubernetes/install.md) to populate your - `values.yaml`. +13. Open the file `palette/values.yaml` with a text editor of your choice. This example uses Vim. - :::warning - - Ensure that the `values.yaml` file is ready before proceeding. Specifically, make sure that the `ociPackEcrRegistry` - and `ociImageRegistry` configurations include the parameters necessary to interact with your `spectro-images` and - `spectro-packs` repositories. + ```shell + vim palette/values.yaml + ``` - ::: +14. Prepare the Palette configuration `palette/values.yaml` file. If you saved your `values.yaml` used during the + Palette installation, you can refer to it when upgrading. Ensure you carry over any necessary configurations, such + as root domains, certificates, image-swap paths, and registries. Refer to + [Kubernetes Installation Instructions](../../install-palette/install-on-kubernetes/airgap-install/install.md) for + basic `values.yaml` guidance. For a full list of parameters, refer to + [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). -13. Upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 12. +15. Upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 14. ```shell helm upgrade --values palette/values.yaml \ image-swap extras/image-swap/image-swap-*.tgz --install ``` - You should receive an output similar to the following. - - ```shell + ```shell hideClipboard title="Example output" Release "image-swap" has been upgraded. Happy Helming! NAME: image-swap LAST DEPLOYED: Thu Feb 22 19:44:13 2024 @@ -340,16 +337,14 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -14. Upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 12. +16. Upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 14. ```shell helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-\*.tgz --install + reach-system extras/reach-system/reach-system-*.tgz --install ``` - You should receive an output similar to the following. - - ```shell + ```shell hideClipboard title="Example output" Release "reach-system" has been upgraded. Happy Helming! NAME: reach-system LAST DEPLOYED: Thu Feb 22 19:47:10 2024 @@ -359,7 +354,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -15. Upgrade the Spectro Management CRDs chart. +17. Upgrade the Spectro Management CRDs chart. ```shell helm upgrade --install spectro-mgmt-crds \ @@ -367,9 +362,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet --values extras/spectro-mgmt-crds/values.yaml ``` - You should receive an output similar to the following. - - ```shell + ```shell hideClipboard title="Example output" Release "spectro-mgmt-crds" has been upgraded. Happy Helming! NAME: spectro-mgmt-crds LAST DEPLOYED: Thu Feb 22 19:43:00 2024 @@ -379,16 +372,14 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -16. Upgrade Palette with the following command. +18. Upgrade Palette with the following command. ```shell helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-\*.tgz --install + hubble palette/spectro-mgmt-plane-*.tgz --install ``` - You should receive an output similar to the following. - - ```shell + ```shell hideClipboard title="Example output" Release "hubble" has been upgraded. Happy Helming! NAME: hubble LAST DEPLOYED: Thu Feb 22 20:05:24 2024 @@ -398,7 +389,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -17. Use the following command to track the upgrade process. +19. Use the following command to track the upgrade process. ```shell kubectl get pods --all-namespaces --watch diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md index 4d1a4afaba7..481772fcd4b 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md @@ -57,150 +57,129 @@ match your environment. ::: -1. Open a terminal session and navigate to the directory with the Palette installation zip file. Unzip the file to a - **palette-install** directory. - - ```shell - unzip release-*.zip -d palette-install - ``` - -2. Navigate to the release directory inside **palette-install**. - - ```shell - cd palette-install/charts/release-* - ``` - -3. Update the cert-manager chart using the following command. - - ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install - ``` - - You should receive an output similar to the following. - - ```shell - Release "cert-manager" has been upgraded. Happy Helming! - NAME: cert-manager - LAST DEPLOYED: Thu Feb 22 19:42:33 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 2 - TEST SUITE: None - ``` - -4. Upgrade the Spectro Management CRDs chart. - - ```shell - helm upgrade --install spectro-mgmt-crds \ - extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ - --values extras/spectro-mgmt-crds/values.yaml - ``` - - You should receive an output similar to the following. - - ```shell - Release "spectro-mgmt-crds" has been upgraded. Happy Helming! - NAME: spectro-mgmt-crds - LAST DEPLOYED: Thu Feb 22 19:43:00 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 2 - TEST SUITE: None - ``` - -5. Prepare the Palette configuration file `values.yaml`. If you saved `values.yaml` used during the Palette - installation, you can reuse it for the upgrade. Alternatively, follow the - [Kubernetes Installation Instructions](../../install-palette/install-on-kubernetes/install.md) to populate your - `values.yaml`. - - :::warning - - Ensure that the `values.yaml` file is ready before proceeding. If you are using a self-hosted OCI registry, make sure - that the `ociImageRegistry.mirrorRegistries` parameter in your `values.yaml` includes the necessary mirror links. - - Include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - -6. If you are using a self-hosted OCI registry, upgrade the image-swap chart with the following command. Point to the - `palette/values.yaml` file from step 5. - - ```shell - helm upgrade --values palette/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - You should receive an output similar to the following. - - ```shell - Release "image-swap" has been upgraded. Happy Helming! - NAME: image-swap - LAST DEPLOYED: Thu Feb 22 19:44:13 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 2 - TEST SUITE: None - ``` - -7. If you are upgrading a Palette instance in an environment that requires network proxy configuration, upgrade the - reach-system chart with the following command. Point to the `palette/values.yaml` file from step 5. - - ```shell - helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-\*.tgz --install - ``` - - You should receive an output similar to the following. - - ```shell - Release "reach-system" has been upgraded. Happy Helming! - NAME: reach-system - LAST DEPLOYED: Thu Feb 22 19:47:10 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 2 - TEST SUITE: None - ``` - -8. Upgrade Palette with the following command. - - ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-\*.tgz --install - ``` - - You should receive an output similar to the following. - - ```shell - Release "hubble" has been upgraded. Happy Helming! - NAME: hubble - LAST DEPLOYED: Thu Feb 22 20:05:24 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 2 - TEST SUITE: None - ``` - -9. Use the following command to track the upgrade process. - - ```shell - kubectl get pods --all-namespaces --watch - ``` - - :::tip - - For a more user-friendly experience, consider using [K9s](https://k9scli.io/) or a similar tool to track the upgrade. - - ::: - - The upgrade usually takes up to five minutes. Palette is upgraded when the deployments in the namespaces `cp-system`, - `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` are in the **Ready** status. +1. Open a terminal session and navigate to the directory where you downloaded the Palette install ZIP file provided by + our support. Unzip the file to a directory named `palette-install`. + + ```shell + unzip charts.zip -d palette-install + ``` + +2. Navigate to the `palette-install` directory. + + ```shell + cd palette-install + ``` + +3. Update the cert-manager chart using the following command. + + ```shell + helm upgrade --values extras/cert-manager/values.yaml \ + cert-manager extras/cert-manager/cert-manager-*.tgz --install + ``` + + ```shell hideClipboard title="Example output" + Release "cert-manager" has been upgraded. Happy Helming! + NAME: cert-manager + LAST DEPLOYED: Wed Jun 17 14:54:45 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 2 + TEST SUITE: None + ``` + +4. Upgrade the Spectro Management CRDs chart. + + ```shell + helm upgrade --install spectro-mgmt-crds \ + extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ + --values extras/spectro-mgmt-crds/values.yaml + ``` + + ```shell hideClipboard title="Example output" + Release "spectro-mgmt-crds" has been upgraded. Happy Helming! + NAME: spectro-mgmt-crds + LAST DEPLOYED: Wed Jun 17 14:55:28 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 2 + TEST SUITE: None + ``` + +5. Prepare the Palette configuration file `values.yaml`. If you saved your `values.yaml` used during the Palette + installation, you can refer to it when upgrading. Ensure you carry over any necessary configurations, such as root + domains, certificates, image-swap paths, and registries. Refer to + [Kubernetes Installation Instructions](../../install-palette/install-on-kubernetes/install.md) for basic + `values.yaml` guidance. For a full list of parameters, refer to + [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). + +6. If you are using a self-hosted OCI registry, upgrade the image-swap chart with the following command. Point to the + `palette/values.yaml` file from step 5. + + ```shell + helm upgrade --values palette/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install + ``` + + ```shell hideClipboard title="Example output" + Release "image-swap" has been upgraded. Happy Helming! + NAME: image-swap + LAST DEPLOYED: Thu Feb 22 19:44:13 2024 + NAMESPACE: default + STATUS: deployed + REVISION: 2 + TEST SUITE: None + ``` + +7. If you are upgrading a Palette instance in an environment that requires network proxy configuration, upgrade the + reach-system chart with the following command. Point to the `palette/values.yaml` file from step 5. + + ```shell + helm upgrade --values palette/values.yaml \ + reach-system extras/reach-system/reach-system-*.tgz --install + ``` + + ```shell hideClipboard title="Example output" + Release "reach-system" has been upgraded. Happy Helming! + NAME: reach-system + LAST DEPLOYED: Thu Feb 22 19:47:10 2024 + NAMESPACE: default + STATUS: deployed + REVISION: 2 + TEST SUITE: None + ``` + +8. Upgrade Palette with the following command. + + ```shell + helm upgrade --values palette/values.yaml \ + hubble palette/spectro-mgmt-plane-*.tgz --install + ``` + + ```shell hideClipboard title="Example output" + Release "hubble" has been upgraded. Happy Helming! + NAME: hubble + LAST DEPLOYED: Wed Jun 17 15:44:47 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 2 + TEST SUITE: None + ``` + +9. Use the following command to track the upgrade process. + + ```shell + kubectl get pods --all-namespaces --watch + ``` + + :::tip + + For a more user-friendly experience, consider using [K9s](https://k9scli.io/) or a similar tool to track the + upgrade. + + ::: + + The upgrade usually takes up to five minutes. Palette is upgraded when the deployments in the namespaces + `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` are in the **Ready** status. ## Validate @@ -214,7 +193,7 @@ match your environment. `App Version` column of `cert-manager`, `image-swap`, `reach-system`, and `hubble` to verify that they have the expected versions. - ```shell + ```shell hideClipboard title="Example output" NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION cert-manager default 2 2024-02-22 19:42:33.776829 +0100 CET deployed cert-manager-1.11.0 1.11.0 image-swap default 2 2024-02-22 19:44:13.209592 +0100 CET deployed image-swap-v1.5.2-spectro-4.1.1 1.5.2 @@ -232,7 +211,7 @@ match your environment. The command should return a list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` namespaces. All deployments should have the status `Running`. - ```shell + ```shell hideClipboard title="Example output" cp-system spectro-cp-ui-689984f88d-54wsw Running hubble-system auth-85b748cbf4-6drkn Running hubble-system auth-85b748cbf4-dwhw2 Running diff --git a/docs/docs-content/release-notes/announcements.md b/docs/docs-content/release-notes/announcements.md index 6ab84575888..b2ce41a3dfb 100644 --- a/docs/docs-content/release-notes/announcements.md +++ b/docs/docs-content/release-notes/announcements.md @@ -24,9 +24,10 @@ Use the [Find Breaking Changes](breaking-changes.md) page to list all the breaki Stay informed about the upcoming breaking changes in Palette and Palette VerteX. Use the information below to prepare for the changes in your environment. -| Change | Target Date | Published Date | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------- | -------------- | -| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | +| Change | Target Date | Published Date | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------- | +| Spectro Cloud is transitioning to the exclusive use of security-hardened images. As a result, retrieving images from Spectro Cloud-owned registries will now require a Spectro Cloud image pull secret. This secret is intended for long-term use and is configured in the system console once as part of the initial setup process. Image pulls from Spectro Cloud-owned repositories will not be allowed unless a valid image pull secret is configured.

This change primarily affects connected self-hosted environments that do not configure mirror registries or image swap; it does not apply to airgapped environments, which pull images from their own registries. Authentication is automatically handled for SaaS environments and Artifact Studio downloads. To obtain your image pull secret, contact your customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for more information. | August 23, 2026 | June 28, 2026 | +| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | diff --git a/docs/docs-content/release-notes/release-notes.md b/docs/docs-content/release-notes/release-notes.md index eccf3784031..3199a661201 100644 --- a/docs/docs-content/release-notes/release-notes.md +++ b/docs/docs-content/release-notes/release-notes.md @@ -23,6 +23,26 @@ tags: ["release-notes"] #### Features + + +- Spectro Cloud is transitioning to the exclusive use of security-hardened images for increased security posture. These + images have both a smaller size and attack surface, undergo regular security scans and strict patching schedules, and + contain cryptographic signatures to avoid tampering. As a result, retrieving images from Spectro Cloud-owned + registries will require a Spectro Cloud image pull secret. This secret is intended for long-term use and is configured + in the system console once as part of the initial setup process. + + This change primarily affects connected self-hosted environments that do not configure mirror registries or image + swap; it does not apply to airgapped environments, which pull images from their own registries. Authentication is + automatically handled for SaaS environments and Artifact Studio downloads. While configuring an image pull secret is + not required for the current version of Palette, it is an + [upcoming breaking change](./announcements.md#upcoming-breaking-changes) and will be mandated in a future release. We + recommend that affected environments request and configure an image pull secret as soon as possible to prevent service + disruptions later. + + To obtain your image pull secret, contact your customer support representative. Refer to + [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for + more information, including how to implement the image pull secret using the system console. + #### Improvements #### Deprecations and Removals diff --git a/docs/docs-content/tutorials/getting-started/palette-edge/central-management/palette-edge.md b/docs/docs-content/tutorials/getting-started/palette-edge/central-management/palette-edge.md index 621cb722085..6161a03689b 100644 --- a/docs/docs-content/tutorials/getting-started/palette-edge/central-management/palette-edge.md +++ b/docs/docs-content/tutorials/getting-started/palette-edge/central-management/palette-edge.md @@ -86,25 +86,25 @@ designed to guide you step-by-step, building on the concepts introduced in the p title: "Build Edge Artifacts", description: "Build the artifacts required for your Edge deployment.", buttonText: "Learn more", - url: "/tutorials/getting-started/palette-edge/entral-management/build-edge-artifacts", + url: "/tutorials/getting-started/palette-edge/central-management/build-edge-artifacts", }, { title: "Create Edge Cluster Profile", description: "Create an Edge native cluster profile to deploy Edge workloads.", buttonText: "Learn more", - url: "/tutorials/getting-started/palette-edge/entral-management/edge-cluster-profile", + url: "/tutorials/getting-started/palette-edge/central-management/edge-cluster-profile", }, { title: "Prepare Edge Host", description: "Install the Palette agent on your Edge host and register the host with Palette.", buttonText: "Learn more", - url: "/tutorials/getting-started/palette-edge/entral-management/prepare-edge-host", + url: "/tutorials/getting-started/palette-edge/central-management/prepare-edge-host", }, { title: "Deploy Edge Cluster", description: "Deploy an Edge cluster with Palette.", buttonText: "Learn more", - url: "/tutorials/getting-started/palette-edge/entral-management/deploy-edge-cluster", + url: "/tutorials/getting-started/palette-edge/central-management/deploy-edge-cluster", }, ]} /> diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md index 9aa6242a868..bdd5705a2f5 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md @@ -114,95 +114,124 @@ The following instructions are agnostic to the Kubernetes distribution you are u infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your environment. Reach out to our support team if you need assistance. -1. Open a terminal session and navigate to the directory where you downloaded the VerteX installation zip file provided - by our support. Unzip the file to a directory named **vertex-install**. +1. Open a terminal session and navigate to the directory where you downloaded the Palette VerteX install ZIP file + provided by our support team. Unzip the file to a directory named `vertex-install`. ```shell - unzip release-*.zip -d vertex-install + unzip charts.zip -d vertex-install ``` -2. Navigate to the release folder inside the **vertex-install** directory. +2. Navigate to the `vertex-install` directory. ```shell - cd vertex-install/charts/release-* + cd vertex-install ``` -3. Open the file **extras/cert-manager/values.yaml** in a text editor and append the URL to your OCI registry, which - also includes the namespace or project that is hosting the Spectro Cloud images. The URL should be in the format - `/`. In the example configuration below, the value `my-oci-registry.com/spectro-images` is - prefixed to each URL. Save the file after you have appended the URL. +3. Open the file `extras/cert-manager/values.yaml` with a text editor of your choice. This example uses Vim. - ```yaml hideClipboard + ```shell + vim extras/cert-manager/values.yaml + ``` + +4. Append `` to each image, along with the `` where you want to store your images. + + ```yaml {2-5} hideClipboard title="Example output" image: - cainjectorImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" ``` -4. Install Cert Manager using the following command. Replace the actual file name of the Cert Manager Helm Chart with - the one you downloaded, as the version number may be different. + In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. + + ```yaml {2-5} hideClipboard title="Example output" + image: + cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` + +5. Install Cert-Manager using the following command. ```shell helm upgrade --values extras/cert-manager/values.yaml \ cert-manager extras/cert-manager/cert-manager-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "cert-manager" does not exist. Installing it now. NAME: cert-manager - LAST DEPLOYED: Mon Jan 29 16:32:33 2024 + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -5. Open the file **extras/image-swap/values.yaml** in a text editor and append the URL to your OCI registry that also - includes the namespace or project that is hosting the Spectro Cloud images. +6. Extract the image-swap TGZ file. + + ```shell + tar -xvzf extras/image-swap/image-swap-*.tgz -C extras/image-swap + ``` + +7. Open the file `extras/image-swap/image-swap/values.yaml` with a text editor of your choice. This example uses Vim. + + ```shell + vim extras/image-swap/image-swap/values.yaml + ``` + +8. Append the values you used for `` and `` used in step 4 to each image. ```yaml hideClipboard config: imageSwapImages: - imageSwapInitImage: "my-oci-registry.com/spectro-images/gcr.io/spectro-images-public/release/thewebroot/imageswap-init:v1.5.3-spectro-4.5.1" - imageSwapImage: "my-oci-registry.com/spectro-images/gcr.io/spectro-images-public/release/thewebroot/imageswap:v1.5.3-spectro-4.5.1" + imageSwapInitImage: "//us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "//us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" ``` -6. Update the `ociImageRegistry` section with the proper configuration values to your OCI registry. The - `ociImageRegistry` section should look similar to the following example. - - :::info +9. (Non-EKS clusters only) If you are not installing Palette VerteX on an EKS cluster, set `isEKSCluster` to `false`. - Include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. + ```yaml + imageSwapConfig: + isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false + ``` - ::: +10. Update the `ociImageRegistry` section with the proper configuration values for your OCI registry. Use the same + `` and `` values used in steps 4 and 8. ```yaml hideClipboard ociImageRegistry: - endpoint: "my-oci-registry.com" + endpoint: "" name: "Airgap Images OCI" password: "" username: "" - baseContentPath: "spectro-images" + baseContentPath: "" insecureSkipVerify: true caCert: "" - mirrorRegistries: "docker.io::my-oci-registry.com/spectro-images/docker.io,gcr.io::my-oci-registry.com/spectro-images/gcr.io,ghcr.io::my-oci-registry.com/spectro-images/ghcr.io,k8s.gcr.io::my-oci-registry.com/spectro-images/k8s.gcr.io,registry.k8s.io::my-oci-registry.com/spectro-images/registry.k8s.io,quay.io::my-oci-registry.com/spectro-images/quay.io,us-docker.pkg.dev::my-oci-registry.com/spectro-images/us-docker.pkg.dev" + mirrorRegistries: "docker.io::/repository/docker.io,gcr.io:://gcr.io,ghcr.io:://ghcr.io,k8s.gcr.io:://k8s.gcr.io,registry.k8s.io:://registry.k8s.io,quay.io:://quay.io,us-docker.pkg.dev:://us-docker.pkg.dev" ``` -7. Go ahead and install the image-swap chart using the following command. Point to the **values.yaml** file you - configured in steps five through six. + :::info + + Include `/v2` in your endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::/v2//docker.io`. + + ::: + +11. Install the image-swap Helm chart using the following command. ```shell - helm upgrade --values extras/image-swap/values.yaml \ + helm upgrade --values extras/image-swap/image-swap/values.yaml \ image-swap extras/image-swap/image-swap-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "image-swap" does not exist. Installing it now. NAME: image-swap LAST DEPLOYED: Mon Jan 29 17:04:23 2024 @@ -219,14 +248,14 @@ environment. Reach out to our support team if you need assistance. ::: -8. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by +12. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by VerteX, including Traefik CRDs, and must be installed before the main VerteX Helm Chart. ```shell helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "spectro-mgmt-crds" does not exist. Installing it now. NAME: spectro-mgmt-crds LAST DEPLOYED: Mon Jan 29 16:35:00 2024 @@ -236,7 +265,13 @@ environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` -9. Open the **values.yaml** file in the **spectro-mgmt-plane** folder with a text editor of your choice. The +13. Open the file `vertex/values.yaml` using a text editor of your choice. This example uses Vim. + + ```shell + vim vertex/values.yaml + ``` + +14. Open the **values.yaml** file in the **spectro-mgmt-plane** folder with a text editor of your choice. The **values.yaml** file contains the default values for the VerteX installation parameters. However, you must populate the following parameters before installing VerteX. You can learn more about the parameters on the **values.yaml** file on the [Helm Configuration Reference](../vertex-helm-ref.md) page. @@ -244,17 +279,18 @@ environment. Reach out to our support team if you need assistance. Ensure you provide the proper `ociImageRegistry.mirrorRegistries` values if you are using a self-hosted OCI registry. You can find the placeholder string in the `ociImageRegistry` section of the **values.yaml** file. - | **Parameter** | **Description** | **Type** | - | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `env.rootDomain` | The URL name or IP address you will use for the VerteX installation. | string | - | `config.installationMode` | The installation mode for VerteX. The values can be `connected` or `airgap`. Set this value to `airgap`. | string | - | `ociPackEcrRegistry` | The OCI registry credentials for the VerteX FIPS packs repository. | object | - | `ociImageRegistry` | The OCI registry credentials for the VerteX images repository. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in [image swap format](https://github.com/phenixblue/imageswap-webhook/blob/master/docs/configuration.md) to use for pulling images. For example: `docker.io::harbor.example.org/airgap-images/docker.io,gcr.io::harbor.example.org/airgap-images/gcr.io`.

**NOTE:** Include `/v2` in your endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. | string | - | `imageSwapImages` | The image swap configuration for VerteX. If you are using an OCI registry, such as Harbor. Replace the prefix URLs with your OCI registry URL that includes the image namespace or project: `/`. | object | - | `imageSwapConfig.isEKSCluster` | If you are NOT installing VerteX on an EKS cluster, set this value to `false`. | boolean | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reach-system` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters for VerteX to use a network proxy in your environment. | object | + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | The base64-encoded contents of your `config.json` containing your registry credentials. Refer to [Helm Configuration Reference](../vertex-helm-ref.md#image-pull-secret) for more information. | string | + | `env.rootDomain` | The URL name or IP address you will use for the VerteX installation. | string | + | `config.installationMode` | The installation mode for VerteX. The values can be `connected` or `airgap`. Set this value to `airgap`. | string | + | `ociPackEcrRegistry` | The OCI registry credentials for the VerteX FIPS packs repository. | object | + | `ociImageRegistry` | The OCI registry credentials for the VerteX images repository. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in [image swap format](https://github.com/phenixblue/imageswap-webhook/blob/master/docs/configuration.md) to use for pulling images. For example: `docker.io::harbor.example.org/airgap-images/docker.io,gcr.io::harbor.example.org/airgap-images/gcr.io`.

**NOTE:** Include `/v2` in your endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. | string | + | `imageSwapImages` | The image swap configuration for VerteX. If you are using an OCI registry, such as Harbor. Replace the prefix URLs with your OCI registry URL that includes the image namespace or project: `/`. | object | + | `imageSwapConfig.isEKSCluster` | If you are NOT installing VerteX on an EKS cluster, set this value to `false`. | boolean | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reach-system` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters for VerteX to use a network proxy in your environment. | object | :::info @@ -708,7 +744,7 @@ environment. Reach out to our support team if you need assistance. ::: -10. This step is only required if you are installing VerteX in an environment where a network proxy must be configured +15. This step is only required if you are installing VerteX in an environment where a network proxy must be configured for VerteX to access the internet. If you are not using a network proxy, skip to the next step. Install the reach-system chart using the following command. Point to the **values.yaml** file you configured in @@ -748,7 +784,7 @@ environment. Reach out to our support team if you need assistance. -11. Install the VerteX Helm Chart using the following command. +16. Install the VerteX Helm Chart using the following command. ```shell helm upgrade --values vertex/values.yaml \ @@ -765,7 +801,7 @@ environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` -12. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces +17. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The installation takes between two to three minutes to complete. @@ -782,7 +818,7 @@ environment. Reach out to our support team if you need assistance. ::: -13. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the +18. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the following command to retrieve the load balancer IP address. You may require the assistance of your network administrator to create the DNS record. @@ -802,7 +838,7 @@ environment. Reach out to our support team if you need assistance. ::: -14. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the +19. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the system console, open a web browser, paste the custom domain URL in the address bar, and append the value `/system`. The first time you visit the VerteX system console, a warning message about a not-trusted SSL certificate may @@ -811,7 +847,7 @@ environment. Reach out to our support team if you need assistance. ![Screenshot of the VerteX system console showing Username and Password fields.](/vertex_install-on-kubernetes_install_system-console.webp) -15. Log in to the system console using the following default credentials. Refer to the +20. Log in to the system console using the following default credentials. Refer to the [password requirements](../../../system-management/account-management/credentials.md#password-requirements-and-security) documentation page to learn more about password requirements. @@ -826,7 +862,7 @@ environment. Reach out to our support team if you need assistance. Refer to the [Account Management](../../../system-management/account-management/account-management.md) documentation page for more information. -16. After login, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a +21. After login, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a different SSL certificate, you must upload the SSL certificate, SSL certificate key, and SSL certificate authority files to VerteX. You can upload the files using the VerteX system console. Refer to the [Configure HTTPS Encryption](../../../system-management/ssl-certificate-management.md) page for instructions on how diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index 08a48e5f68d..9ccecb25df9 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -360,7 +360,7 @@ Kubernetes. ```shell helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-\*.tgz --install + reach-system extras/reach-system/reach-system-*.tgz --install ``` You should receive an output similar to the following. @@ -379,7 +379,7 @@ Kubernetes. ```shell helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-\*.tgz --install + hubble palette/spectro-mgmt-plane-*.tgz --install ``` You should receive an output similar to the following. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index 79581783fb0..da763dc7771 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -148,7 +148,7 @@ match your environment. ```shell helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-\*.tgz --install + reach-system extras/reach-system/reach-system-*.tgz --install ``` You should receive an output similar to the following. @@ -167,7 +167,7 @@ match your environment. ```shell helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-\*.tgz --install + hubble palette/spectro-mgmt-plane-*.tgz --install ``` You should receive an output similar to the following. diff --git a/static/assets/docs/images/palette_installation_install-on-vmware_palette-system-console.webp b/static/assets/docs/images/palette_installation_install-on-vmware_palette-system-console.webp index ed93c439499e7a0c361474b740f71bad1355654f..1f24c3e126e70d52fa5cc0573310fd847f082193 100644 GIT binary patch literal 51034 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 XIrOw~0^&bk3}A!Q=3ZXs{`vVI!i8Vx From 7bf1c373b22a204a8c4b3892e4ee226a4f463245 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Thu, 18 Jun 2026 19:26:15 -0400 Subject: [PATCH 04/22] Updates from code review, additional cleanup and steps per pritam --- .../configure-image-pull-secret.md | 157 +++-- .../airgap-install/install.md | 2 +- .../install-on-kubernetes/install.md | 34 +- .../install-on-kubernetes/palette-helm-ref.md | 12 +- .../install-on-kubernetes/uninstall.md | 26 +- .../install-on-kubernetes/install.md | 567 ++++++++++++------ .../install-on-kubernetes/vertex-helm-ref.md | 49 +- .../configure-image-pull-secret_palette.webp | Bin 0 -> 48160 bytes ...-on-kubernetes_install_system-console.webp | Bin 17386 -> 57010 bytes 9 files changed, 566 insertions(+), 281 deletions(-) create mode 100644 static/assets/docs/images/configure-image-pull-secret_palette.webp diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md index 2d952bb8746..67b88833c79 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -13,18 +13,18 @@ keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "se Beginning in 4.9.b, Spectro Cloud is initiating the shift to security-hardened images. While images have a smaller attack surface compared to physical and virtual machines, security-hardened images are built to reduce the attack -surface further by containing only the essential runtime components an application needs. They have strict Software -Lifecycle Agreements (SLAs) that require the images to be regularly scanned for vulnerabilities, rebuilt, and patched, -keeping the number of CVEs to a minimum. These images also contain artifacts such as Software Bill of Materials (SBOMs) -and cryptographic signatures to verify the image has not been tampered with. +surface further by containing only the essential runtime components an application needs. They have strict Service Level +Agreements (SLAs) that require the images to be regularly scanned for vulnerabilities, rebuilt, and patched, keeping the +number of CVEs to a minimum. These images also contain artifacts such as Software Bill of Materials (SBOMs) and +cryptographic signatures to verify the image has not been tampered with. -As a result of this transition, all images hosted Spectro Cloud's private repositories must now be authenticated and +As a result of this transition, all images hosted in Spectro Cloud's OCI registries must now be authenticated and retrieved using [image pull secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets-1). Like -activation keys, these secrets are obtained from your Spectro Cloud customer support representative; they are intended -for long-term use and only need to be configured once as part of your initial setup process. If you need to rotate the -secret, whether due to a security incident or as part of your organization's security policy, contact support to request -a new one. +[activation keys](../activate-installation/activate-installation.md), these secrets are obtained from your Spectro Cloud +customer support representative; they are intended for long-term use and only need to be configured once as part of your +initial setup process. If you need to rotate the secret as part of your organization's security policy, contact support +to request a new one. Once configured, the secret is distributed to the management plane, PCGs, and all managed workload clusters so they can pull the required images. @@ -37,70 +37,94 @@ the [Announcements](../../release-notes/announcements.md#upcoming-breaking-chang ::: -## Image Pull Secret Requirements +## When to Configure Image Pull Secret -While pulling any image hosted in a Spectro Cloud-owned repository requires an image pull secret, this secret is -preconfigured in certain Spectro Cloud-maintained environments. +Depending on how your environment retrieves images, you may or may not need to configure Spectro Cloud's image pull +secret. ### Configuration Required -Connected self-hosted Palette and Palette VerteX environments that pull images directly from Spectro Cloud-owned -registries must have an image pull secret configured. This includes environments that do not use +Non-airgapped self-hosted Palette and Palette VerteX environments that pull images directly from Spectro Cloud-owned OCI +registries must configure an image pull secret. This includes environments that _do not_ use [mirror registries](../system-management/registry-override.md) or [image swap](../../clusters/cluster-management/image-swap.md) configurations to redirect image pulls to a private registry. ### Configuration Not Required -The following environments do not require you to configure Spectro Cloud's image pull secret: +Image pull secrets are managed by Spectro Cloud. While you do not need to configure the pull secret, you must ensure +that the secret propagates to your clusters. This happens automatically unless there are connectivity issues from your +cluster to the Palette or Palette VerteX management plane. - **SaaS deployments** — Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action is needed; for dedicated SaaS customers with access to the system console, consult with your customer support representative. -- **Airgapped self-hosted Palette and Palette VerteX environments** - Assets downloaded from - [Artifact Studio](../../downloads/artifact-studio.md) are automatically authenticated using Spectro Cloud's image pull - secret. When you upload the packs and images to your private registry, you can use your _personal_ image pull secret - to authenticate and retrieve the images from your private registry. [CHECKING WITH ANIRUDH IF THERE IS CURRENTLY A WAY - TO CONFIGURE AN IMAGE PULL SECRET OUTSIDE OF THE HELM INSTALL METHOD] +- **Airgapped self-hosted Palette and Palette VerteX environments** - The Spectro Cloud-owned images are pulled directly + from your local registry and do not need the Spectro Cloud's OCI registry pull secret. -- **Environments with configured mirror registries or image swaps** - Images are pulled from your own private registry, - which bypasses the need for a Spectro Cloud image pull secret. +- **Environments with configured mirror registries or image swaps** - If your non-airgapped self-hosted Palette or + Palette VerteX environment pulls all Spectro Cloud-owned images from a custom or private registry through + [mirror registries](../system-management/registry-override.md) or + [image swaps](../../clusters/cluster-management/image-swap.md), you do not need to configure the image pull secret. -- **Workload clusters that pull Spectro Cloud images from a private registry** - The secret is only needed when pulling - directly from Spectro Cloud-hosted registries. +## Configure Image Pull Secret -## Configure Image Pull Secret During Installation +Depending on your installation method, you can configure Spectro Cloud's image pull secret during or after installing +self-hosted Palette. -Certain installation methods allow you to include the image pull secret during your Palette installation. +### During Installation -- **Helm Chart** - Use the - [`global.imagePullSecret.dockerConfigJson`](../install-palette/install-on-kubernetes/palette-helm-ref.md#image-pull-secret) - field in your `palette/values.yaml` file. +You can add your image pull secret when installing self-hosted Palette and Palette VerteX using Helm charts or the +Palette CLI. -- **Management Appliance** - Not supported. Configure the secret - [post-installation](#configure-image-pull-secret-post-installation) using the system console. +Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the +secret [post-installation](#configure-image-pull-secret-post-installation) using the system console. -- **Palette CLI** - [APPARENTLY WITH THE SPECTRO-MGMT PACK? I WASN'T AWARE YOU COULD MODIFY THAT WITH THE CLI? CONFIRM - WITH ANIRUDH] +#### Helm Chart Installations -## Configure Image Pull Secret Post-Installation +For self-hosted Palette or Palette VerteX environments installed on an existing Kubernetes cluster using Helm charts, +you can apply your image pull secret during the installation process. -Alternatively, you can configure the image pull secret once Palette is installed. This method is the same for all -installation methods. +| **File** | **Parameter** | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `palette/values.yaml` or `vertex/values.yaml` | [`global.imagePullSecret.dockerConfigJson`](../install-palette/install-on-kubernetes/palette-helm-ref.md#image-pull-secret) | +| `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | -### Prerequisites +For the full installation process, refer to the appropriate +[Palette](../install-palette/install-on-kubernetes/install.md) or +[Palette VerteX](../../vertex/install-palette-vertex/install-on-kubernetes/install.md) installation guide. -- A self-hosted instance of Palette installed using the Palette CLI, Helm chart, or management appliance. +#### Palette CLI Installations + +[AWAITING INSTRUCTIONS FROM ZULFI] + +Configuring an image pull secret when installing self-hosted Palette using the Palette Management Appliance or Palette +CLI is not supported. + +### Post-Installation + +Alternatively, you can configure the image pull secret once Palette is installed. + +:::warning + +Configuring an image pull secret is currently optional. Once it is mandatory, image pull secrets must be added during +the installation process. At that time, the system console method described below will only be used to rotate the image +pull secret if required by your organization's security policy. + +::: + +#### Prerequisites + +- A self-hosted instance of Palette. - Access to the [system console](../system-management/system-management.md#access-the-system-console). - An image pull secret provided by Spectro Cloud support. -### Enablement +#### Enablement -1. Log in to the Palette [system console](../system-management/system-management.md#access-the-system-console). Refer to - the [Access the System Console](../system-management/system-management.md#access-the-system-console) guide. +1. Log in to the Palette [system console](../system-management/system-management.md#access-the-system-console). 2. From the left main menu, select **Administration**. @@ -114,9 +138,11 @@ If the secret is valid, it is saved and distributed to the management plane, wor rotate your image pull secret for any reason, repeat these steps, and paste your new secret into the **Pull secret** field. -### Validate +#### Validate + + -[INCLUDE TERMINAL STEPS?] + 1. Log in to the Palette system console. @@ -125,3 +151,48 @@ field. 3. Select the **Hardened Images** tab. 4. Verify that the **Pull secret** field displays a masked secret. + + ![Configuring an image pull secret in the system console](/configure-image-pull-secret_palette.webp) + + + + + +1. Open a terminal session in an environment that has network access to the cluster. Set the `KUBECONFIG` environment + variable to the file path of your cluster's kubeconfig that Palette is installed on. + + ```shell + export KUBECONFIG= + ``` + +2. Issue the following command to verify the secret propagated to your management cluster matches the one configured in + the system console. + + ```shell + kubectl get secret spectro-image-pull-secret --namespace hubble-system --output yaml + ``` + + ```yaml title="Example output" hideClipboard {3} + apiVersion: v1 + data: + .dockerconfigjson: abcdEFGhiJKlmnOPQrSTUVwX... # output omitted for brevity + kind: Secret + metadata: + annotations: + meta.helm.sh/release-name: hubble + meta.helm.sh/release-namespace: default + creationTimestamp: "2026-06-18T22:33:37Z" + labels: + app: spectro + app.kubernetes.io/managed-by: Helm + module: hubble + name: spectro-image-pull-secret + namespace: hubble-system + resourceVersion: "28192" + uid: c7991fac-2ec0-4419-b451-10c82208f8e5 + type: kubernetes.io/dockerconfigjson + ``` + + + + diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md index dc88c51acd1..78d4b60bd27 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md @@ -111,7 +111,7 @@ The following instructions are agnostic to the Kubernetes distribution you are u infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your environment. Reach out to our support team if you need assistance. -1. Open a terminal session and navigate to the directory where you downloaded the Palette install zip file provided by +1. Open a terminal session and navigate to the directory where you downloaded the Palette install ZIP file provided by our support team. Unzip the file to a directory named `palette-install`. ```shell diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md index b23efa22016..3cedd67c41a 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md @@ -151,23 +151,23 @@ your environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` -5. Open the file `values.yaml` in the `palette` directory with a text editor of your choice. This example uses Vim. +5. Open the file `palette/values.yaml` using a text editor of your choice. This example uses Vim. ```shell vim palette/values.yaml ``` -6. The file `values.yaml` contains the default values for the Palette installation parameters. You must populate the - following parameters before installing Palette. For a complete list of fields and additional information, refer to - [Helm Configuration Reference](palette-helm-ref.md) page. +6. The file `palette/values.yaml` contains the default values for the Palette installation parameters. You must + populate the following parameters before installing Palette. For a complete list of fields and additional + information, refer to [Helm Configuration Reference](palette-helm-ref.md). - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `global.imagePullSecret.dockerConfigJson` | The image pull secret provided by your Spectro Cloud customer support representative. This secret is required if you plan to pull images hosted in a Spectro Cloud-owned registry. If you omit this during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information.

Alternately, if you plan to pull images from your own private registry, use the base64-encoded contents of your `config.json` containing the registry credentials. | string | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | + | `global.imagePullSecret.dockerConfigJson` | The image pull secret provided by your Spectro Cloud customer support representative. This secret is required if you plan to pull images hosted in a Spectro Cloud-owned registry. If you omit this during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information.

Alternately, if you plan to pull images from your own private registry, use the base64-encoded contents of your `config.json` containing the registry credentials. Refer to [Helm Configuration Reference](palette-helm-ref.md#image-pull-secret) for more information. | string | + | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | ### Self-Hosted OCI Registries @@ -192,8 +192,8 @@ your environment. Reach out to our support team if you need assistance. ::: -7. Save the completed `values.yaml` file. Expand the following sections to review an example of the `values.yaml` file - with the required parameters highlighted. +7. Save the completed `palette/values.yaml` file. Expand the following sections to review an example of the + `palette/values.yaml` file with the required parameters highlighted. @@ -627,9 +627,9 @@ your environment. Reach out to our support team if you need assistance. -8. (Self-hosted OCI registry only) If you configured `ociImageRegistry` in `values.yaml`, install the Image Swap Helm - chart before installing Palette. Image Swap rewrites pod image references to pull from your mirror registry. Palette - ignores the `mirrorRegistries` configuration unless the Image Swap chart is installed. +8. (Self-hosted OCI registry only) If you configured the [Self-Hosted OCI Registry](#self-hosted-oci-registries) + values, install the Image Swap Helm chart. Image Swap rewrites pod image references to pull from your mirror + registry. Palette ignores the `mirrorRegistries` configuration unless the Image Swap chart is installed. ```shell helm upgrade --values palette/values.yaml \ @@ -648,7 +648,7 @@ your environment. Reach out to our support team if you need assistance. 9. (Proxy environments only) If you are installing Palette in an environment where a network proxy must be configured for Palette to access the internet, install the reach-system chart using the following command. Ensure you set - `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `values.yaml`. + `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `palette/values.yaml`. ```shell helm upgrade --values palette/values.yaml \ diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index ef583e55c78..1afd3da9f33 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -63,6 +63,12 @@ management plane, workload clusters, and PCGs. The secret serves the following p | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | | `dockerConfigJson` | The values of the `config.json` file encoded in base64 as a single string, containing the registry URL and credentials for your image registry. For more information about the `config.json` file, refer to the [Kubernetes Documentation](https://kubernetes.io/docs/concepts/containers/images/#config-json). | String | `""` | +```yaml +global: + imagePullSecret: + dockerConfigJson: ewoJImF1dGhzHsKCQkiaG9va3......MiOiAidHJ1ZSIKCX0KfQ # Base64 encoded config.json +``` + :::info To obtain the base64-encoded version of your `config.json` file, use the following command. Replace @@ -75,12 +81,6 @@ cat | base64 | tr -d '\n' ::: -```yaml -global: - imagePullSecret: - dockerConfigJson: ewoJImF1dGhzHsKCQkiaG9va3......MiOiAidHJ1ZSIKCX0KfQ # Base64 encoded config.json -``` - ## MongoDB Palette uses MongoDB Enterprise as its internal database and supports two modes of deployment: diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md index 33b3a886f9b..10e60d4799a 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md @@ -41,27 +41,33 @@ to install Palette, this process does not apply. ``` 2. Issue the following command to start uninstalling the Palette management plane. This will only remove the resources - managed by Helm and the remaining resources will require additional manual intervention. + managed by Helm. The remaining resources will require additional manual intervention. ```shell helm uninstall hubble ``` -3. Issue the following command to remove the namespace and custom resource definitions related to the Palette management - plane. +3. Remove the namespace and custom resource definitions related to the Palette management plane. ```shell - kubectl delete namespace hubble-system || kubectl delete crd spectroclusteractions.jet.cluster.spectrocloud.com + kubectl delete namespace hubble-system + kubectl delete crd spectroclusteractions.jet.cluster.spectrocloud.com ``` -4. Issue the following command to uninstall Cert Manager. Cert Manager does not reply on any Helm hooks and the Helm - uninstall command will uninstall all related resources. +4. Uninstall Cert Manager. ```shell helm uninstall cert-manager + kubectl delete namespace cert-manager ``` -5. (Optional) If you installed Reach, issue the following command to start uninstalling Reach. This will remove all +5. Uninstall the Spectro Management CRDs chart. + + ```shell + helm uninstall spectro-mgmt-crds + ``` + +6. (Reach only) If you installed Reach, issue the following command to start uninstalling Reach. This will remove all resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and will require additional manual intervention to remove. @@ -69,7 +75,7 @@ to install Palette, this process does not apply. helm uninstall reach-system ``` -6. (Optional) Issue the following commands to remove the remaining Reach system resources. +7. (Reach only) Issue the following commands to remove the remaining Reach system resources. ```shell kubectl delete ns reach-system @@ -83,13 +89,13 @@ to install Palette, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -7. (Optional) If you installed Image Swap, issue the following command to remove the `image-swap` chart. +8. (Image Swap only) If you installed Image Swap, issue the following command to remove the `image-swap` chart. ```shell helm uninstall image-swap ``` -8. (Optional) Issue the following commands to remove the remaining resources related to `image-swap`. +9. (Image Swap only) Issue the following commands to remove the remaining resources related to `image-swap`. ```shell kubectl delete ns imageswap-system diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md index 4551f48fffb..907caa3d8fe 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md @@ -77,10 +77,14 @@ has the necessary network connectivity for VerteX to operate successfully. operations will not be FIPS-compliant. - A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the - annotation `storageclass.kubernetes.io/is-default-class` set to `true`. To override the default StorageClass for a - workload, modify the `storageClass` parameter. Check out the - [Change the default StorageClass](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/) - page to learn more about modifying StorageClasses. + annotation `storageclass.kubernetes.io/is-default-class` set to `true`. + + ```shell + kubectl patch storageclass --patch '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' + ``` + + To use another storage class for the Palette VerteX installation, you must set the preferred storage class name in the + `vertex/values.yaml` file using the `mongo.storageClass` parameter. - Palette VerteX uses Traefik as the ingress controller. If you already have an ingress controller deployed in the cluster, set the `ingress.enabled` parameter to `false` in the `values.yaml` file. @@ -97,7 +101,11 @@ has the necessary network connectivity for VerteX to operate successfully. - Access to the VerteX Helm Charts. Refer to the [Access VerteX](../../vertex.md#access-palette-vertex) for instructions on how to request access to the Helm Chart. -
+- An image pull secret from Spectro Cloud customer support, required to pull images from Spectro Cloud OCI registries. + This is not required if you plan to use [mirror registries](../../system-management/registry-override.md) or + [image swaps](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. :::warning @@ -112,38 +120,74 @@ The following instructions are written agnostic to the Kubernetes distribution y underlying infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your environment. Reach out to our support team if you need assistance. -1. Open a terminal session and navigate to the directory where you downloaded the Palette install zip file provided by - our support. Unzip the file to a directory named **vertex-install**. +1. Open a terminal session and navigate to the directory where you downloaded the Palette VerteX install ZIP file + provided by our support team. Unzip the file to a directory named `vertex-install`. ```shell - unzip release-*.zip -d vertex-install + unzip charts.zip -d vertex-install ``` -2. Navigate to the release folder inside the **vertex-install** directory. +2. Navigate to the `vertex-install` directory. + + ```shell + cd vertex-install + ``` + + ### Cert-Manager Helm Chart + +3. Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. ```shell - cd vertex-install/charts/release-* + vim extras/cert-manager/values.yaml + ``` + +4. If you plan to pull images from Spectro Cloud OCI registries, paste the image pull secret received from your + customer support representative into the `imagePullSecret.dockerConfigJson` field. It is not required if you plan to + use mirror registries or image swap. + + Alternately, if you plan to pull images from a private registry that requires authentication, use the base64-encoded + contents of your `config.json` containing the registry credentials. Refer to + [Helm Configuration Reference](./vertex-helm-ref.md#image-pull-secret) for more information. + + :::info + + If you omit the image pull secret during installation, you must provide it through the system console. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. + + ::: + + ```yaml title="Example configuration" hideClipboard {5} + imagePullSecret: + # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. + # Pods automatically reference that pull secret when create is true or the secret already exists (PEM-10596). + create: false + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson ``` -3. Install Cert Manager using the following command. Replace the actual file name of the Cert Manager Helm Chart with - the one you downloaded, as the version number may be different. +5. Install the Cert-Manager Helm chart. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "cert-manager" does not exist. Installing it now. NAME: cert-manager - LAST DEPLOYED: Mon Jan 29 16:32:33 2024 + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -4. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by + ### Spectro Management CRDs Helm Chart + +6. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by Palette VerteX, including Traefik CRDs, and must be installed before the main Palette VerteX Helm chart. When the chart is installed, the custom resource types are registered with the Kubernetes API server; no pods are deployed. @@ -156,53 +200,85 @@ your environment. Reach out to our support team if you need assistance. ```shell hideClipboard title="Example output" Release "spectro-mgmt-crds" does not exist. Installing it now. NAME: spectro-mgmt-crds - LAST DEPLOYED: Mon Jan 29 16:35:00 2024 + LAST DEPLOYED: Wed Jun 17 21:17:39 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -5. Open the **values.yaml** in the **spectro-mgmt-plane** folder with a text editor of your choice. The **values.yaml** - contains the default values for the VerteX installation parameters. However, you must populate the following - parameters before installing VerteX. You can learn more about the parameters in the **values.yaml** file in the - [Helm Configuration Reference](vertex-helm-ref.md) page. + ### VerteX Helm Chart - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `env.rootDomain` | The URL name or IP address you will use for the VerteX installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for VerteX FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reach-system` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure VerteX to use a network proxy in your environment | object | +7. Open the file `vertex/values.yaml` using a text editor of your choice. This example uses Vim. - :::info + ```shell + vim vertex/values.yaml + ``` - If you are installing VerteX by pulling required images from a private mirror registry, you will need to provide the - credentials to your registry in the **values.yaml** file. For more information, refer to - [Helm Configuration Reference](vertex-helm-ref.md#image-pull-secret). +8. The file `vertex/values.yaml` contains the default values for the Palette VerteX installation parameters. You must + populate the following parameters before installing Palette VerteX. For a complete list of fields and additional + information, refer to [Helm Configuration Reference](./vertex-helm-ref.md). + + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from Spectro Cloud OCI registries (without mirror registries or image swap configured) or images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). If you omit the image pull secret during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. | string | + | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette VerteX FIPS packs. These credentials are provided by our support team. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your Palette VerteX installation. | string | + + #### Self-Hosted OCI Registries + + The following parameters are required if you pull Palette VerteX images from a self-hosted OCI registry instead of a + Spectro Cloud OCI registry or AWS ECR. + + :::tip + + If you would prefer to keep your image swap values in a separate location, you can use the following table to + complete the `extras/image-swap/values.yaml` file instead. + + ```shell + tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ + vim extras/image-swap/values.yaml + ``` ::: - Save the **values.yaml** file after you have populated the required parameters mentioned in the table. + | **Parameter** | **Description** | **Type** | + | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](./vertex-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](./vertex-helm-ref.md#oci-image-registry) page for examples. | string | + | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | + | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | + + :::info + + Include `/v2` in your mirror registry endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. + + ::: - Select one of the following tabs to review an example of the **values.yaml** file with the required parameters - highlighted. +9. Save the completed `vertex/values.yaml` file. Expand the following sections to review an example of the + `vertex/values.yaml` file with the required parameters highlighted. - - + - ```yaml {60,84-92} + ```yaml {8,60,84-93} ######################### # Spectro Cloud Palette # ######################### global: imagePullSecret: - create: false # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity # MongoDB Configuration mongo: @@ -224,6 +300,7 @@ your environment. Reach out to our support team if you need assistance. config: installationMode: "connected" #values can be connected or airgap. + isPaletteBaseCluster: false # SSO SAML Configuration (Optional for self-hosted type) sso: @@ -246,14 +323,14 @@ your environment. Reach out to our support team if you need assistance. password: "" # base64 encoded SMTP password env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) # # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.example.com" + rootDomain: "vertex.docs-test.spectrocloud.com" # stableEndpointAccess is used when deploying EKS clusters in Private network type. # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true @@ -278,14 +355,15 @@ your environment. Reach out to our support team if you need assistance. # caCert: "" ociPackEcrRegistry: - endpoint: "15789037893.dkr.ecr.us-east-1.amazonaws.com" # - name: "VerteX Packs OCI" # - accessKey: "**************" # - secretKey: "**************" # + endpoint: "https://415789037893.dkr.ecr.us-west-2.amazonaws.com" # + name: "Palette Packs" # + accessKey: "**********" # + secretKey: "**********" # baseContentPath: "production-fips" # isPrivate: true insecureSkipVerify: false caCert: "" + credentialType: "" # ociImageRegistry: # endpoint: "" # @@ -311,8 +389,8 @@ your environment. Reach out to our support team if you need assistance. # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap-init:v1.5.3-spectro-4.5.1" - imageSwapImage: "us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" + imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" imageSwapConfig: isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false @@ -336,15 +414,28 @@ your environment. Reach out to our support team if you need assistance. serverCrtBase64: "" serverKeyBase64: "" insecureSkipVerify: false - + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" ingress: - # When enabled, the Traefik ingress controller is installed. + # When enabled the Traefik ingress controller would be installed enabled: true + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + ingress: # Default SSL certificate and key for the ingress controller (Optional) # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) certificate: "" key: "" @@ -355,6 +446,7 @@ your environment. Reach out to our support team if you need assistance. # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' # Azure example # service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -371,10 +463,10 @@ your environment. Reach out to our support team if you need assistance. enabled: false frpHostURL: proxy.sample.spectrocloud.com server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity ca: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity service: annotations: {} @@ -398,18 +490,17 @@ your environment. Reach out to our support team if you need assistance. - + - ```yaml {60,75-82,94-102} + ```yaml {4,55,84-93} ######################### # Spectro Cloud Palette # ######################### global: imagePullSecret: - create: false # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity # MongoDB Configuration mongo: @@ -427,10 +518,11 @@ your environment. Reach out to our support team if you need assistance. cpuLimit: "2000m" memoryLimit: "4Gi" pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class + storageClass: "" # leave empty to use the default storage class config: installationMode: "connected" #values can be connected or airgap. + isPaletteBaseCluster: false # SSO SAML Configuration (Optional for self-hosted type) sso: @@ -453,27 +545,27 @@ your environment. Reach out to our support team if you need assistance. password: "" # base64 encoded SMTP password env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) # # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.example.com" + rootDomain: "vertex.docs-test.spectrocloud.com" # stableEndpointAccess is used when deploying EKS clusters in Private network type. # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true cluster: stableEndpointAccess: false - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" + # registry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # insecureSkipVerify: false + # caCert: "" ociPackRegistry: endpoint: "example.harbor.org" # @@ -504,22 +596,22 @@ your environment. Reach out to our support team if you need assistance. caCert: "" mirrorRegistries: "" # See instructions below. - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. + # Instruction for mirrorRegistries. + # ---------------------------------- + # Please provide the registry endpoint for the following registries, separated by double colons (::): + # docker.io + # gcr.io + # ghcr.io + # k8s.gcr.io + # registry.k8s.io + # quay.io + # For each registry, follow this example format: + # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ + # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap-init:v1.5.3-spectro-4.5.1" - imageSwapImage: "us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" + imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" imageSwapConfig: isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false @@ -543,15 +635,28 @@ your environment. Reach out to our support team if you need assistance. serverCrtBase64: "" serverKeyBase64: "" insecureSkipVerify: false - + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" ingress: - # When enabled, the Traefik ingress controller is installed. + # When enabled the Traefik ingress controller would be installed enabled: true + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + ingress: # Default SSL certificate and key for the ingress controller (Optional) # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) certificate: "" key: "" @@ -562,6 +667,7 @@ your environment. Reach out to our support team if you need assistance. # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' # Azure example # service.beta.kubernetes.io/azure-load-balancer-internal: "true" @@ -578,10 +684,10 @@ your environment. Reach out to our support team if you need assistance. enabled: false frpHostURL: proxy.sample.spectrocloud.com server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity ca: - crt : LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity service: annotations: {} @@ -607,71 +713,109 @@ your environment. Reach out to our support team if you need assistance. - :::warning + ### Image Swap Helm Chart - Ensure you have configured the **values.yaml** file with the required parameters before proceeding to the next - steps. +10. (Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap + Helm chart. Image Swap rewrites pod image references to pull from your mirror registry. Palette VerteX ignores the + `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on + whether you added your image swap values to `vertex/values.yaml` or `extras/image-swap/values.yaml`. - ::: + + + + + ```shell + helm upgrade --values vertex/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install + ``` -6. This step is only required if you are installing Palette in an environment where a network proxy must be configured - for Palette to access the internet. If you are not using a network proxy, skip to the next step. + - Install the reach-system chart using the following command. Point to the **values.yaml** file you configured in - step 5. Make sure you configure the `reach-system.enable` section in the **values.yaml** file. + + + ```shell + helm upgrade --values extras/image-swap/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install + ``` + + + + + + ```shell hideClipboard title="Example output" + Release "image-swap" does not exist. Installing it now. + NAME: image-swap + LAST DEPLOYED: Wed Jun 17 14:44:13 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` + + ### Reach System Helm Chart + +11. (Proxy environments only) If you are installing Palette VerteX in an environment where a network proxy must be + configured for VerteX to access the internet, install the Reach System chart using the following command. Ensure you + set `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `vertex/values.yaml`. ```shell helm upgrade --values vertex/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install + reach-system extras/reach-system/reach-system-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "reach-system" does not exist. Installing it now. NAME: reach-system - LAST DEPLOYED: Mon Jan 29 17:04:23 2024 + LAST DEPLOYED: Fri Jan 30 18:40:57 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` - + +
- How to update containerd to use proxy configurations - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. + Update containerd to use proxy configurations - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` + If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy + settings. You can do this by updating the containerd configuration file on each node in the cluster. The + configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an + example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for + guidance. + + ``` + [Service] + Environment="HTTP_PROXY=http://example.com:9090" + Environment="HTTPS_PROXY=http://example.com:9090" + Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" + ```
-7. Install the VerteX Helm Chart using the following command. + + + ### Installation + +12. Install the VerteX Helm Chart using the following command. ```shell - helm upgrade --values vertex/values.yaml \ - hubble vertex/spectro-mgmt-plane-*.tgz --install + helm upgrade --values vertex/values.yaml \ + hubble vertex/spectro-mgmt-plane-*.tgz --install ``` - ```shell hideClipboard + ```shell hideClipboard title="Example output" Release "hubble" does not exist. Installing it now. NAME: hubble - LAST DEPLOYED: Mon Jan 29 17:07:51 2024 + LAST DEPLOYED: Wed Jun 17 21:41:31 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -8. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces +13. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The installation takes between two to three minutes to complete. @@ -688,9 +832,9 @@ your environment. Reach out to our support team if you need assistance. ::: -9. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the - following command to retrieve the load balancer IP address. You may require the assistance of your network - administrator to create the DNS record. +14. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the + following command to retrieve the load balancer IP address. If you need assistance creating the DNS record, consult + with your network administrator. ```shell kubectl get service traefik-ingress-controller --namespace ingress-traefik \ @@ -708,7 +852,7 @@ your environment. Reach out to our support team if you need assistance. ::: -10. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the +15. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the system console, open a web browser and paste the custom domain URL in the address bar and append the value `/system`. Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system @@ -720,7 +864,7 @@ your environment. Reach out to our support team if you need assistance. ![Screenshot of the VerteX system console showing Username and Password fields.](/vertex_install-on-kubernetes_install_system-console.webp) -11. Log in to the system console using the following default credentials. Refer to the +16. Log in to the system console using the following default credentials. Refer to the [password requirements](../../system-management/account-management/credentials.md#password-requirements-and-security) documentation page to learn more about password requirements. @@ -729,13 +873,13 @@ your environment. Reach out to our support team if you need assistance. | Username | `admin` | | Password | `admin` | - After login, you will be prompted to create a new password. Enter a new password and save your changes. You will be - redirected to the VerteX system console. Use the username `admin` and your new password to log in to the system - console. You can create additional system administrator accounts and assign roles to users in the system console. - Refer to the [Account Management](../../system-management/account-management/account-management.md) documentation - page for more information. + After logging in, you must create a new password. Once you create your password, you are redirected to the VerteX + system console. Use the username `admin` and your new password to log in to the system console. You can create + additional system administrator accounts and assign roles to users in the system console. Refer to the + [Account Management](../../system-management/account-management/account-management.md) documentation page for more + information. -12. After login, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a +17. After logging in, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority files to VerteX. You can upload the files using the VerteX system console. Refer to the [Configure HTTPS Encryption](../../system-management/ssl-certificate-management.md) page for instructions on how to @@ -749,72 +893,121 @@ your environment. Reach out to our support team if you need assistance. ::: -You now have a self-hosted instance of VerteX installed in a Kubernetes cluster. Make sure you retain the -**values.yaml** file as you may need it for future upgrades. +You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the `values.yaml` +file, as you can refer to it for future upgrades. ## Validate -Use the following steps to validate the VerteX installation. +Use the following steps to validate your Palette VerteX installation. -1. To access the VerteX system console, open a web browser and paste the `env.rootDomain` value you provided in the - address bar and append the value `/system`. You can also use the IP address of the load balancer. + -2. Log in using the credentials you received from our support team. After login, you will be prompted to create a new - password. Enter a new password and save your changes. You will be redirected to the VerteX system console. + -3. Open a terminal session and issue the following command to verify the VerteX installation. The command should return - a list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` - namespaces. +1. Open up a web browser and navigate to the Palette VerteX system console. To access the system console, open a web + browser and paste the `env.rootDomain` value you provided in the address bar and append the value `/system`. You can + also use the IP address of the load balancer. + +2. Log in using the default credentials. After logging in, you are prompted to create a new password. Enter a new + password and save your changes. You are redirected to the Palette VerteX system console. + + + + + +1. Open a terminal session with access to the cluster you installed Palette VerteX on. + +2. Verify all pods in all namespaces are running. ```shell - kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ - | grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' + kubectl get pods --all-namespaces ``` - Your output should look similar to the following. - - ```shell hideClipboard - cp-system spectro-cp-ui-689984f88d-54wsw Running - hubble-system auth-85b748cbf4-6drkn Running - hubble-system auth-85b748cbf4-dwhw2 Running - hubble-system cloud-fb74b8558-lqjq5 Running - hubble-system cloud-fb74b8558-zkfp5 Running - hubble-system configserver-685fcc5b6d-t8f8h Running - hubble-system event-68568f54c7-jzx5t Running - hubble-system event-68568f54c7-w9rnh Running - hubble-system foreq-6b689f54fb-vxjts Running - hubble-system hashboard-897bc9884-pxpvn Running - hubble-system hashboard-897bc9884-rmn69 Running - hubble-system hutil-6d7c478c96-td8q4 Running - hubble-system hutil-6d7c478c96-zjhk4 Running - hubble-system mgmt-85dbf6bf9c-jbggc Running - hubble-system mongo-0 Running - hubble-system mongo-1 Running - hubble-system mongo-2 Running - hubble-system msgbroker-6c9b9fbf8b-mcsn5 Running - hubble-system oci-proxy-7789cf9bd8-qcjkl Running - hubble-system packsync-28205220-bmzcg Succeeded - hubble-system spectrocluster-6c57f5775d-dcm2q Running - hubble-system spectrocluster-6c57f5775d-gmdt2 Running - hubble-system spectrocluster-6c57f5775d-sxks5 Running - hubble-system system-686d77b947-8949z Running - hubble-system system-686d77b947-cgzx6 Running - hubble-system timeseries-7865bc9c56-5q87l Running - hubble-system timeseries-7865bc9c56-scncb Running - hubble-system timeseries-7865bc9c56-sxmgb Running - hubble-system user-5c9f6c6f4b-9dgqz Running - hubble-system user-5c9f6c6f4b-hxkj6 Running - ingress-traefik traefik-ingress-controller-9dmzq Running - ingress-traefik traefik-ingress-controller-tpwtf Running - ingress-traefik traefik-ingress-controller-xz4jf Running - jet-system jet-6599b9856d-t9mr4 Running - ui-system spectro-ui-76ffdf67fb-rkgx8 Running + ```shell hideClipboard title="Example output" + NAMESPACE NAME READY STATUS RESTARTS AGE + cert-manager cert-manager-5fb779d887-mz2vb 1/1 Running 0 8m46s + cert-manager cert-manager-cainjector-764f9646d4-7nhpq 1/1 Running 0 8m46s + cert-manager cert-manager-webhook-85b8dbdddd-fkn6z 1/1 Running 0 8m46s + cp-system spectro-cp-ui-5dffbcdc78-gk8st 1/1 Running 0 7m14s + hubble-system auth-7f4c7ff9c-2clwp 1/1 Running 0 6m8s + hubble-system auth-7f4c7ff9c-j84bt 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-9r8bp 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-pvcv4 1/1 Running 0 6m8s + hubble-system configserver-5bc8f9fdcb-mbt66 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-bmzdk 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-cxc58 1/1 Running 0 6m7s + hubble-system event-5fbf6b7f44-zhr9h 1/1 Running 0 6m7s + hubble-system foreq-8487bf9bbf-847vj 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-k48wn 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-pddx7 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-5mhjp 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-jwzr5 1/1 Running 0 6m7s + hubble-system memstore-7d59d65f67-j8lls 1/1 Running 0 6m6s + hubble-system mgmt-54fb5f487d-dj2tz 1/1 Running 0 7m14s + hubble-system mongo-0 2/2 Running 0 6m33s + hubble-system mongo-1 2/2 Running 0 5m47s + hubble-system mongo-2 2/2 Running 0 4m57s + hubble-system mongodb-key-manager-helm-k6294 0/1 Completed 0 7m15s + hubble-system msgbroker-0 1/1 Running 0 7m15s + hubble-system msgbroker-1 1/1 Running 0 6m43s + hubble-system oci-proxy-78cd749dc9-jfs86 1/1 Running 0 6m6s + hubble-system reloader-reloader-55d78d877b-7tnkq 1/1 Running 0 6m6s + hubble-system specman-0 1/1 Running 0 6m2s + hubble-system spectro-tunnel-74d559dd65-hlwch 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-knrfq 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-pb6pr 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-xcvk9 1/1 Running 0 6m5s + hubble-system spectrocluster-jobs-7dc76bf6c7-pjc7l 1/1 Running 0 6m5s + hubble-system spectrocluster-reconciler-dcfd55ff5-gnfjg 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-grznt 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-jj9m6 1/1 Running 0 6m4s + hubble-system spectrossh-589d975d4d-82vm2 1/1 Running 0 6m4s + hubble-system system-d48fdbc9-ffzq9 1/1 Running 0 6m8s + hubble-system system-d48fdbc9-sztrr 1/1 Running 0 6m8s + hubble-system timeseries-f465b4c99-8h8c7 1/1 Running 0 6m4s + hubble-system timeseries-f465b4c99-jlzlj 1/1 Running 0 6m3s + hubble-system timeseries-f465b4c99-z27d8 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-fgwtp 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-wcqxk 1/1 Running 0 6m3s + ingress-traefik traefik-ingress-controller-5dctd 1/1 Running 0 7m15s + ingress-traefik traefik-ingress-controller-tx6st 1/1 Running 0 7m16s + ingress-traefik traefik-ingress-controller-zf25w 1/1 Running 0 7m16s + jet-system jet-796fc87c5d-vpvtz 1/1 Running 0 4m1s + kube-system aws-node-8xqnx 2/2 Running 0 121m + kube-system aws-node-gtr64 2/2 Running 0 121m + kube-system aws-node-h7pdv 2/2 Running 0 121m + kube-system coredns-566b9b9d-hck47 1/1 Running 0 129m + kube-system coredns-566b9b9d-jpnrs 1/1 Running 0 129m + kube-system ebs-csi-controller-7dfbb6bd58-nwcjl 6/6 Running 0 113m + kube-system ebs-csi-controller-7dfbb6bd58-w8kxz 6/6 Running 0 113m + kube-system ebs-csi-node-9r6fk 3/3 Running 0 113m + kube-system ebs-csi-node-vp744 3/3 Running 0 113m + kube-system ebs-csi-node-xb69v 3/3 Running 0 113m + kube-system kube-proxy-59qgr 1/1 Running 0 121m + kube-system kube-proxy-krrzd 1/1 Running 0 121m + kube-system kube-proxy-lbsgp 1/1 Running 0 121m + ui-system spectro-ui-56749c5f84-98m89 1/1 Running 0 7m15s ``` -## Next Steps +3. Verify the `hubble` release is deployed. - + ```shell + helm status hubble + ``` + + ```shell title="Example output" hideClipboard + NAME: hubble + LAST DEPLOYED: Thu Jun 18 18:33:18 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` -## Resources + + + + +## Next Steps -- [Enterprise Install Troubleshooting](../../../troubleshooting/enterprise-install.md) + diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md index 1b3d2df8270..36cf07e4459 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md @@ -37,36 +37,51 @@ The global block allows you to provide configurations that apply globally to the ### Image Pull Secret -This section is only relevant if you are using your own private registry to host the images required for the Palette -installation process. +:::warning -The `imagePullSecret` block allows you to provide image pull secrets that will be used to authenticate with private -registries to obtain the images required for Palette VerteX installation. +Spectro Cloud's image pull secret will be required in an upcoming release for any users pulling images from a Spectro +Cloud-owned registry. This is a breaking change. We recommend obtaining your secret as soon as possible to avoid service +disruptions. Refer to +[Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) +for more information. -| **Parameters** | **Description** | **Type** | **Default value** | -| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | -| `create` | Specifies whether to create a secret containing credentials to your own private image registry. | Boolean | `false` | -| `dockerConfigJson` | The **config.json** file value containing the registry URL and credentials for your image registry in base64 encoded format on a single line. For more information about the **config.json** file, refer to [Kubernetes Documentation](https://kubernetes.io/docs/concepts/containers/images/#config-json). | String | None | +::: -:::info +The `imagePullSecret` block configures the image pull secret used to authenticate with private registries. Palette +VerteX always creates a Kubernetes Secret named `spectro-image-pull-secret` from this value and distributes it to the +management plane, workload clusters, and PCGs. The secret serves the following purposes: -To obtain the base-64 encoded version of the credential `config.json` file, you can issue the following command. Replace -`` with the path to your `config.json` file. The `tr -d '\n'` removes new line characters -and produce the output on a single line. +- **Spectro Cloud registry authentication** - Authenticates with Spectro Cloud's registries to pull security-hardened + images. These images are used by the management plane, workload clusters, and PCGs. To obtain this secret, contact + your Spectro Cloud customer support representative. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. -```shell -cat | base64 | tr -d '\n' -``` +- **Private registry authentication** - If you host Palette images in your own private registry, the secret provides the + credentials needed to pull those images. -::: +| **Parameters** | **Description** | **Type** | **Default value** | +| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------- | +| `dockerConfigJson` | The values of the `config.json` file encoded in base64 as a single string, containing the registry URL and credentials for your image registry. For more information about the `config.json` file, refer to the [Kubernetes Documentation](https://kubernetes.io/docs/concepts/containers/images/#config-json). | String | `""` | ```yaml global: imagePullSecret: - create: true dockerConfigJson: ewoJImF1dGhzHsKCQkiaG9va3......MiOiAidHJ1ZSIKCX0KfQ # Base64 encoded config.json ``` +:::info + +To obtain the base64-encoded version of your `config.json` file, use the following command. Replace +`` with the path to your `config.json` file. The `tr -d '\n'` removes new line characters +and produces the output on a single line. + +```shell +cat | base64 | tr -d '\n' +``` + +::: + ## MongoDB Palette VerteX uses MongoDB Enterprise as its internal database and supports two modes of deployment: diff --git a/static/assets/docs/images/configure-image-pull-secret_palette.webp b/static/assets/docs/images/configure-image-pull-secret_palette.webp new file mode 100644 index 0000000000000000000000000000000000000000..06547d00cf91cd83fdb6f0ad95e4b4dc1d41f70f GIT binary patch literal 48160 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

y>5*SgkqK_oga_H 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 Date: Mon, 22 Jun 2026 17:18:17 -0400 Subject: [PATCH 05/22] Adjustments to announcements; begin partial conversion sync across helm guides --- .../_kubernetes-install-cluster-prereqs.mdx | 62 ++++ .../configure-image-pull-secret.md | 9 +- .../install-on-kubernetes/install.md | 343 ++++++++++++------ .../release-notes/announcements.md | 8 +- .../install-on-kubernetes/install.md | 114 ++---- 5 files changed, 338 insertions(+), 198 deletions(-) create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx new file mode 100644 index 00000000000..2c477cb47a3 --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx @@ -0,0 +1,62 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-cluster-prereqs +--- + +- We recommend the following resources for {props.version}. Refer to our + for additional sizing information. + + - A minimum of three AMD64 (x86_64) nodes. These can be worker nodes or three untainted control plane nodes. ARM-based + nodes are not supported. + + - 8 CPUs per node + + - 16 GB of memory per node + + - 110 GB of disk space per node + +- The following network ports must be accessible: + + - **TCP/443** - Inbound and outbound to and from the {props.version} management cluster + + - **TCP/6443** - Outbound traffic from the {props.version} management cluster to the deployed cluster's Kubernetes API server. + +- The following SSL certificate files for the domain name you will assign to {props.version}. You must enable HTTPS + encryption for {props.version}. Reach out to your network administrator or security team to obtain these files: + + - x509 SSL certificate file in base64 format + + - x509 SSL certificate key file in base64 format + + - x509 SSL certificate authority file in base64 format + +- The Kubernetes cluster must use a Kubernetes version compatible with your {props.version}version. Refer to + to locate the required Kubernetes version. + +- Ensure the Kubernetes cluster _does_ not have Cert Manager installed. {props.version} requires a unique Cert Manager + configuration to be installed as part of the installation process. If Cert Manager is already installed, you must + uninstall it before installing {props.version}. + +- A Container Storage Interface (CSI) to create persistent volumes, which are used to store + persistent data. You may install any CSI that is compatible with your Kubernetes cluster. + +- A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the + annotation `storageclass.kubernetes.io/is-default-class` set to `true`. You can set a default storage class in your Kubernetes cluster using the + following `kubectl` command. + + ```shell + kubectl patch storageclass --patch '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' + ``` + + To use a non-default storage class for the {props.version} installation, you must set the preferred storage class name + in the {props.helm}/values.yaml file using the `mongo.storageClass` parameter. diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md index 67b88833c79..48c86c9f619 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -78,9 +78,13 @@ self-hosted Palette. You can add your image pull secret when installing self-hosted Palette and Palette VerteX using Helm charts or the Palette CLI. +:::info + Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the secret [post-installation](#configure-image-pull-secret-post-installation) using the system console. +::: + #### Helm Chart Installations For self-hosted Palette or Palette VerteX environments installed on an existing Kubernetes cluster using Helm charts, @@ -97,10 +101,7 @@ For the full installation process, refer to the appropriate #### Palette CLI Installations -[AWAITING INSTRUCTIONS FROM ZULFI] - -Configuring an image pull secret when installing self-hosted Palette using the Palette Management Appliance or Palette -CLI is not supported. +[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI; VISH FOR PCG] ### Post-Installation diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md index 3cedd67c41a..0bc92cdb708 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md @@ -116,11 +116,46 @@ your environment. Reach out to our support team if you need assistance. cd palette-install ``` -3. Install Cert-Manager using the following command. + ### Cert-Manager Helm Chart + +3. Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. + + ```shell + vim extras/cert-manager/values.yaml + ``` + +4. If you plan to pull images from Spectro Cloud OCI registries, paste the image pull secret received from your + customer support representative into the `imagePullSecret.dockerConfigJson` field. It is not required if you plan to + use mirror registries or image swap. + + Alternately, if you plan to pull images from a private registry that requires authentication, use the base64-encoded + contents of your `config.json` containing the registry credentials. Refer to + [Helm Configuration Reference](./palette-helm-ref.md#image-pull-secret) for more information. + + :::info + + If you omit the image pull secret during installation, you must provide it through the system console. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. + + ::: + + ```yaml title="Example configuration" hideClipboard {5} + imagePullSecret: + # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. + # Pods automatically reference that pull secret when create is true or the secret already exists (PEM-10596). + create: false + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson + ``` + +5. Install the Cert-Manager Helm chart. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` ```shell hideClipboard title="Example output" @@ -133,53 +168,72 @@ your environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` -4. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by - Palette, including Traefik CRDs, and must be installed _before_ the main Palette Helm chart. When the chart is + ### Spectro Management CRDs Helm Chart + +6. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by + Palette, including Traefik CRDs, and must be installed before the main Palette Helm chart. When the chart is installed, the custom resource types are registered with the Kubernetes API server; no pods are deployed. ```shell - helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz + helm upgrade --install spectro-mgmt-crds \ + extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ + --values extras/spectro-mgmt-crds/values.yaml ``` ```shell hideClipboard title="Example output" Release "spectro-mgmt-crds" does not exist. Installing it now. NAME: spectro-mgmt-crds - LAST DEPLOYED: Wed Jun 17 12:55:23 2026 + LAST DEPLOYED: Wed Jun 17 21:17:39 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -5. Open the file `palette/values.yaml` using a text editor of your choice. This example uses Vim. + ### Palette Helm Chart + +7. Open the file `palette/values.yaml` using a text editor of your choice. This example uses Vim. ```shell vim palette/values.yaml ``` -6. The file `palette/values.yaml` contains the default values for the Palette installation parameters. You must +8. The file `palette/values.yaml` contains the default values for the Palette installation parameters. You must populate the following parameters before installing Palette. For a complete list of fields and additional - information, refer to [Helm Configuration Reference](palette-helm-ref.md). + information, refer to [Helm Configuration Reference](./palette-helm-ref.md). - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | - | `global.imagePullSecret.dockerConfigJson` | The image pull secret provided by your Spectro Cloud customer support representative. This secret is required if you plan to pull images hosted in a Spectro Cloud-owned registry. If you omit this during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information.

Alternately, if you plan to pull images from your own private registry, use the base64-encoded contents of your `config.json` containing the registry credentials. Refer to [Helm Configuration Reference](palette-helm-ref.md#image-pull-secret) for more information. | string | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from Spectro Cloud OCI registries (without mirror registries or image swap configured) or images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). If you omit the image pull secret during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. | string | + | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your Palette installation. | string | - ### Self-Hosted OCI Registries + #### Self-Hosted OCI Registries The following parameters are required if you pull Palette images from a self-hosted OCI registry instead of a - Spectro Cloud-owned registry or AWS ECR. + Spectro Cloud OCI registry or AWS ECR. + + :::tip + + If you would prefer to keep your image swap values in a separate location, you can use the following table to + complete the `extras/image-swap/values.yaml` file instead. + + ```shell + tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ + vim extras/image-swap/values.yaml + ``` + + ::: - | **Parameter** | **Description** | **Type** | - | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](palette-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](palette-helm-ref.md#oci-image-registry) page for examples. | string | - | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | - | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | + | **Parameter** | **Description** | **Type** | + | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](./palette-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](./palette-helm-ref.md#oci-image-registry) page for examples. | string | + | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | + | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | :::info @@ -192,7 +246,7 @@ your environment. Reach out to our support team if you need assistance. ::: -7. Save the completed `palette/values.yaml` file. Expand the following sections to review an example of the +9. Save the completed `palette/values.yaml` file. Expand the following sections to review an example of the `palette/values.yaml` file with the required parameters highlighted. @@ -627,15 +681,35 @@ your environment. Reach out to our support team if you need assistance. -8. (Self-hosted OCI registry only) If you configured the [Self-Hosted OCI Registry](#self-hosted-oci-registries) - values, install the Image Swap Helm chart. Image Swap rewrites pod image references to pull from your mirror - registry. Palette ignores the `mirrorRegistries` configuration unless the Image Swap chart is installed. + ### Image Swap Helm Chart + +10. (Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap + Helm chart. Image Swap rewrites pod image references to pull from your mirror registry. Palette ignores the + `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on + whether you added your image swap values to `palette/values.yaml` or `extras/image-swap/values.yaml`. + + + + ```shell helm upgrade --values palette/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install + image-swap extras/image-swap/image-swap-*.tgz --install + ``` + + + + + + ```shell + helm upgrade --values extras/image-swap/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install ``` + + + + ```shell hideClipboard title="Example output" Release "image-swap" does not exist. Installing it now. NAME: image-swap @@ -646,13 +720,15 @@ your environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` -9. (Proxy environments only) If you are installing Palette in an environment where a network proxy must be configured - for Palette to access the internet, install the reach-system chart using the following command. Ensure you set - `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `palette/values.yaml`. + ### Reach System Helm Chart + +11. (Proxy environments only) If you are installing Palette VerteX in an environment where a network proxy must be + configured for VerteX to access the internet, install the Reach System chart using the following command. Ensure you + set `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `vertex/values.yaml`. ```shell - helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install + helm upgrade --values vertex/values.yaml \ + reach-system extras/reach-system/reach-system-*.tgz --install ``` ```shell hideClipboard title="Example output" @@ -665,43 +741,49 @@ your environment. Reach out to our support team if you need assistance. TEST SUITE: None ``` - + +

- Update containerd to use proxy configurations - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. + Update containerd to use proxy configurations - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` + If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy + settings. You can do this by updating the containerd configuration file on each node in the cluster. The + configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an + example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for + guidance. + + ``` + [Service] + Environment="HTTP_PROXY=http://example.com:9090" + Environment="HTTPS_PROXY=http://example.com:9090" + Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" + ```
-10. Install the Palette Helm chart using the following command. + + + ### Installation + +12. Install the Palette Helm Chart using the following command. ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-*.tgz --install + helm upgrade --values palette/values.yaml \ + hubble palette/spectro-mgmt-plane-*.tgz --install ``` ```shell hideClipboard title="Example output" Release "hubble" does not exist. Installing it now. NAME: hubble - LAST DEPLOYED: Wed Jun 17 13:32:33 2026 + LAST DEPLOYED: Wed Jun 17 21:41:31 2026 NAMESPACE: default STATUS: deployed REVISION: 1 TEST SUITE: None ``` -11. Track the installation process using the command below. Palette is ready when the deployments in the namespaces +13. Track the installation process using the command below. Palette is ready when the deployments in the namespaces `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The installation takes between two to three minutes to complete. @@ -718,7 +800,7 @@ your environment. Reach out to our support team if you need assistance. ::: -12. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the +14. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the following command to retrieve the load balancer IP address. You may require the assistance of your network administrator to create the DNS record. @@ -738,7 +820,7 @@ your environment. Reach out to our support team if you need assistance. ::: -13. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. Open a web +15. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. Open a web browser and paste the custom domain URL in the address bar and append the value `/system`. Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system console. @@ -749,7 +831,7 @@ your environment. Reach out to our support team if you need assistance. ![Screenshot of the Palette system console showing Username and Password fields.](/palette_installation_install-on-vmware_palette-system-console.webp) -14. Log in to the system console using the default credentials. Refer to the +16. Log in to the system console using the default credentials. Refer to the [password requirements](../../system-management/account-management/credentials.md#password-requirements-and-security) documentation page to learn more about password requirements @@ -764,7 +846,7 @@ your environment. Reach out to our support team if you need assistance. Refer to the [Account Management](../../system-management/account-management/account-management.md) documentation page for more information. -15. After logging in, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a +17. After logging in, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority files to Palette. You can upload the files using the Palette system console. Refer to the [Configure HTTPS Encryption](../../system-management/ssl-certificate-management.md) page for instructions on how to @@ -783,7 +865,7 @@ file, as you can refer to it for future upgrades. ## Validate -Use the following steps to validate the Palette installation. +Use the following steps to validate your Palette installation. @@ -800,63 +882,94 @@ Use the following steps to validate the Palette installation. -Open a terminal session and issue the following command to verify the Palette installation. The command should return a -list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` namespaces. - -```shell -kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ -| grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' -``` - -Your output should look similar to the following. - -```shell hideClipboard - cp-system spectro-cp-ui-78c9b7dcc5-q8ln4 Running - hubble-system auth-58bc56bc79-68lbg Running - hubble-system auth-58bc56bc79-r2md8 Running - hubble-system cloud-8475845cff-dnq27 Running - hubble-system cloud-8475845cff-v2cww Running - hubble-system configserver-74dd648bf5-6tvmv Running - hubble-system event-68cfb57f6d-9dx5b Running - hubble-system event-68cfb57f6d-g5zrl Running - hubble-system event-68cfb57f6d-rz4sz Running - hubble-system foreq-6c75b84554-x4f7h Running - hubble-system hashboard-7b69cc685f-d8mmw Running - hubble-system hashboard-7b69cc685f-mbb57 Running - hubble-system hutil-5456dfbdd7-68p4m Running - hubble-system hutil-5456dfbdd7-dllfj Running - hubble-system memstore-8654b49cfd-npqbv Running - hubble-system mgmt-55985b7ccb-gpvnr Running - hubble-system mongo-0 Running - hubble-system mongo-1 Running - hubble-system mongo-2 Pending - hubble-system mongodb-key-manager-helm-4z2mw Running - hubble-system msgbroker-0 Running - hubble-system msgbroker-1 Running - hubble-system oci-proxy-787fd499d4-f772t Running - hubble-system specman-0 Running - hubble-system spectro-tunnel-69448888-qn7kk Running - hubble-system spectrocluster-54fb864b48-8fhkr Running - hubble-system spectrocluster-54fb864b48-9hkgg Running - hubble-system spectrocluster-54fb864b48-w5dwr Running - hubble-system spectrocluster-jobs-6ddfbddcd6-j9xb8 Running - hubble-system spectrocluster-reconciler-d448fc8cf-qr6bp Running - hubble-system spectroclusterop-89968785d-6n48l Running - hubble-system spectroclusterop-89968785d-gzd5w Running - hubble-system spectrossh-d5fd6b49-wfcgc Running - hubble-system system-6f7767845d-lm5zn Running - hubble-system system-6f7767845d-xf2hl Running - hubble-system timeseries-6f5bf98c5c-fcqnh Running - hubble-system timeseries-6f5bf98c5c-vmb5h Running - hubble-system timeseries-6f5bf98c5c-xm8s6 Running - hubble-system user-796c877b57-6rcdp Running - hubble-system user-796c877b57-ptbg4 Running - ingress-traefik traefik-ingress-controller-9dmzq Running - ingress-traefik traefik-ingress-controller-tpwtf Running - ingress-traefik traefik-ingress-controller-xz4jf Running - jet-system jet-555cdf78f5-4l2s2 Running - ui-system spectro-ui-8658f85c85-9lkhs Running -``` +1. Open a terminal session with access to the cluster you installed Palette on. + +2. Verify all pods in all namespaces are running. + + ```shell + kubectl get pods --all-namespaces + ``` + + ```shell hideClipboard title="Example output" + NAMESPACE NAME READY STATUS RESTARTS AGE + cert-manager cert-manager-5fb779d887-mz2vb 1/1 Running 0 8m46s + cert-manager cert-manager-cainjector-764f9646d4-7nhpq 1/1 Running 0 8m46s + cert-manager cert-manager-webhook-85b8dbdddd-fkn6z 1/1 Running 0 8m46s + cp-system spectro-cp-ui-5dffbcdc78-gk8st 1/1 Running 0 7m14s + hubble-system auth-7f4c7ff9c-2clwp 1/1 Running 0 6m8s + hubble-system auth-7f4c7ff9c-j84bt 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-9r8bp 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-pvcv4 1/1 Running 0 6m8s + hubble-system configserver-5bc8f9fdcb-mbt66 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-bmzdk 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-cxc58 1/1 Running 0 6m7s + hubble-system event-5fbf6b7f44-zhr9h 1/1 Running 0 6m7s + hubble-system foreq-8487bf9bbf-847vj 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-k48wn 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-pddx7 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-5mhjp 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-jwzr5 1/1 Running 0 6m7s + hubble-system memstore-7d59d65f67-j8lls 1/1 Running 0 6m6s + hubble-system mgmt-54fb5f487d-dj2tz 1/1 Running 0 7m14s + hubble-system mongo-0 2/2 Running 0 6m33s + hubble-system mongo-1 2/2 Running 0 5m47s + hubble-system mongo-2 2/2 Running 0 4m57s + hubble-system mongodb-key-manager-helm-k6294 0/1 Completed 0 7m15s + hubble-system msgbroker-0 1/1 Running 0 7m15s + hubble-system msgbroker-1 1/1 Running 0 6m43s + hubble-system oci-proxy-78cd749dc9-jfs86 1/1 Running 0 6m6s + hubble-system reloader-reloader-55d78d877b-7tnkq 1/1 Running 0 6m6s + hubble-system specman-0 1/1 Running 0 6m2s + hubble-system spectro-tunnel-74d559dd65-hlwch 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-knrfq 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-pb6pr 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-xcvk9 1/1 Running 0 6m5s + hubble-system spectrocluster-jobs-7dc76bf6c7-pjc7l 1/1 Running 0 6m5s + hubble-system spectrocluster-reconciler-dcfd55ff5-gnfjg 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-grznt 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-jj9m6 1/1 Running 0 6m4s + hubble-system spectrossh-589d975d4d-82vm2 1/1 Running 0 6m4s + hubble-system system-d48fdbc9-ffzq9 1/1 Running 0 6m8s + hubble-system system-d48fdbc9-sztrr 1/1 Running 0 6m8s + hubble-system timeseries-f465b4c99-8h8c7 1/1 Running 0 6m4s + hubble-system timeseries-f465b4c99-jlzlj 1/1 Running 0 6m3s + hubble-system timeseries-f465b4c99-z27d8 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-fgwtp 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-wcqxk 1/1 Running 0 6m3s + ingress-traefik traefik-ingress-controller-5dctd 1/1 Running 0 7m15s + ingress-traefik traefik-ingress-controller-tx6st 1/1 Running 0 7m16s + ingress-traefik traefik-ingress-controller-zf25w 1/1 Running 0 7m16s + jet-system jet-796fc87c5d-vpvtz 1/1 Running 0 4m1s + kube-system aws-node-8xqnx 2/2 Running 0 121m + kube-system aws-node-gtr64 2/2 Running 0 121m + kube-system aws-node-h7pdv 2/2 Running 0 121m + kube-system coredns-566b9b9d-hck47 1/1 Running 0 129m + kube-system coredns-566b9b9d-jpnrs 1/1 Running 0 129m + kube-system ebs-csi-controller-7dfbb6bd58-nwcjl 6/6 Running 0 113m + kube-system ebs-csi-controller-7dfbb6bd58-w8kxz 6/6 Running 0 113m + kube-system ebs-csi-node-9r6fk 3/3 Running 0 113m + kube-system ebs-csi-node-vp744 3/3 Running 0 113m + kube-system ebs-csi-node-xb69v 3/3 Running 0 113m + kube-system kube-proxy-59qgr 1/1 Running 0 121m + kube-system kube-proxy-krrzd 1/1 Running 0 121m + kube-system kube-proxy-lbsgp 1/1 Running 0 121m + ui-system spectro-ui-56749c5f84-98m89 1/1 Running 0 7m15s + ``` + +3. Verify the `hubble` release is deployed. + + ```shell + helm status hubble + ``` + + ```shell title="Example output" hideClipboard + NAME: hubble + LAST DEPLOYED: Thu Jun 18 18:33:18 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` diff --git a/docs/docs-content/release-notes/announcements.md b/docs/docs-content/release-notes/announcements.md index b2ce41a3dfb..cb453e8804e 100644 --- a/docs/docs-content/release-notes/announcements.md +++ b/docs/docs-content/release-notes/announcements.md @@ -24,10 +24,10 @@ Use the [Find Breaking Changes](breaking-changes.md) page to list all the breaki Stay informed about the upcoming breaking changes in Palette and Palette VerteX. Use the information below to prepare for the changes in your environment. -| Change | Target Date | Published Date | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------- | -| Spectro Cloud is transitioning to the exclusive use of security-hardened images. As a result, retrieving images from Spectro Cloud-owned registries will now require a Spectro Cloud image pull secret. This secret is intended for long-term use and is configured in the system console once as part of the initial setup process. Image pulls from Spectro Cloud-owned repositories will not be allowed unless a valid image pull secret is configured.

This change primarily affects connected self-hosted environments that do not configure mirror registries or image swap; it does not apply to airgapped environments, which pull images from their own registries. Authentication is automatically handled for SaaS environments and Artifact Studio downloads. To obtain your image pull secret, contact your customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for more information. | August 23, 2026 | June 28, 2026 | -| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | +| Change | Target Date | Published Date | +| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------- | +| Spectro Cloud is transitioning to the use of security-hardened images. As a result, retrieving images from Spectro Cloud OCI registries will now require a Spectro Cloud image pull secret. TThis secret is intended for long-term use and is configured once. Image pulls from Spectro Cloud registries will not be allowed unless a valid image pull secret is configured.

This change primarily affects non-airgap environments that do not configure mirror registries or image swap; it does not apply to airgapped environments, which pull images from their own registries. To obtain your image pull secret, contact your Spectro Cloud customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for more information. | _To be announced_ | June 28, 2026 | +| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md index 907caa3d8fe..07a37d2b592 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md @@ -18,85 +18,38 @@ has the necessary network connectivity for VerteX to operate successfully. ## Prerequisites -- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed and available. - -- [Helm](https://helm.sh/docs/intro/install/) is installed and available. - -- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using - `kubectl` commands and have sufficient permissions to install VerteX. We recommend using a role with cluster-admin - permissions to install VerteX. - -- Ensure `unzip` or a similar extraction utility is installed on your system. - -- The Kubernetes cluster must be set up on a version of Kubernetes that is compatible to your upgraded version. Refer to - the [Kubernetes Requirements](../install-palette-vertex.md#kubernetes-requirements) section to find the version - required for your Palette installation. - -- Ensure the Kubernetes cluster does not have Cert Manager installed. VerteX requires a unique Cert Manager - configuration to be installed as part of the installation process. If Cert Manager is already installed, you must - uninstall it before installing VerteX. - -- Palette requires a Container Storage Interface (CSI) to create Persistent Volumes, which are used to store persistent - data. You may install any CSI that is compatible with your Kubernetes cluster. - -- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named - `hubble` with the permission `readWriteAnyDatabase`. Refer to the - [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a - database user in Atlas. - -- We recommend the following resources for VerteX. Refer to the - [VerteX size guidelines](../install-palette-vertex.md#size-guidelines) for additional sizing information. - - - 8 CPUs per node. - - - 16 GB Memory per node. - - - 110 GB Disk Space per node. - - - A minimum of three worker nodes or three untainted control plane nodes. - - - AMD64 (also known as x86_64) architecture. ARM-based nodes are not supported. - -- The following network ports must be accessible for VerteX to operate successfully. - - - TCP/443: Inbound and outbound to and from the VerteX management cluster. - - - TCP/6443: Outbound traffic from the VerteX management cluster to the deployed clusters' Kubernetes API server. - -- Ensure you have an SSL certificate that matches the domain name you will assign to VerteX. You will need this to - enable HTTPS encryption for VerteX. Reach out to your network administrator or security team to obtain the SSL - certificate. You need the following files: - - - x509 SSL certificate file in base64 format. +:::warning - - x509 SSL certificate key file in base64 format. +Do not use a VerteX-managed Kubernetes cluster when installing VerteX. VerteX-managed clusters contain the VerteX agent +and VerteX-created Kubernetes resources that will interfere with the installation of VerteX. - - x509 SSL certificate authority file in base64 format. +::: -- Ensure the OS and Kubernetes cluster you are installing VerteX onto is FIPS-compliant. Otherwise, VerteX and its - operations will not be FIPS-compliant. +### Kubernetes Cluster -- A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the - annotation `storageclass.kubernetes.io/is-default-class` set to `true`. + - ```shell - kubectl patch storageclass --patch '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}' - ``` +- (FIPS compliance only) The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. + Otherwise, Palette VerteX and its operations will not be FIPS-compliant. - To use another storage class for the Palette VerteX installation, you must set the preferred storage class name in the - `vertex/values.yaml` file using the `mongo.storageClass` parameter. +### Local Environment -- Palette VerteX uses Traefik as the ingress controller. If you already have an ingress controller deployed in the - cluster, set the `ingress.enabled` parameter to `false` in the `values.yaml` file. +- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using + `kubectl` commands and have sufficient permissions to install VerteX. We recommend using a role with cluster-admin + permissions to install VerteX. -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS - encryption for VerteX. +- The following software installed and available: -- Ensure VerteX has access to the required domains and ports. Refer to the - [Required Domains](../install-palette-vertex.md#proxy-requirements) section for more information. + - [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) + - [Helm](https://helm.sh/docs/intro/install/) -- If you are installing VerteX behind a network proxy server, ensure you have the Certificate Authority (CA) certificate - file in the base64 format. You will need this to enable VerteX to communicate with the network proxy server. +- Ensure `unzip` or a similar extraction utility is installed on your system. - Access to the VerteX Helm Charts. Refer to the [Access VerteX](../../vertex.md#access-palette-vertex) for instructions on how to request access to the Helm Chart. @@ -107,12 +60,23 @@ has the necessary network connectivity for VerteX to operate successfully. [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. -:::warning +### Other Prerequisites -Do not use a VerteX-managed Kubernetes cluster when installing VerteX. VerteX-managed clusters contain the VerteX agent -and VerteX-created Kubernetes resources that will interfere with the installation of VerteX. +- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named + `hubble` with the permission `readWriteAnyDatabase`. Refer to the + [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a + database user in Atlas. -::: +- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS + encryption for VerteX. + +- (Proxy environments only) If you are installing VerteX behind a network proxy server, ensure VerteX has access to the + required domains and ports. Refer to the [Required Domains](../install-palette-vertex.md#proxy-requirements) section + for more information. + +- (Proxy environments only) If you are installing VerteX behind a network proxy server, ensure you have the Certificate + Authority (CA) certificate file in the base64 format. You will need this to enable VerteX to communicate with the + network proxy server. ## Install VerteX @@ -225,7 +189,7 @@ your environment. Reach out to our support team if you need assistance. | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette VerteX FIPS packs. These credentials are provided by our support team. | object | | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | + | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette VerteX to use a network proxy in your environment | object | | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your Palette VerteX installation. | string | #### Self-Hosted OCI Registries @@ -1010,4 +974,4 @@ Use the following steps to validate your Palette VerteX installation. ## Next Steps - + From 0f4d328d94cdd7392aa7f5f468e9401cef43fde1 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Tue, 23 Jun 2026 18:23:17 -0400 Subject: [PATCH 06/22] Helm install and image pull secret partials --- _partials/self-hosted/_install-next-steps.mdx | 2 +- ..._image-pull-secret-config-not-required.mdx | 29 + .../_image-pull-secret-config-required.mdx | 13 + .../_image-pull-secret-during-install.mdx | 14 + .../_image-pull-secret-enablement.mdx | 23 + .../_image-pull-secret-helm-install.mdx | 21 + .../_image-pull-secret-intro.mdx | 34 + .../_image-pull-secret-post-install.mdx | 14 + .../_image-pull-secret-prereqs.mdx | 15 + .../_image-pull-secret-validate.mdx | 69 ++ .../_kubernetes-install-begin.mdx | 18 + ...kubernetes-install-cert-manager-airgap.mdx | 68 ++ ...rnetes-install-cert-manager-non-airgap.mdx | 62 + .../_kubernetes-install-cluster-prereqs.mdx | 2 +- .../_kubernetes-install-end.mdx | 113 ++ .../_kubernetes-install-image-swap.mdx | 38 + .../_kubernetes-install-local-prereqs.mdx | 23 + .../_kubernetes-install-main-chart-airgap.mdx | 513 ++++++++ ...bernetes-install-main-chart-non-airgap.mdx | 512 ++++++++ .../_kubernetes-install-other-prereqs.mdx | 24 + .../_kubernetes-install-reach-system.mdx | 45 + .../_kubernetes-install-spectro-mgmt-crds.mdx | 24 + .../_kubernetes-install-validate.mdx | 114 ++ .../configure-image-pull-secret.md | 213 +--- .../airgap-install/install.md | 949 ++------------- .../install-on-kubernetes/install.md | 1037 ++--------------- .../configure-image-pull-secret.md | 102 ++ .../airgap-install/install.md | 1035 ++-------------- .../install-on-kubernetes/install.md | 1014 ++-------------- src/theme/MDXComponents/MDXComponents.ts | 2 + 30 files changed, 2350 insertions(+), 3792 deletions(-) create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-enablement.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-intro.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-post-install.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx create mode 100644 _partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-begin.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-non-airgap.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-end.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-local-prereqs.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-spectro-mgmt-crds.mdx create mode 100644 _partials/self-hosted/kubernetes-install/_kubernetes-install-validate.mdx diff --git a/_partials/self-hosted/_install-next-steps.mdx b/_partials/self-hosted/_install-next-steps.mdx index c9d3848990f..0e7a170f972 100644 --- a/_partials/self-hosted/_install-next-steps.mdx +++ b/_partials/self-hosted/_install-next-steps.mdx @@ -13,6 +13,6 @@ Now that you have installed {props.version}, you can either edition={props.edition} text="activate your installation" url="/activate-installation" - /> . + />. Beginning with version 4.6.32, once you install {props.version}, you have 30 days to activate it; versions older than 4.6.32 do not need to be activated. During the 30-day trial period, you can use {props.version} without any restrictions. After 30 days, you can continue to use {props.version}, but you cannot deploy additional clusters or perform any day-2 operations on existing clusters until {props.version} is activated. Each installation of {props.version} must be activated separately. We recommend activating {props.version} as soon as possible to avoid any disruptions. \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx new file mode 100644 index 00000000000..26df429de95 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx @@ -0,0 +1,29 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-config-not-required +--- + +Image pull secrets are managed by Spectro Cloud. While you do not need to configure the pull secret, you must ensure +that the secret propagates to your workload clusters. This happens automatically unless there are connectivity +constraints from your workload clusters to the Palette or Palette VerteX management plane. [THESE REQUIRE MANUAL +INTERVENTION STEPS THAT WE DON'T HAVE YET.] + +- **SaaS deployments** — Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action + is needed; for dedicated SaaS customers with access to the system console, consult with your customer support + representative. + +- **Airgapped self-hosted {props.version} environments** - The Spectro Cloud-owned images are pulled directly + from your local registry and do not need the Spectro Cloud's OCI registry pull secret. + +- **Environments with configured mirror registries or image swaps** - If your non-airgapped self-hosted {props.version} environment pulls all Spectro Cloud-owned images from a custom or private registry through + or [image swaps](/clusters/cluster-management/image-swap/), you do not need to configure the image pull secret. + +- **Self-hosted OCI registries with pull-through cache** - If you are using a registry that uses pull-through cache (for + example, a [Harbor proxy cache project](https://goharbor.io/docs/latest/administration/configure-proxy-cache/) or a + [JFrog Artifactory remote repository](https://docs.jfrog.com/artifactory/docs/remote-repositories)), you must + configure the hardened image registry credentials at the cache level. + diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx new file mode 100644 index 00000000000..0ef5693a013 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx @@ -0,0 +1,13 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-config-required +--- + +Non-airgapped self-hosted {props.version} environments that pull images directly from Spectro Cloud-owned OCI +registries must configure an image pull secret. This includes environments that _do not_ use + or [image swap](/clusters/cluster-management/image-swap/) configurations to redirect image pulls to a private +registry. \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx new file mode 100644 index 00000000000..b0046b54be7 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx @@ -0,0 +1,14 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-during-install +--- + +You can add your image pull secret when installing self-hosted {props.version} using Helm charts or the +Palette CLI. + +:::info + +Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the +secret [post-installation](#configure-image-pull-secret-post-installation) using the system console. + +::: \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-enablement.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-enablement.mdx new file mode 100644 index 00000000000..91dd77ad0d1 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-enablement.mdx @@ -0,0 +1,23 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-enablement +--- + +1. Log in to the {props.version} + . + +2. From the left main menu, select **Administration**. + +3. Select the **Hardened Images** tab. + +4. In the **Pull secret** field, paste the image pull secret you received from Spectro Cloud support. + +5. Select **Validate and Save**. + +If the secret is valid, it is saved and distributed to the management plane, workload clusters, and PCGs. If you need to +rotate your image pull secret for any reason, repeat these steps, and paste your new secret into the **Pull secret** +field. diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx new file mode 100644 index 00000000000..e998f0741e0 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx @@ -0,0 +1,21 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-helm-install +--- + +For self-hosted {props.version} environments installed on an existing Kubernetes cluster using Helm charts, +you can apply your image pull secret during the installation process. + +| **File** | **Parameter** | +| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| {props.helm}/values.yaml | | +| `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | + +For the full installation process, refer to the + . \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-intro.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-intro.mdx new file mode 100644 index 00000000000..0371bf50966 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-intro.mdx @@ -0,0 +1,34 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-intro +--- + +Beginning in 4.9.b, Spectro Cloud is initiating the shift to security-hardened images. While images have a smaller +attack surface compared to physical and virtual machines, security-hardened images are built to reduce the attack +surface further by containing only the essential runtime components an application needs. They have strict Service Level +Agreements (SLAs) that require the images to be regularly scanned for vulnerabilities, rebuilt, and patched, keeping the +number of CVEs to a minimum. These images also contain artifacts such as Software Bill of Materials (SBOMs) and +cryptographic signatures to verify the image has not been tampered with. + +As a result of this transition, all images hosted in Spectro Cloud's OCI registries must now be authenticated and +retrieved using +[image pull secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets-1). Like + , these secrets are obtained from your Spectro Cloud +customer support representative; they are intended for long-term use and only need to be configured once as part of your +initial setup process. If you need to rotate the secret as part of your organization's security policy, contact support +to request a new one. + +Once configured, the secret is distributed to the management plane, PCGs, and all managed workload clusters so they can +pull the required images. + +:::warning + +As of 4.9.b, configuring an image pull secret is optional; however, it will be mandatory in an upcoming release. +Therefore, we recommend configuring your image pull secret as soon as possible to avoid service disruptions. Refer to +the [Announcements](/release-notes/announcements/#upcoming-breaking-changes) page for the latest updates. + +::: \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-post-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-post-install.mdx new file mode 100644 index 00000000000..5ad7c3ee99f --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-post-install.mdx @@ -0,0 +1,14 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-post-install +--- + +Alternatively, you can configure the image pull secret once {props.version} is installed. + +:::warning + +Configuring an image pull secret is currently optional. Once it is mandatory, image pull secrets must be added during +the installation process. At that time, the system console method described below will only be used to rotate the image +pull secret if required by your organization's security policy. + +::: \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx new file mode 100644 index 00000000000..1465fdd6ee2 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx @@ -0,0 +1,15 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-prereqs +--- + +- A self-hosted instance of {props.version}. + +- Access to the {props.version} + + +- An image pull secret provided by Spectro Cloud support. \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx new file mode 100644 index 00000000000..63683184869 --- /dev/null +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx @@ -0,0 +1,69 @@ +--- +partial_category: self-hosted +partial_name: image-pull-secret-validate +--- + + + + + +1. Log in to the {props.version} + . + +2. From the left main menu, select **Administration**. + +3. Select the **Hardened Images** tab. + +4. Verify that the **Pull secret** field displays a masked secret. + + {props.edition === 'vertex' + ? Configuring an image pull secret in the system console. + : Configuring an image pull secret in the system console + } + + + + + +1. Open a terminal session in an environment that has network access to the cluster. Set the `KUBECONFIG` environment + variable to the file path of your cluster's kubeconfig that {props.version} is installed on. + + ```shell + export KUBECONFIG= + ``` + +2. Issue the following command to verify the secret propagated to your management cluster matches the one configured in + the system console. + + ```shell + kubectl get secret spectro-image-pull-secret --namespace hubble-system --output yaml + ``` + + ```yaml title="Example output" hideClipboard {3} + apiVersion: v1 + data: + .dockerconfigjson: abcdEFGhiJKlmnOPQrSTUVwX... # output omitted for brevity + kind: Secret + metadata: + annotations: + meta.helm.sh/release-name: hubble + meta.helm.sh/release-namespace: default + creationTimestamp: "2026-06-18T22:33:37Z" + labels: + app: spectro + app.kubernetes.io/managed-by: Helm + module: hubble + name: spectro-image-pull-secret + namespace: hubble-system + resourceVersion: "28192" + uid: c7991fac-2ec0-4419-b451-10c82208f8e5 + type: kubernetes.io/dockerconfigjson + ``` + + + + \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-begin.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-begin.mdx new file mode 100644 index 00000000000..601804c6fac --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-begin.mdx @@ -0,0 +1,18 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-begin +--- + +The following instructions are written agnostic to the Kubernetes distribution you are using. Depending on the +underlying infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match +your environment. Reach out to our support team if you need assistance. + +1. Open a terminal session and navigate to the directory where you downloaded the {props.version} install ZIP file + provided by our support team. Unzip the file to a directory named {props.helm}-install. + + {`unzip charts.zip -d ${props.helm}-install`} + + +2. Navigate to the {props.helm}-install directory. + + {`cd ${props.helm}-install`} \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx new file mode 100644 index 00000000000..abd4e0720ac --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx @@ -0,0 +1,68 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-cert-manager-airgap +--- + +Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. + + ```shell + vim extras/cert-manager/values.yaml + ``` + + +
  • Append `` to each image, along with the `` where you want to store your images.
  • + + ```yaml hideClipboard title="Example output" + image: + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` + + In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. + + ```yaml hideClipboard title="Example output" + image: + cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` + +
  • If the registry you are pulling images from requires authentication, use the base64-encoded + contents of your `config.json` containing the registry credentials. Refer to + for more information.
  • + + ```yaml title="Example configuration" hideClipboard {5} + imagePullSecret: + # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. + # Pods automatically reference that pull secret when create is true or the secret already exists. + create: false + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson + ``` + +
  • Install the Cert-Manager Helm chart.
  • + + ```shell + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml + ``` + + ```shell hideClipboard title="Example output" + Release "cert-manager" does not exist. Installing it now. + NAME: cert-manager + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-non-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-non-airgap.mdx new file mode 100644 index 00000000000..08828b7946b --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-non-airgap.mdx @@ -0,0 +1,62 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-cert-manager-non-airgap +--- + +Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. + + ```shell + vim extras/cert-manager/values.yaml + ``` + +
  • If you plan to pull images from Spectro Cloud OCI registries, paste the image pull secret received from your + customer support representative into the `imagePullSecret.dockerConfigJson` field. It is not required if you plan to + use mirror registries or image swap.
  • + + Alternately, if you plan to pull images from a private registry that requires authentication, use the base64-encoded + contents of your `config.json` containing the registry credentials. Refer to + for more information. + + :::info + + If you omit the image pull secret during installation, you must provide it through the system console. Refer to + for more information. + + ::: + + ```yaml title="Example configuration" hideClipboard {5} + imagePullSecret: + # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. + # Pods automatically reference that pull secret when create is true or the secret already exists. + create: false + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson + ``` + +
  • Install the Cert-Manager Helm chart.
  • + + ```shell + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml + ``` + + ```shell hideClipboard title="Example output" + Release "cert-manager" does not exist. Installing it now. + NAME: cert-manager + LAST DEPLOYED: Wed Jun 17 12:54:27 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx index 2c477cb47a3..f923485343f 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx @@ -35,7 +35,7 @@ partial_name: kubernetes-install-cluster-prereqs - x509 SSL certificate authority file in base64 format -- The Kubernetes cluster must use a Kubernetes version compatible with your {props.version}version. Refer to +- The Kubernetes cluster must use a Kubernetes version compatible with your {props.version} version. Refer to {`helm upgrade --values ${props.helm}/values.yaml \\\n hubble ${props.helm}/spectro-mgmt-plane-*.tgz --install`} + + ```shell hideClipboard title="Example output" + Release "hubble" does not exist. Installing it now. + NAME: hubble + LAST DEPLOYED: Wed Jun 17 21:41:31 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` + +
  • Track the installation process using the command below. {props.version} is ready when the deployments in the namespaces + `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state.
  • + + + + ```shell + kubectl get pods --all-namespaces --watch + ``` + + :::tip + + For a more user-friendly experience, use the open source tool [k9s](https://k9scli.io/) to monitor the installation + process. + + ::: + +
  • Create a DNS CNAME record that is mapped to the {props.version} `traefik-ingress-controller` load balancer. You can use the + following command to retrieve the load balancer IP address. If you need assistance creating the DNS record, contact + your network administrator.
  • + + ```shell + kubectl get service traefik-ingress-controller --namespace ingress-traefik \ + --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' + ``` + + :::warning + + If {props.version} has only one tenant and you use local accounts with Single Sign-On (SSO) disabled, you can access + {props.version} using the IP address or any domain name that resolves to that IP. However, once you enable SSO, users + must log in using the tenant-specific subdomain. For example, if you create a tenant named `tenant1` and the domain + name you assigned to {props.version} is {props.helm}.example.com, the tenant URL will be tenant1.{props.helm}.example.com. We recommend you create an additional wildcard DNS record to map all tenant URLs to the {props.version} load balancer. + For example, *.{props.helm}.example.com. + + ::: + +
  • Use the custom domain name or the IP address of the load balancer to visit the {props.version} system console. To access the + system console, open a web browser and paste the custom domain URL in the address bar and append the value + `/system`. Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. + Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system + console.
  • + + The first time you visit the {props.version} system console, a warning message about a not-trusted SSL certificate may + appear. This is expected, as you still need to upload your SSL certificate to {props.version}. You can ignore this warning + message and proceed. + + {props.edition === 'vertex' + ? Screenshot of the VerteX system console showing Username and Password fields. + : Screenshot of the Palette system console showing Username and Password fields. + } + + +
  • Log in to the system console using the following default credentials. Refer to + guide for more information.
  • + + | **Parameter** | **Value** | + | ------------- | --------- | + | Username | `admin` | + | Password | `admin` | + + After logging in, you must create a new password. Once you create your password, you are redirected to the {props.version} + system console. Use the username `admin` and your new password to log in to the system console. You can create + additional system administrator accounts and assign roles to users in the system console. Refer to + for more information. + +
  • After logging in, a summary page is displayed. {props.version} is installed with a self-signed SSL certificate. To assign a + different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority + files to {props.version}. You can upload the files using the {props.version} system console. Refer to + for more information.
  • + + :::warning + + If you plan to deploy host clusters into different networks, you may require a reverse proxy. Check out the + guide for more information. + + ::: + +You now have a self-hosted instance of {props.version} installed in a Kubernetes cluster. Make sure you retain the `values.yaml` +file, as you can refer to it for future upgrades. \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx new file mode 100644 index 00000000000..c7ab3bceadc --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx @@ -0,0 +1,38 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-image-swap +--- + +(Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap + Helm chart. Image swap rewrites pod image references to pull from your mirror registry. {props.version} ignores the + `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on + whether you added your image swap values to {props.helm}/values.yaml or `extras/image-swap/values.yaml`. + + + + + + {`helm upgrade --values ${props.helm}/values.yaml \\\n image-swap extras/image-swap/image-swap-*.tgz --install`} + + + + + + ```shell + helm upgrade --values extras/image-swap/values.yaml \ + image-swap extras/image-swap/image-swap-*.tgz --install + ``` + + + + + + ```shell hideClipboard title="Example output" + Release "image-swap" does not exist. Installing it now. + NAME: image-swap + LAST DEPLOYED: Wed Jun 17 14:44:13 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-local-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-local-prereqs.mdx new file mode 100644 index 00000000000..c2c7d8d3ec7 --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-local-prereqs.mdx @@ -0,0 +1,23 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-local-prereqs +--- + +- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using + `kubectl` commands and have sufficient permissions to install {props.version}. We recommend using a role with cluster-admin + permissions to install {props.version}. + +- The following software installed and available: + + - [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) + - [Helm](https://helm.sh/docs/intro/install/) + - `unzip` or a similar extraction utility + - `vim`, `nano`, or a similar text editor + +- Access to the {props.version} Helm charts (`charts.zip`). Refer to + for instructions on how to request access. \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx new file mode 100644 index 00000000000..3d94fc10fec --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx @@ -0,0 +1,513 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-main-chart-airgap +--- + +Open the file {props.helm}/values.yaml using a text editor of your choice. This example uses Vim. + + {`vim ${props.helm}/values.yaml`} + + +
  • The file {props.helm}/values.yaml contains the default values for the {props.version} installation parameters. The following table lists the most important parameters to pay attention to. For a complete list of fields and additional + information, refer to + for more information.
  • + + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). | string | + | `env.rootDomain` | The URL name or IP address you will use for the {props.version} installation. | string | + | `config.installationMode` | Determines whether your {props.version} installation should have a default connection to the internet. Set to `airgap`. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for {props.version} FIPS packs. These credentials are provided by our support team. If using images from a self-hosted OCI registry instead, leave these sections blank and refer to the [Self-Hosted OCI Registries](#self-hosted-oci-registries) table instead. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | (Proxy environments only) Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | + | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your {props.version} installation. | string | + + #### Self-Hosted OCI Registries + + The following parameters are required if you pull {props.version} images from a self-hosted OCI registry instead of a + Spectro Cloud OCI registry or AWS ECR. + + :::tip + + If you would prefer to keep your image swap values in a separate location, you can use the following table to + complete the `extras/image-swap/values.yaml` file instead. Otherwise, complete the following fields in {props.helm}/values.yaml. + + ```shell + tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ + vim extras/image-swap/values.yaml + ``` + + ::: + + | **Parameter** | **Description** | **Type** | + | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the page for parameter descriptions. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the page for examples. | string | + | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | + | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing {props.version} on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | + + :::info + + Include `/v2` in your mirror registry endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. + + ::: + +
  • Save the completed {props.helm}/values.yaml file. Expand the following sections to review an example of the + {props.helm}/values.yaml file with the required parameters highlighted.
  • + + + + + + ```yaml {8,26,29,60,84-93,122-123,149-151} + ######################### + # Spectro Cloud Palette # + ######################### + + global: + imagePullSecret: + # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity + + # MongoDB Configuration + mongo: + # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas + internal: true + + # Mongodb URL. Only change if using Mongo Atlas. + databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" + # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. + databasePassword: "" + + #No. of mongo replicas to run, default is 3 + replicas: 3 + # The following only apply if mongo.internal == true + cpuLimit: "2000m" + memoryLimit: "4Gi" + pvcSize: "20Gi" + storageClass: "" # leave empty to use the default storage class + + config: + installationMode: "airgap" #values can be connected or airgap. + isPaletteBaseCluster: false + + # SSO SAML Configuration (Optional for self-hosted type) + sso: + saml: + enabled: false + acsUrlRoot: "myfirstpalette.spectrocloud.com" + acsUrlScheme: "https" + audienceUrl: "https://www.spectrocloud.com" + entityId: "https://www.spectrocloud.com" + apiVersion: "v1" + + # Email Configurations. (Optional for self-hosted type) + email: + enabled: false + emailId: "noreply@spectrocloud.com" + smtpServer: "smtp.gmail.com" + smtpPort: 587 + insecureSkipVerifyTls: false + fromEmailId: "noreply@spectrocloud.com" + password: "" # base64 encoded SMTP password + + env: + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer + # E.g., myfirstpalette.spectrocloud.com + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) + # + # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes + # E.g., *.myfirstpalette.spectrocloud.com + rootDomain: "my-domain.docs-test.spectrocloud.com" + + # stableEndpointAccess is used when deploying EKS clusters in Private network type. + # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true + cluster: + stableEndpointAccess: false + + # registry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # insecureSkipVerify: false + # caCert: "" + + # ociPackRegistry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # baseContentPath: "" # + # insecureSkipVerify: false + # caCert: "" + + ociPackEcrRegistry: + endpoint: "https://123456789.dkr.ecr.us-east-1.amazonaws.com" # + name: "Palette Packs" # + accessKey: "**********" # + secretKey: "**********" # + baseContentPath: "production-fips" # + isPrivate: true + insecureSkipVerify: false + caCert: "" + credentialType: "" + + # ociImageRegistry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # baseContentPath: "" # + # insecureSkipVerify: false + # caCert: "" + # mirrorRegistries: "" # See instructions below. + + # Instruction for mirrorRegistries. + # ---------------------------------- + # Please provide the registry endpoint for the following registries, separated by double colons (::): + # docker.io + # gcr.io + # ghcr.io + # k8s.gcr.io + # registry.k8s.io + # quay.io + # For each registry, follow this example format: + # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ + # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. + + imageSwapImages: + imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" + + imageSwapConfig: + isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false + + grpc: + external: false + endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. + grpcStaticIP: "" + caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert + serverCrtBase64: "" + serverKeyBase64: "" + insecureSkipVerify: false + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" + ingress: + # When enabled the Traefik ingress controller would be installed + enabled: true + + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + + ingress: + # Default SSL certificate and key for the ingress controller (Optional) + # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) + certificate: "" + key: "" + + #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. + ingressStaticIP: "" + + # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. + terminateHTTPSAtLoadBalancer: false + + frps: + frps: + enabled: false + frpHostURL: proxy.sample.spectrocloud.com + server: + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity + ca: + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity + service: + annotations: {} + + ui-system: + enabled: true + ui: + nocUI: + enable: true + mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette + mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID + + reachSystem: + enabled: false + proxySettings: + http_proxy: "" + https_proxy: "" + no_proxy: "" + ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. + scheduleOnControlPlane: true + ``` + + + + + + ```yaml {8,26,29,60,75-82,94-102,117-119,121-122,149-150} + ######################### + # Spectro Cloud Palette # + ######################### + + global: + imagePullSecret: + # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity + + # MongoDB Configuration + mongo: + # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas + internal: true + + # Mongodb URL. Only change if using Mongo Atlas. + databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" + # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. + databasePassword: "" + + #No. of mongo replicas to run, default is 3 + replicas: 3 + # The following only apply if mongo.internal == true + cpuLimit: "2000m" + memoryLimit: "4Gi" + pvcSize: "20Gi" + storageClass: "" # leave empty to use the default storage class + + config: + installationMode: "airgap" #values can be connected or airgap. + isPaletteBaseCluster: false + + # SSO SAML Configuration (Optional for self-hosted type) + sso: + saml: + enabled: false + acsUrlRoot: "myfirstpalette.spectrocloud.com" + acsUrlScheme: "https" + audienceUrl: "https://www.spectrocloud.com" + entityId: "https://www.spectrocloud.com" + apiVersion: "v1" + + # Email Configurations. (Optional for self-hosted type) + email: + enabled: false + emailId: "noreply@spectrocloud.com" + smtpServer: "smtp.gmail.com" + smtpPort: 587 + insecureSkipVerifyTls: false + fromEmailId: "noreply@spectrocloud.com" + password: "" # base64 encoded SMTP password + + env: + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer + # E.g., myfirstpalette.spectrocloud.com + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) + # + # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes + # E.g., *.myfirstpalette.spectrocloud.com + rootDomain: "my-domain.docs-test.spectrocloud.com" + + # stableEndpointAccess is used when deploying EKS clusters in Private network type. + # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true + cluster: + stableEndpointAccess: false + + # registry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # insecureSkipVerify: false + # caCert: "" + + ociPackRegistry: + endpoint: "example.harbor.org" # + name: "Packs OCI" # + password: "**************" # + username: "**************" # + baseContentPath: "spectro-packs" # + insecureSkipVerify: false + caCert: "" + + # ociPackEcrRegistry: + # endpoint: "" # + # name: "" # + # accessKey: "" # + # secretKey: "" # + # baseContentPath: "" # + # isPrivate: true + # insecureSkipVerify: false + # caCert: "" + + ociImageRegistry: + endpoint: "example.harbor.org" # + name: "Images OCI" # + password: "**************" # + username: "**************" # + baseContentPath: "spectro-images" # + insecureSkipVerify: false + caCert: "" + mirrorRegistries: "docker.io::harbor.example.org/project/docker.io,gcr.io::harbor.example.org/project/gcr.io" # See instructions below. + + # Instruction for mirrorRegistries. + # ---------------------------------- + # Please provide the registry endpoint for the following registries, separated by double colons (::): + # docker.io + # gcr.io + # ghcr.io + # k8s.gcr.io + # registry.k8s.io + # quay.io + # For each registry, follow this example format: + # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ + # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. + + imageSwapImages: + imageSwapInitImage: "harbor.example.org/project/us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "harbor.example.org/project/us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" + + imageSwapConfig: + isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false + + grpc: + external: false + endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. + grpcStaticIP: "" + caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert + serverCrtBase64: "" + serverKeyBase64: "" + insecureSkipVerify: false + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" + ingress: + # When enabled the Traefik ingress controller would be installed + enabled: true + + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + + ingress: + # Default SSL certificate and key for the ingress controller (Optional) + # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) + certificate: "" + key: "" + + #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. + ingressStaticIP: "" + + # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. + terminateHTTPSAtLoadBalancer: false + + frps: + frps: + enabled: false + frpHostURL: proxy.sample.spectrocloud.com + server: + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity + ca: + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity + service: + annotations: {} + + ui-system: + enabled: true + ui: + nocUI: + enable: true + mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette + mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID + + reachSystem: + enabled: false + proxySettings: + http_proxy: "" + https_proxy: "" + no_proxy: "" + ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. + scheduleOnControlPlane: true + ``` + + + + \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx new file mode 100644 index 00000000000..324b7df838d --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx @@ -0,0 +1,512 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-main-chart-non-airgap +--- + +Open the file {props.helm}/values.yaml using a text editor of your choice. This example uses Vim. + + {`vim ${props.helm}/values.yaml`} + + +
  • The file {props.helm}/values.yaml contains the default values for the {props.version} installation parameters. The following table lists the most important parameters to pay attention to. For a complete list of fields and additional + information, refer to + for more information.
  • + + | **Parameter** | **Description** | **Type** | + | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from Spectro Cloud OCI registries (without mirror registries or image swap configured) or images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). If you omit the image pull secret during installation, you must provide it through the system console. Refer to for more information. | string | + | `env.rootDomain` | The URL name or IP address you will use for the {props.version} installation. | string | + | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for {props.version} FIPS packs. These credentials are provided by our support team. If using images from a self-hosted OCI registry instead, leave these sections blank and refer to the [Self-Hosted OCI Registries](#self-hosted-oci-registries) table instead. | object | + | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | + | `reachSystem` | (Proxy environments only) Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | + | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your {props.version} installation. | string | + + #### Self-Hosted OCI Registries + + The following parameters are required if you pull {props.version} images from a self-hosted OCI registry instead of a + Spectro Cloud OCI registry or AWS ECR. + + :::tip + + If you would prefer to keep your image swap values in a separate location, you can use the following table to + complete the `extras/image-swap/values.yaml` file instead. Otherwise, complete the following fields in {props.helm}/values.yaml. + + ```shell + tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ + vim extras/image-swap/values.yaml + ``` + + ::: + + | **Parameter** | **Description** | **Type** | + | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | + | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the page for parameter descriptions. | object | + | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the page for examples. | string | + | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | + | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing {props.version} on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | + + :::info + + Include `/v2` in your mirror registry endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. + + ::: + +
  • Save the completed {props.helm}/values.yaml file. Expand the following sections to review an example of the + {props.helm}/values.yaml file with the required parameters highlighted.
  • + + + + + + ```yaml {8,26,60,84-93,122-123,149-151} + ######################### + # Spectro Cloud Palette # + ######################### + + global: + imagePullSecret: + # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity + + # MongoDB Configuration + mongo: + # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas + internal: true + + # Mongodb URL. Only change if using Mongo Atlas. + databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" + # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. + databasePassword: "" + + #No. of mongo replicas to run, default is 3 + replicas: 3 + # The following only apply if mongo.internal == true + cpuLimit: "2000m" + memoryLimit: "4Gi" + pvcSize: "20Gi" + storageClass: "" # leave empty to use the default storage class + + config: + installationMode: "connected" #values can be connected or airgap. + isPaletteBaseCluster: false + + # SSO SAML Configuration (Optional for self-hosted type) + sso: + saml: + enabled: false + acsUrlRoot: "myfirstpalette.spectrocloud.com" + acsUrlScheme: "https" + audienceUrl: "https://www.spectrocloud.com" + entityId: "https://www.spectrocloud.com" + apiVersion: "v1" + + # Email Configurations. (Optional for self-hosted type) + email: + enabled: false + emailId: "noreply@spectrocloud.com" + smtpServer: "smtp.gmail.com" + smtpPort: 587 + insecureSkipVerifyTls: false + fromEmailId: "noreply@spectrocloud.com" + password: "" # base64 encoded SMTP password + + env: + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer + # E.g., myfirstpalette.spectrocloud.com + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) + # + # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes + # E.g., *.myfirstpalette.spectrocloud.com + rootDomain: "my-domain.docs-test.spectrocloud.com" + + # stableEndpointAccess is used when deploying EKS clusters in Private network type. + # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true + cluster: + stableEndpointAccess: false + + # registry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # insecureSkipVerify: false + # caCert: "" + + # ociPackRegistry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # baseContentPath: "" # + # insecureSkipVerify: false + # caCert: "" + + ociPackEcrRegistry: + endpoint: "https://123456789.dkr.ecr.us-east-1.amazonaws.com" # + name: "Palette Packs" # + accessKey: "**********" # + secretKey: "**********" # + baseContentPath: "production-fips" # + isPrivate: true + insecureSkipVerify: false + caCert: "" + credentialType: "" + + # ociImageRegistry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # baseContentPath: "" # + # insecureSkipVerify: false + # caCert: "" + # mirrorRegistries: "" # See instructions below. + + # Instruction for mirrorRegistries. + # ---------------------------------- + # Please provide the registry endpoint for the following registries, separated by double colons (::): + # docker.io + # gcr.io + # ghcr.io + # k8s.gcr.io + # registry.k8s.io + # quay.io + # For each registry, follow this example format: + # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ + # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. + + imageSwapImages: + imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" + + imageSwapConfig: + isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false + + grpc: + external: false + endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. + grpcStaticIP: "" + caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert + serverCrtBase64: "" + serverKeyBase64: "" + insecureSkipVerify: false + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" + ingress: + # When enabled the Traefik ingress controller would be installed + enabled: true + + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + + ingress: + # Default SSL certificate and key for the ingress controller (Optional) + # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) + certificate: "" + key: "" + + #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. + ingressStaticIP: "" + + # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. + terminateHTTPSAtLoadBalancer: false + + frps: + frps: + enabled: false + frpHostURL: proxy.sample.spectrocloud.com + server: + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity + ca: + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity + service: + annotations: {} + + ui-system: + enabled: true + ui: + nocUI: + enable: true + mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette + mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID + + reachSystem: + enabled: false + proxySettings: + http_proxy: "" + https_proxy: "" + no_proxy: "" + ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. + scheduleOnControlPlane: true + ``` + + + + + + ```yaml {8,26,60,75-82,94-102,117-119,121-122,149-150} + ######################### + # Spectro Cloud Palette # + ######################### + + global: + imagePullSecret: + # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication + dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity + + # MongoDB Configuration + mongo: + # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas + internal: true + + # Mongodb URL. Only change if using Mongo Atlas. + databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" + # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. + databasePassword: "" + + #No. of mongo replicas to run, default is 3 + replicas: 3 + # The following only apply if mongo.internal == true + cpuLimit: "2000m" + memoryLimit: "4Gi" + pvcSize: "20Gi" + storageClass: "" # leave empty to use the default storage class + + config: + installationMode: "connected" #values can be connected or airgap. + isPaletteBaseCluster: false + + # SSO SAML Configuration (Optional for self-hosted type) + sso: + saml: + enabled: false + acsUrlRoot: "myfirstpalette.spectrocloud.com" + acsUrlScheme: "https" + audienceUrl: "https://www.spectrocloud.com" + entityId: "https://www.spectrocloud.com" + apiVersion: "v1" + + # Email Configurations. (Optional for self-hosted type) + email: + enabled: false + emailId: "noreply@spectrocloud.com" + smtpServer: "smtp.gmail.com" + smtpPort: 587 + insecureSkipVerifyTls: false + fromEmailId: "noreply@spectrocloud.com" + password: "" # base64 encoded SMTP password + + env: + # rootDomain is a DNS record which will be mapped to the ingress controller load balancer + # E.g., myfirstpalette.spectrocloud.com + # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) + # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) + # + # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes + # E.g., *.myfirstpalette.spectrocloud.com + rootDomain: "my-domain.docs-test.spectrocloud.com" + + # stableEndpointAccess is used when deploying EKS clusters in Private network type. + # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true + cluster: + stableEndpointAccess: false + + # registry: + # endpoint: "" # + # name: "" # + # password: "" # + # username: "" # + # insecureSkipVerify: false + # caCert: "" + + ociPackRegistry: + endpoint: "example.harbor.org" # + name: "Packs OCI" # + password: "**************" # + username: "**************" # + baseContentPath: "spectro-packs" # + insecureSkipVerify: false + caCert: "" + + # ociPackEcrRegistry: + # endpoint: "" # + # name: "" # + # accessKey: "" # + # secretKey: "" # + # baseContentPath: "" # + # isPrivate: true + # insecureSkipVerify: false + # caCert: "" + + ociImageRegistry: + endpoint: "example.harbor.org" # + name: "Images OCI" # + password: "**************" # + username: "**************" # + baseContentPath: "spectro-images" # + insecureSkipVerify: false + caCert: "" + mirrorRegistries: "docker.io::harbor.example.org/project/docker.io,gcr.io::harbor.example.org/project/gcr.io" # See instructions below. + + # Instruction for mirrorRegistries. + # ---------------------------------- + # Please provide the registry endpoint for the following registries, separated by double colons (::): + # docker.io + # gcr.io + # ghcr.io + # k8s.gcr.io + # registry.k8s.io + # quay.io + # For each registry, follow this example format: + # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ + # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. + + imageSwapImages: + imageSwapInitImage: "harbor.example.org/project/us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" + imageSwapImage: "harbor.example.org/project/us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" + + imageSwapConfig: + isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false + + grpc: + external: false + endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. + grpcStaticIP: "" + caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert + serverCrtBase64: "" + serverKeyBase64: "" + insecureSkipVerify: false + tunnel: + preferredServer: + endpoint: "" + servers: + - endpoint: "" + ingress: + # When enabled the Traefik ingress controller would be installed + enabled: true + + # Port allocation behaviour based on traefik.hostPort: + # + # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. + # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. + traefik: + # Whether to front the Traefik ingress controller with a cloud + # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) + hostPort: false + + ingress: + # Default SSL certificate and key for the ingress controller (Optional) + # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com + # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) + certificate: "" + key: "" + + #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. + annotations: {} + # AWS example + # service.beta.kubernetes.io/aws-load-balancer-internal: "true" + # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp + # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: + # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" + # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' + + # Azure example + # service.beta.kubernetes.io/azure-load-balancer-internal: "true" + # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel + + # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. + ingressStaticIP: "" + + # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. + terminateHTTPSAtLoadBalancer: false + + frps: + frps: + enabled: false + frpHostURL: proxy.sample.spectrocloud.com + server: + crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity + key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity + ca: + crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity + service: + annotations: {} + + ui-system: + enabled: true + ui: + nocUI: + enable: true + mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette + mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID + + reachSystem: + enabled: false + proxySettings: + http_proxy: "" + https_proxy: "" + no_proxy: "" + ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. + scheduleOnControlPlane: true + ``` + + + + \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx new file mode 100644 index 00000000000..b940306bd5e --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx @@ -0,0 +1,24 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-other-prereqs +--- + +- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named + `hubble` with the permission `readWriteAnyDatabase`. Refer to the + [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for more information. + +- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS + encryption for {props.version}. + +- (Proxy environments only) If you are installing {props.version} behind a network proxy server, ensure {props.version} has access to the + required domains and ports. Refer to + for more information. + +- (Proxy environments only) If you are installing {props.version} behind a network proxy server, ensure you have the network proxy's Certificate + Authority (CA) certificate file in the base64 format. You will need this to enable {props.version} to communicate with the + network proxy server. \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx new file mode 100644 index 00000000000..7867819a120 --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx @@ -0,0 +1,45 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-reach-system +--- + +(Proxy environments only) If you are installing {props.version} in an environment where a network proxy must be + configured for {props.version} to access the internet, install the Reach System chart using the following command. + + :::warning + + Ensure you + set `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in {props.helm}/values.yaml as well. + + ::: + + {`helm upgrade --values ${props.helm}/values.yaml \\\n reach-system extras/reach-system/reach-system-*.tgz --install`} + + ```shell hideClipboard title="Example output" + Release "reach-system" does not exist. Installing it now. + NAME: reach-system + LAST DEPLOYED: Fri Jan 30 18:40:57 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` + +
    + + Update containerd to use proxy configurations + + If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy + settings. You can do this by updating the containerd configuration file on each node in the cluster. The + configuration file is typically located at `/etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an + example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for + guidance. + + ``` + [Service] + Environment="HTTP_PROXY=http://example.com:9090" + Environment="HTTPS_PROXY=http://example.com:9090" + Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" + ``` + +
    \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-spectro-mgmt-crds.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-spectro-mgmt-crds.mdx new file mode 100644 index 00000000000..db0e5ce3204 --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-spectro-mgmt-crds.mdx @@ -0,0 +1,24 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-spectro-mgmt-crds +--- + +Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by + {props.version}, including Traefik CRDs, and must be installed before the main {props.version} Helm chart. When the + chart is installed, the custom resource types are registered with the Kubernetes API server; no pods are deployed. + + ```shell + helm upgrade --install spectro-mgmt-crds \ + extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ + --values extras/spectro-mgmt-crds/values.yaml + ``` + + ```shell hideClipboard title="Example output" + Release "spectro-mgmt-crds" does not exist. Installing it now. + NAME: spectro-mgmt-crds + LAST DEPLOYED: Wed Jun 17 21:17:39 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` \ No newline at end of file diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-validate.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-validate.mdx new file mode 100644 index 00000000000..54371a87fe4 --- /dev/null +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-validate.mdx @@ -0,0 +1,114 @@ +--- +partial_category: self-hosted +partial_name: kubernetes-install-validate +--- + +Use the following steps to validate your {props.version} installation. + + + + + +1. Open up a web browser and navigate to the {props.version} system console. To access the system console, open a web + browser and paste the `env.rootDomain` value you provided in the address bar and append the value `/system`. You can + also use the IP address of the load balancer. + +2. Log in using the default credentials. After logging in, you are prompted to create a new password. Enter a new + password and save your changes. You are redirected to the {props.version} system console. + + + + + +1. Open a terminal session with access to the cluster you installed {props.version} on. + +2. Verify all pods in all namespaces are running. + + ```shell + kubectl get pods --all-namespaces + ``` + + ```shell hideClipboard title="Example output" + NAMESPACE NAME READY STATUS RESTARTS AGE + cert-manager cert-manager-5fb779d887-mz2vb 1/1 Running 0 8m46s + cert-manager cert-manager-cainjector-764f9646d4-7nhpq 1/1 Running 0 8m46s + cert-manager cert-manager-webhook-85b8dbdddd-fkn6z 1/1 Running 0 8m46s + cp-system spectro-cp-ui-5dffbcdc78-gk8st 1/1 Running 0 7m14s + hubble-system auth-7f4c7ff9c-2clwp 1/1 Running 0 6m8s + hubble-system auth-7f4c7ff9c-j84bt 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-9r8bp 1/1 Running 0 6m7s + hubble-system cloud-8f8467c95-pvcv4 1/1 Running 0 6m8s + hubble-system configserver-5bc8f9fdcb-mbt66 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-bmzdk 1/1 Running 0 6m8s + hubble-system event-5fbf6b7f44-cxc58 1/1 Running 0 6m7s + hubble-system event-5fbf6b7f44-zhr9h 1/1 Running 0 6m7s + hubble-system foreq-8487bf9bbf-847vj 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-k48wn 1/1 Running 0 6m7s + hubble-system hashboard-66f957cfdf-pddx7 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-5mhjp 1/1 Running 0 6m6s + hubble-system hutil-7cc6975bb5-jwzr5 1/1 Running 0 6m7s + hubble-system memstore-7d59d65f67-j8lls 1/1 Running 0 6m6s + hubble-system mgmt-54fb5f487d-dj2tz 1/1 Running 0 7m14s + hubble-system mongo-0 2/2 Running 0 6m33s + hubble-system mongo-1 2/2 Running 0 5m47s + hubble-system mongo-2 2/2 Running 0 4m57s + hubble-system mongodb-key-manager-helm-k6294 0/1 Completed 0 7m15s + hubble-system msgbroker-0 1/1 Running 0 7m15s + hubble-system msgbroker-1 1/1 Running 0 6m43s + hubble-system oci-proxy-78cd749dc9-jfs86 1/1 Running 0 6m6s + hubble-system reloader-reloader-55d78d877b-7tnkq 1/1 Running 0 6m6s + hubble-system specman-0 1/1 Running 0 6m2s + hubble-system spectro-tunnel-74d559dd65-hlwch 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-knrfq 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-pb6pr 1/1 Running 0 6m5s + hubble-system spectrocluster-6885954988-xcvk9 1/1 Running 0 6m5s + hubble-system spectrocluster-jobs-7dc76bf6c7-pjc7l 1/1 Running 0 6m5s + hubble-system spectrocluster-reconciler-dcfd55ff5-gnfjg 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-grznt 1/1 Running 0 6m4s + hubble-system spectroclusterop-58966f7f54-jj9m6 1/1 Running 0 6m4s + hubble-system spectrossh-589d975d4d-82vm2 1/1 Running 0 6m4s + hubble-system system-d48fdbc9-ffzq9 1/1 Running 0 6m8s + hubble-system system-d48fdbc9-sztrr 1/1 Running 0 6m8s + hubble-system timeseries-f465b4c99-8h8c7 1/1 Running 0 6m4s + hubble-system timeseries-f465b4c99-jlzlj 1/1 Running 0 6m3s + hubble-system timeseries-f465b4c99-z27d8 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-fgwtp 1/1 Running 0 6m3s + hubble-system user-697c6f8bf-wcqxk 1/1 Running 0 6m3s + ingress-traefik traefik-ingress-controller-5dctd 1/1 Running 0 7m15s + ingress-traefik traefik-ingress-controller-tx6st 1/1 Running 0 7m16s + ingress-traefik traefik-ingress-controller-zf25w 1/1 Running 0 7m16s + jet-system jet-796fc87c5d-vpvtz 1/1 Running 0 4m1s + kube-system aws-node-8xqnx 2/2 Running 0 121m + kube-system aws-node-gtr64 2/2 Running 0 121m + kube-system aws-node-h7pdv 2/2 Running 0 121m + kube-system coredns-566b9b9d-hck47 1/1 Running 0 129m + kube-system coredns-566b9b9d-jpnrs 1/1 Running 0 129m + kube-system ebs-csi-controller-7dfbb6bd58-nwcjl 6/6 Running 0 113m + kube-system ebs-csi-controller-7dfbb6bd58-w8kxz 6/6 Running 0 113m + kube-system ebs-csi-node-9r6fk 3/3 Running 0 113m + kube-system ebs-csi-node-vp744 3/3 Running 0 113m + kube-system ebs-csi-node-xb69v 3/3 Running 0 113m + kube-system kube-proxy-59qgr 1/1 Running 0 121m + kube-system kube-proxy-krrzd 1/1 Running 0 121m + kube-system kube-proxy-lbsgp 1/1 Running 0 121m + ui-system spectro-ui-56749c5f84-98m89 1/1 Running 0 7m15s + ``` + +3. Verify the `hubble` release is deployed. + + ```shell + helm status hubble + ``` + + ```shell title="Example output" hideClipboard + NAME: hubble + LAST DEPLOYED: Thu Jun 18 18:33:18 2026 + NAMESPACE: default + STATUS: deployed + REVISION: 1 + TEST SUITE: None + ``` + + + + \ No newline at end of file diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md index 48c86c9f619..fea19bd6ed9 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md @@ -11,31 +11,13 @@ tags: ["self-hosted", "account", "image pull secret", "hardened images", "securi keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] --- -Beginning in 4.9.b, Spectro Cloud is initiating the shift to security-hardened images. While images have a smaller -attack surface compared to physical and virtual machines, security-hardened images are built to reduce the attack -surface further by containing only the essential runtime components an application needs. They have strict Service Level -Agreements (SLAs) that require the images to be regularly scanned for vulnerabilities, rebuilt, and patched, keeping the -number of CVEs to a minimum. These images also contain artifacts such as Software Bill of Materials (SBOMs) and -cryptographic signatures to verify the image has not been tampered with. - -As a result of this transition, all images hosted in Spectro Cloud's OCI registries must now be authenticated and -retrieved using -[image pull secrets](https://kubernetes.io/docs/concepts/configuration/secret/#using-imagepullsecrets-1). Like -[activation keys](../activate-installation/activate-installation.md), these secrets are obtained from your Spectro Cloud -customer support representative; they are intended for long-term use and only need to be configured once as part of your -initial setup process. If you need to rotate the secret as part of your organization's security policy, contact support -to request a new one. - -Once configured, the secret is distributed to the management plane, PCGs, and all managed workload clusters so they can -pull the required images. - -:::warning - -As of 4.9.b, configuring an image pull secret is optional; however, it will be mandatory in an upcoming release. -Therefore, we recommend configuring your image pull secret as soon as possible to avoid service disruptions. Refer to -the [Announcements](../../release-notes/announcements.md#upcoming-breaking-changes) page for the latest updates. - -::: + ## When to Configure Image Pull Secret @@ -44,29 +26,23 @@ secret. ### Configuration Required -Non-airgapped self-hosted Palette and Palette VerteX environments that pull images directly from Spectro Cloud-owned OCI -registries must configure an image pull secret. This includes environments that _do not_ use -[mirror registries](../system-management/registry-override.md) or -[image swap](../../clusters/cluster-management/image-swap.md) configurations to redirect image pulls to a private -registry. + ### Configuration Not Required -Image pull secrets are managed by Spectro Cloud. While you do not need to configure the pull secret, you must ensure -that the secret propagates to your clusters. This happens automatically unless there are connectivity issues from your -cluster to the Palette or Palette VerteX management plane. - -- **SaaS deployments** — Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action - is needed; for dedicated SaaS customers with access to the system console, consult with your customer support - representative. - -- **Airgapped self-hosted Palette and Palette VerteX environments** - The Spectro Cloud-owned images are pulled directly - from your local registry and do not need the Spectro Cloud's OCI registry pull secret. - -- **Environments with configured mirror registries or image swaps** - If your non-airgapped self-hosted Palette or - Palette VerteX environment pulls all Spectro Cloud-owned images from a custom or private registry through - [mirror registries](../system-management/registry-override.md) or - [image swaps](../../clusters/cluster-management/image-swap.md), you do not need to configure the image pull secret. + ## Configure Image Pull Secret @@ -75,125 +51,64 @@ self-hosted Palette. ### During Installation -You can add your image pull secret when installing self-hosted Palette and Palette VerteX using Helm charts or the -Palette CLI. - -:::info - -Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the -secret [post-installation](#configure-image-pull-secret-post-installation) using the system console. - -::: + #### Helm Chart Installations -For self-hosted Palette or Palette VerteX environments installed on an existing Kubernetes cluster using Helm charts, -you can apply your image pull secret during the installation process. - -| **File** | **Parameter** | -| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| `palette/values.yaml` or `vertex/values.yaml` | [`global.imagePullSecret.dockerConfigJson`](../install-palette/install-on-kubernetes/palette-helm-ref.md#image-pull-secret) | -| `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | - -For the full installation process, refer to the appropriate -[Palette](../install-palette/install-on-kubernetes/install.md) or -[Palette VerteX](../../vertex/install-palette-vertex/install-on-kubernetes/install.md) installation guide. + #### Palette CLI Installations -[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI; VISH FOR PCG] +[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI] ### Post-Installation -Alternatively, you can configure the image pull secret once Palette is installed. - -:::warning - -Configuring an image pull secret is currently optional. Once it is mandatory, image pull secrets must be added during -the installation process. At that time, the system console method described below will only be used to rotate the image -pull secret if required by your organization's security policy. - -::: + #### Prerequisites -- A self-hosted instance of Palette. - -- Access to the [system console](../system-management/system-management.md#access-the-system-console). - -- An image pull secret provided by Spectro Cloud support. + #### Enablement -1. Log in to the Palette [system console](../system-management/system-management.md#access-the-system-console). - -2. From the left main menu, select **Administration**. - -3. Select the **Hardened Images** tab. - -4. In the **Pull secret** field, paste the image pull secret you received from Spectro Cloud support. - -5. Select **Validate and Save**. - -If the secret is valid, it is saved and distributed to the management plane, workload clusters, and PCGs. If you need to -rotate your image pull secret for any reason, repeat these steps, and paste your new secret into the **Pull secret** -field. + #### Validate - - - - -1. Log in to the Palette system console. - -2. From the left main menu, select **Administration**. - -3. Select the **Hardened Images** tab. - -4. Verify that the **Pull secret** field displays a masked secret. - - ![Configuring an image pull secret in the system console](/configure-image-pull-secret_palette.webp) - - - - - -1. Open a terminal session in an environment that has network access to the cluster. Set the `KUBECONFIG` environment - variable to the file path of your cluster's kubeconfig that Palette is installed on. - - ```shell - export KUBECONFIG= - ``` - -2. Issue the following command to verify the secret propagated to your management cluster matches the one configured in - the system console. - - ```shell - kubectl get secret spectro-image-pull-secret --namespace hubble-system --output yaml - ``` - - ```yaml title="Example output" hideClipboard {3} - apiVersion: v1 - data: - .dockerconfigjson: abcdEFGhiJKlmnOPQrSTUVwX... # output omitted for brevity - kind: Secret - metadata: - annotations: - meta.helm.sh/release-name: hubble - meta.helm.sh/release-namespace: default - creationTimestamp: "2026-06-18T22:33:37Z" - labels: - app: spectro - app.kubernetes.io/managed-by: Helm - module: hubble - name: spectro-image-pull-secret - namespace: hubble-system - resourceVersion: "28192" - uid: c7991fac-2ec0-4419-b451-10c82208f8e5 - type: kubernetes.io/dockerconfigjson - ``` - - - - + diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md index 78d4b60bd27..1e93685896a 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/airgap-install/install.md @@ -9,886 +9,121 @@ tags: ["self-hosted", "enterprise", "airgap"] keywords: ["self-hosted", "enterprise"] --- -You can use the Palette Helm Chart to install Palette in a multi-node Kubernetes cluster in your airgap production +You can use the Palette Helm chart to install Palette in a multi-node Kubernetes cluster in your airgap production environment. This installation method is common in secure environments with restricted network access that prohibits using Palette SaaS. Review our [architecture diagrams](../../../../architecture/networking-ports.md) to ensure your Kubernetes cluster has the necessary network connectivity for self-hosted Palette to operate successfully. -:::warning - -Complete the [Environment Setup](./kubernetes-airgap-instructions.md) steps before proceeding with the installation. - -::: - ## Prerequisites -- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed and available. - -- [Helm](https://helm.sh/docs/intro/install/) is installed and available. - -- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using - `kubectl` commands and have sufficient permissions to install Palette. We recommend using a role with `cluster-admin` - permissions to install Palette. - -- Ensure `unzip` or a similar extraction utility is installed on your system. - -- The Kubernetes cluster must be set up on a supported version of Kubernetes. Refer to the - [Kubernetes Requirements](../../install-palette.md#kubernetes-requirements) section to find the version required for - your Palette installation. - -- Ensure the Kubernetes cluster does not have Cert Manager installed. Palette requires a unique Cert Manager - configuration to be installed as part of the installation process. If Cert Manager is already installed, you must - uninstall it before installing Palette. - -- Palette requires a Container Storage Interface (CSI) to create Persistent Volumes, which are used to store persistent - data. You may install any CSI that is compatible with your Kubernetes cluster. - -- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named - `hubble` with the permission `readWriteAnyDatabase`. Refer to the - [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a - database user in Atlas. - -- We recommended the following resources for Palette. Refer to the - [Palette size guidelines](../../install-palette.md#size-guidelines) for additional sizing information. - - - 8 CPUs per node. - - - 16 GB Memory per node. - - - 110 GB Disk Space per node. - - - A minimum of three worker nodes or three untainted control plane nodes. - - - AMD64 (also known as x86_64) architecture. ARM-based nodes are not supported. - -- The following network ports must be accessible for Palette to operate successfully. - - - TCP/443: Inbound and outbound to and from the Palette management cluster. - - - TCP/6443: Outbound traffic from the Palette management cluster to the deployed clusters' Kubernetes API server. - -- Ensure you have an SSL certificate that matches the domain name you will assign to Palette. You will need this to - enable HTTPS encryption for Palette. Reach out to your network administrator or security team to obtain the SSL - certificate. You need the following files: - - - x509 SSL certificate file in the base64 format. - - - x509 SSL certificate key file in the base64 format. - - - x509 SSL certificate authority file in the base64 format. - -- A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the - annotation `storageclass.kubernetes.io/is-default-class` set to `true`. To override the default StorageClass for a - workload, modify the `storageClass` parameter. Check out the - [Change the default StorageClass](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/) - page to learn more about modifying StorageClasses. - -- Palette uses Traefik as the ingress controller. If you already have an ingress controller deployed in the cluster, set - the `ingress.enabled` parameter to `false` in the `values.yaml` file. - -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS - encryption for Palette. - -- If you are installing Palette behind a network proxy server, ensure you have the Certificate Authority (CA) - certificate file in the base64 format. You will need this to enable Palette to communicate with the network proxy - server. - -- Access to the Palette Helm Charts. Refer to the [Access Palette](../../../enterprise-version.md#access-palette) for - instructions on how to request access to the Helm Chart. - :::warning -Do not use a Palette-managed Kubernetes cluster when installing Palette. Palette-managed clusters contain the Palette -agent and Palette-created Kubernetes resources that will interfere with the installation. - -::: - -## Install Palette - -The following instructions are agnostic to the Kubernetes distribution you are using. Depending on the underlying -infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your -environment. Reach out to our support team if you need assistance. - -1. Open a terminal session and navigate to the directory where you downloaded the Palette install ZIP file provided by - our support team. Unzip the file to a directory named `palette-install`. - - ```shell - unzip charts.zip -d palette-install - ``` - -2. Navigate to the `palette-install` directory. - - ```shell - cd palette-install - ``` - -3. Open the file **extras/cert-manager/values.yaml** in a text editor and append the URL to your OCI registry, which - also includes the namespace or project that is hosting the Spectro Cloud images. The URL should be in the format - `/`. In the example configuration below, the value `my-oci-registry.com/spectro-images` is - prefixed to each URL. Save the file after you have appended the URL. - - ```yaml hideClipboard - image: - cainjectorImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" - ``` - -4. Install Cert-Manager using the following command. - - ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "cert-manager" does not exist. Installing it now. - NAME: cert-manager - LAST DEPLOYED: Wed Jun 17 12:54:27 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -5. Open the file **extras/image-swap/values.yaml** in a text editor and append the URL to your OCI registry that also - includes the namespace or project that is hosting the Spectro Cloud images. - - ```yaml hideClipboard - config: - imageSwapImages: - imageSwapInitImage: "my-oci-registry.com/spectro-images/gcr.io/spectro-images-public/release/thewebroot/imageswap-init:v1.5.3-spectro-4.5.1" - imageSwapImage: "my-oci-registry.com/spectro-images/gcr.io/spectro-images-public/release/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - ``` - -6. Update the `ociImageRegistry` section with the proper configuration values to your OCI registry. The - `ociImageRegistry` section should look similar to the following example. - - :::info - - Include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - - ```yaml hideClipboard - ociImageRegistry: - endpoint: "my-oci-registry.com" - name: "Airgap Images OCI" - password: "" - username: "" - baseContentPath: "spectro-images" - insecureSkipVerify: true - caCert: "" - mirrorRegistries: "docker.io::my-oci-registry.com/spectro-images/docker.io,gcr.io::my-oci-registry.com/spectro-images/gcr.io,ghcr.io::my-oci-registry.com/spectro-images/ghcr.io,k8s.gcr.io::my-oci-registry.com/spectro-images/k8s.gcr.io,registry.k8s.io::my-oci-registry.com/spectro-images/registry.k8s.io,quay.io::my-oci-registry.com/spectro-images/quay.io,us-docker.pkg.dev::my-oci-registry.com/spectro-images/us-docker.pkg.dev" - ``` - -7. Go ahead and install the image-swap chart using the following command. Point to the **values.yaml** file you - configured in steps five through six. - - ```shell - helm upgrade --values extras/image-swap/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - ```shell hideClipboard - Release "image-swap" does not exist. Installing it now. - NAME: image-swap - LAST DEPLOYED: Mon Jan 29 17:04:23 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - :::tip - - If you need to override the image-swap registry configuration post-deployment, refer to the - [Override Registry Configuration](../../../system-management/registry-override.md) page for instructions. - - ::: - -8. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by - Palette, including Traefik CRDs, and must be installed before the main Palette Helm chart. - - ```shell - helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz - ``` - - ```shell hideClipboard title="Example output" - Release "spectro-mgmt-crds" does not exist. Installing it now. - NAME: spectro-mgmt-crds - LAST DEPLOYED: Mon Jan 29 16:35:00 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -9. Open the **values.yaml** file in the **spectro-mgmt-plane** folder with a text editor of your choice. The - **values.yaml** file contains the default values for the Palette installation parameters. However, you must populate - the following parameters before installing Palette. You can learn more about the parameters on the **values.yaml** - file on the [Helm Configuration Reference](../palette-helm-ref.md) page. - - Ensure you provide the proper `ociImageRegistry.mirrorRegistries` values if you are using a self-hosted OCI - registry. You can find the placeholder string in the `ociImageRegistry` section of the **values.yaml** file. - - | **Parameter** | **Description** | **Type** | - | ----------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `config.installationMode` | The installation mode for Palette. The values can be `connected` or `airgap`. Set this value to `airgap`. | string | - | `ociPackEcrRegistry` | The OCI registry credentials for the Palette FIPS packs repository. | object | - | `ociImageRegistry` | The OCI registry credentials for the Palette images repository. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in [image swap format](https://github.com/phenixblue/imageswap-webhook/blob/master/docs/configuration.md) to use for pulling images. For example: `docker.io::harbor.example.org/airgap-images/docker.io,gcr.io::harbor.example.org/airgap-images/gcr.io`.

    **NOTE:** Include `/v2` in your endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. | string | - | `imageSwapImages` | The image swap configuration for Palette. If you are using an OCI registry, such as Harbor, replace the prefix URLs with your OCI registry URL that includes the image namespace or project: `/`. | object | - | `imageSwapConfig.isEKSCluster` | If you are NOT installing Palette on an EKS cluster, set this value to `false`. | boolean | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reach-system` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters for Palette to use a network proxy in your environment. | object | - - :::info - - If you are installing Palette by pulling required images from a private mirror registry, you will need to provide - the credentials to your registry in the **values.yaml** file. For more information, refer to - [Helm Configuration Reference](../palette-helm-ref.md#image-pull-secret). - - ::: - - Save the **values.yaml** file after you have populated the required parameters mentioned in the table. Select one of - the following tabs to review an example of the **values.yaml** file with the required parameters highlighted. - - - - - - - ```yaml {30,60,75-82,94-102,118-120} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - create: false - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo,mongo-1.mongo,mongo-2.mongo" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "airgap" #values can be connected or airgap. - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: true - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "palette.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackRegistry: - endpoint: "my-oci-registry.com" # - name: "Airgap Packs OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-packs" # - insecureSkipVerify: false - caCert: "" - - # ociPackEcrRegistry: - # endpoint: "" # - # name: "" # - # accessKey: "" # - # secretKey: "" # - # baseContentPath: "" # - # isPrivate: true - # insecureSkipVerify: false - # caCert: "" - - ociImageRegistry: - endpoint: "my-oci-registry.com" # - name: "Airgap Images OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-images" # - insecureSkipVerify: true - caCert: "" - mirrorRegistries: "docker.io::my-oci-registry.com/spectro-images/docker.io,gcr.io::my-oci-registry.com/spectro-images/gcr.io,ghcr.io::my-oci-registry.com/spectro-images/ghcr.io,k8s.gcr.io::my-oci-registry.com/spectro-images/k8s.gcr.io,registry.k8s.io::my-oci-registry.com/spectro-images/registry.k8s.io,quay.io::my-oci-registry.com/spectro-images/quay.io,us-docker.pkg.dev::my-oci-registry.com/spectro-images/us-docker.pkg.dev" # See instructions below. +- Complete the [Environment Setup](./kubernetes-airgap-instructions.md) steps before proceeding with the installation. - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. +- Do not use a Palette-managed Kubernetes cluster when installing Palette. Palette-managed clusters contain the Palette + agent and Palette-created Kubernetes resources that will interfere with the installation of Palette. +::: - imageSwapImages: - imageSwapInitImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - imageSwapImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - - ingress: - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt : LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - ```yaml {30,60,84-92,94-102,117-119} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - create: false - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo,mongo-1.mongo,mongo-2.mongo" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "airgap" #values can be connected or airgap. - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: true - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "palette.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - # ociPackRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackEcrRegistry: - endpoint: "123456789.dkr.ecr.us-east-1.amazonaws.com" # - name: "Airgap Packs OCI" # - accessKey: "**************" # - secretKey: "**************" # - baseContentPath: "spectro-packs" # - isPrivate: true - insecureSkipVerify: true - caCert: "" - - ociImageRegistry: - endpoint: "public.ecr.aws/123456789" # - name: "Airgap Images OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-images" # - insecureSkipVerify: false - caCert: "" - mirrorRegistries: "docker.io::public.ecr.aws/123456789/spectro-images/docker.io,gcr.io::public.ecr.aws/123456789/spectro-images/gcr.io,ghcr.io::public.ecr.aws/123456789/spectro-images/ghcr.io,k8s.gcr.io::public.ecr.aws/123456789/spectro-images/k8s.gcr.io,registry.k8s.io::public.ecr.aws/123456789/spectro-images/registry.k8s.io,quay.io::public.ecr.aws/123456789/spectro-images/quay.io,us-docker.pkg.dev::public.ecr.aws/123456789/spectro-images/us-docker.pkg.dev" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "public.ecr.aws/123456789/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - imageSwapImage: "public.ecr.aws/123456789/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - - ingress: - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt : LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - :::warning - - Ensure you have configured the `values.yaml` file with the required parameters before proceeding to the next steps. - For the parameter `ociImageRegistry.mirrorRegistries`, include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - -10. This step is only required if you are installing Palette in an environment where a network proxy must be configured - for Palette to access the internet. If you are not using a network proxy, skip to the next step. - - Install the reach-system chart using the following command. Point to the **values.yaml** file you configured in - step 9. - - ```shell - helm upgrade --values palette/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install - ``` - - ```shell hideClipboard - Release "reach-system" does not exist. Installing it now. - NAME: reach-system - LAST DEPLOYED: Mon Jan 29 17:04:23 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - -
    - How to update containerd to use proxy configurations - - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. - - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` - -
    - -11. Install the Palette Helm Chart using the following command. - - ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-*.tgz --install - ``` - - ```shell hideClipboard - Release "hubble" does not exist. Installing it now. - NAME: hubble - LAST DEPLOYED: Mon Jan 29 17:07:51 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -12. Track the installation process using the command below. Palette is ready when the deployments in the namespaces - `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The - installation takes two to three minutes to complete. - - - - ```shell - kubectl get pods --all-namespaces --watch - ``` - - :::tip - - For a more user-friendly experience, use the open source tool [k9s](https://k9scli.io/) to monitor the installation - process. - - ::: - -13. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the - following command to retrieve the load balancer IP address. You may require the assistance of your network - administrator to create the DNS record. - - ```shell - kubectl get service traefik-ingress-controller --namespace ingress-traefik \ - --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' - ``` - - :::warning - - If Palette has only one tenant and you use local accounts with Single Sign-On (SSO) disabled, you can access Palette - using the IP address or any domain name that resolves to that IP. However, once you enable SSO, users must log in - using the tenant-specific subdomain. For example, if you create a tenant named `tenant1` and the domain name you - assigned to Palette is `palette.example.com`, the tenant URL will be `tenant1.palette.example.com`. We recommend you - create an additional wildcard DNS record to map all tenant URLs to the Palette load balancer. For example, - `*.palette.example.com`. - - ::: - -14. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. To access the - system console, open a web browser, paste the custom domain URL in the address bar, and append the value `/system`. - - The first time you visit the Palette system console, a warning message about a not-trusted SSL certificate may - appear. This is expected, as you have not yet uploaded your SSL certificate to Palette. You can ignore this warning - message and proceed. - - ![Screenshot of the Palette system console showing Username and Password fields.](/palette_installation_install-on-vmware_palette-system-console.webp) - -15. Log in to the system console using the following default credentials. Refer to the - [password requirements](../../../system-management/account-management/credentials.md#password-requirements-and-security) - documentation page to learn more about password requirements. +### Kubernetes Cluster - | **Parameter** | **Value** | - | ------------- | --------- | - | Username | `admin` | - | Password | `admin` | + - After login, you will be prompted to create a new password. Enter a new password and save your changes. You will be - redirected to the Palette system console. Use the username `admin` and your new password to log in to the system - console. You can create additional system administrator accounts and assign roles to users in the system console. - Refer to the [Account Management](../../../system-management/account-management/account-management.md) documentation - page for more information. +### Local Environment -16. After login, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a - different SSL certificate, you must upload the SSL certificate, SSL certificate key, and SSL certificate authority - files to Palette. You can upload the files using the Palette system console. Refer to the - [Configure HTTPS Encryption](../../../system-management/ssl-certificate-management.md) page for instructions on how - to upload the SSL certificate files to Palette. + - :::warning +### Other Prerequisites - If you plan to deploy host clusters into different networks, you may require a reverse proxy. Check out the - [Configure Reverse Proxy](../../../system-management/reverse-proxy.md) guide for instructions on how to configure a - reverse proxy for Palette. + - ::: +## Install Palette -You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the -**values.yaml** file, as you may need it for future upgrades. + + +### Cert-Manager Helm Chart + +3. + +### Spectro Management CRDs Helm Chart + +7. + +### Palette Helm Chart + +8. + +### Image Swap Helm Chart + +11. + +### Reach System Helm Chart + +12. + +### Installation + +13. ## Validate -Use the following steps to validate the Palette installation. - -1. Open up a web browser and navigate to the Palette system console. To access the system console, open a web browser, - paste the `env.rootDomain` value you provided in the address bar, and append the value `/system` in the following - format: `/system`. You can also use the IP address of the load balancer. - -2. Log in using the credentials you received from our support team. After login, you will be prompted to create a new - password. Enter a new password and save your changes. You will be redirected to the Palette system console. - -3. Open a terminal session and issue the following command to verify the Palette installation. The command should return - a list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` - namespaces. - - ```shell - kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ - | grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' - ``` - - Your output should look similar to the following. - - ```shell hideClipboard - cp-system spectro-cp-ui-689984f88d-54wsw Running - hubble-system auth-85b748cbf4-6drkn Running - hubble-system auth-85b748cbf4-dwhw2 Running - hubble-system cloud-fb74b8558-lqjq5 Running - hubble-system cloud-fb74b8558-zkfp5 Running - hubble-system configserver-685fcc5b6d-t8f8h Running - hubble-system event-68568f54c7-jzx5t Running - hubble-system event-68568f54c7-w9rnh Running - hubble-system foreq-6b689f54fb-vxjts Running - hubble-system hashboard-897bc9884-pxpvn Running - hubble-system hashboard-897bc9884-rmn69 Running - hubble-system hutil-6d7c478c96-td8q4 Running - hubble-system hutil-6d7c478c96-zjhk4 Running - hubble-system mgmt-85dbf6bf9c-jbggc Running - hubble-system mongo-0 Running - hubble-system mongo-1 Running - hubble-system mongo-2 Running - hubble-system msgbroker-6c9b9fbf8b-mcsn5 Running - hubble-system oci-proxy-7789cf9bd8-qcjkl Running - hubble-system packsync-28205220-bmzcg Succeeded - hubble-system spectrocluster-6c57f5775d-dcm2q Running - hubble-system spectrocluster-6c57f5775d-gmdt2 Running - hubble-system spectrocluster-6c57f5775d-sxks5 Running - hubble-system system-686d77b947-8949z Running - hubble-system system-686d77b947-cgzx6 Running - hubble-system timeseries-7865bc9c56-5q87l Running - hubble-system timeseries-7865bc9c56-scncb Running - hubble-system timeseries-7865bc9c56-sxmgb Running - hubble-system user-5c9f6c6f4b-9dgqz Running - hubble-system user-5c9f6c6f4b-hxkj6 Running - ingress-traefik traefik-ingress-controller-9dmzq Running - ingress-traefik traefik-ingress-controller-tpwtf Running - ingress-traefik traefik-ingress-controller-xz4jf Running - jet-system jet-6599b9856d-t9mr4 Running - ui-system spectro-ui-76ffdf67fb-rkgx8 Running - ``` + ## Next Steps diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md index 0bc92cdb708..453f3ab784a 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md @@ -9,87 +9,10 @@ tags: ["self-hosted", "enterprise"] keywords: ["self-hosted", "enterprise"] --- -You can use the Palette Helm Chart to install Palette in a multi-node Kubernetes cluster in your production environment. +You can use the Palette Helm chart to install Palette in a multi-node Kubernetes cluster in your production environment. ## Prerequisites -- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed and available. - -- [Helm](https://helm.sh/docs/intro/install/) is installed and available. - -- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using - `kubectl` commands and have sufficient permissions to install Palette. We recommend using a role with cluster-admin - permissions to install Palette. - -- Ensure `unzip` or a similar extraction utility is installed on your system. - -- The Kubernetes cluster must be set up on a supported version of Kubernetes. Refer to the - [Kubernetes Requirements](../install-palette.md#kubernetes-requirements) section to find the version required for your - Palette installation. - -- Ensure the Kubernetes cluster does not have Cert Manager installed. Palette requires a unique Cert Manager - configuration to be installed as part of the installation process. If Cert Manager is already installed, you must - uninstall it before installing Palette. - -- Palette requires a Container Storage Interface (CSI) to create Persistent Volumes, which are used to store persistent - data. You may install any CSI that is compatible with your Kubernetes cluster. - -- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named - `hubble` with the permission `readWriteAnyDatabase`. Refer to the - [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a - database user in Atlas. - -- We recommended the following resources for Palette. Refer to the - [Palette size guidelines](../install-palette.md#size-guidelines) for additional sizing information. - - - 8 CPUs per node. - - - 16 GB Memory per node. - - - 110 GB Disk Space per node. - - - A minimum of three worker nodes or three untainted control plane nodes. - - - AMD64 (also known as x86_64) architecture. ARM-based nodes are not supported. - -- The following network ports must be accessible for Palette to operate successfully. - - - TCP/443: Inbound and outbound to and from the Palette management cluster. - - - TCP/6443: Outbound traffic from the Palette management cluster to the deployed clusters' Kubernetes API server. - -- Ensure you have an SSL certificate that matches the domain name you will assign to Palette. You will need this to - enable HTTPS encryption for Palette. Reach out to your network administrator or security team to obtain the SSL - certificate. You need the following files: - - - x509 SSL certificate file in base64 format. - - - x509 SSL certificate key file in base64 format. - - - x509 SSL certificate authority file in base64 format. - -- A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the - annotation `storageclass.kubernetes.io/is-default-class` set to `true`. To override the default StorageClass for a - workload, modify the `storageClass` parameter. Check out the - [Change the default StorageClass](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/) - page to learn more about modifying StorageClasses. - -- Palette uses Traefik as the ingress controller. If you already have an ingress controller deployed in the cluster, set - the `ingress.enabled` parameter to `false` in the `values.yaml` file. - -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS - encryption for Palette. - -- If you are installing Palette behind a network proxy server, ensure you have the Certificate Authority (CA) - certificate file in the base64 format. You will need this to enable Palette to communicate with the network proxy - server. - -- Ensure Palette has access to the required domains and ports. Refer to the - [Required Domains](../install-palette.md#proxy-requirements) section for more information. - -- Access to the Palette Helm Charts. Refer to the [Access Palette](../../enterprise-version.md#access-palette) for - instructions on how to request access to the Helm Chart - :::warning Do not use a Palette-managed Kubernetes cluster when installing Palette. Palette-managed clusters contain the Palette @@ -97,883 +20,109 @@ agent and Palette-created Kubernetes resources that will interfere with the inst ::: -## Install Palette - -The following instructions are written agnostic to the Kubernetes distribution you are using. Depending on the -underlying infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match -your environment. Reach out to our support team if you need assistance. - -1. Open a terminal session and navigate to the directory where you downloaded the Palette install zip file provided by - our support team. Unzip the file to a directory named `palette-install`. - - ```shell - unzip charts.zip -d palette-install - ``` - -2. Navigate to the `palette-install` directory. - - ```shell - cd palette-install - ``` - - ### Cert-Manager Helm Chart - -3. Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. - - ```shell - vim extras/cert-manager/values.yaml - ``` - -4. If you plan to pull images from Spectro Cloud OCI registries, paste the image pull secret received from your - customer support representative into the `imagePullSecret.dockerConfigJson` field. It is not required if you plan to - use mirror registries or image swap. - - Alternately, if you plan to pull images from a private registry that requires authentication, use the base64-encoded - contents of your `config.json` containing the registry credentials. Refer to - [Helm Configuration Reference](./palette-helm-ref.md#image-pull-secret) for more information. - - :::info - - If you omit the image pull secret during installation, you must provide it through the system console. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. - - ::: - - ```yaml title="Example configuration" hideClipboard {5} - imagePullSecret: - # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. - # Pods automatically reference that pull secret when create is true or the secret already exists (PEM-10596). - create: false - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson - ``` - -5. Install the Cert-Manager Helm chart. - - ```shell - helm upgrade --install cert-manager \ - ./extras/cert-manager/cert-manager-*.tgz \ - --namespace cert-manager \ - --create-namespace \ - --values ./extras/cert-manager/values.yaml - ``` - - ```shell hideClipboard title="Example output" - Release "cert-manager" does not exist. Installing it now. - NAME: cert-manager - LAST DEPLOYED: Wed Jun 17 12:54:27 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### Spectro Management CRDs Helm Chart - -6. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by - Palette, including Traefik CRDs, and must be installed before the main Palette Helm chart. When the chart is - installed, the custom resource types are registered with the Kubernetes API server; no pods are deployed. - - ```shell - helm upgrade --install spectro-mgmt-crds \ - extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ - --values extras/spectro-mgmt-crds/values.yaml - ``` - - ```shell hideClipboard title="Example output" - Release "spectro-mgmt-crds" does not exist. Installing it now. - NAME: spectro-mgmt-crds - LAST DEPLOYED: Wed Jun 17 21:17:39 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### Palette Helm Chart - -7. Open the file `palette/values.yaml` using a text editor of your choice. This example uses Vim. - - ```shell - vim palette/values.yaml - ``` - -8. The file `palette/values.yaml` contains the default values for the Palette installation parameters. You must - populate the following parameters before installing Palette. For a complete list of fields and additional - information, refer to [Helm Configuration Reference](./palette-helm-ref.md). - - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from Spectro Cloud OCI registries (without mirror registries or image swap configured) or images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). If you omit the image pull secret during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. | string | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette to use a network proxy in your environment | object | - | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your Palette installation. | string | - - #### Self-Hosted OCI Registries - - The following parameters are required if you pull Palette images from a self-hosted OCI registry instead of a - Spectro Cloud OCI registry or AWS ECR. - - :::tip - - If you would prefer to keep your image swap values in a separate location, you can use the following table to - complete the `extras/image-swap/values.yaml` file instead. - - ```shell - tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ - vim extras/image-swap/values.yaml - ``` - - ::: - - | **Parameter** | **Description** | **Type** | - | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](./palette-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](./palette-helm-ref.md#oci-image-registry) page for examples. | string | - | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | - | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | - - :::info - - Include `/v2` in your mirror registry endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - -9. Save the completed `palette/values.yaml` file. Expand the following sections to review an example of the - `palette/values.yaml` file with the required parameters highlighted. - - - - - - - ```yaml hideClipboard title="Example values.yaml" {60,84-92} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo,mongo-1.mongo,mongo-2.mongo" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "connected" #values can be connected or airgap. - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: true - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "palette.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - # ociPackRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackEcrRegistry: - endpoint: "15789037893.dkr.ecr.us-east-1.amazonaws.com" # - name: "Palette Packs OCI" # - accessKey: "**************" # - secretKey: "**************" # - baseContentPath: "production" # - isPrivate: true - insecureSkipVerify: false - caCert: "" - - # ociImageRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - # mirrorRegistries: "" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" - imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - tunnel: - preferredServer: - endpoint: "" - servers: - - endpoint: "" - ingress: - msgbroker: - proxyBodySize: "15m" # Default proxy body size for msgbroker ingress - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false +### Kubernetes Cluster - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} + - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID +### Local Environment - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` + - +- An image pull secret from Spectro Cloud customer support, required to pull images from Spectro Cloud OCI registries. + This is not required if you plan to use [mirror registries](../../system-management/registry-override.md) or + [image swap](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to + [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) + for more information. - +### Other Prerequisites - ```yaml hideClipboard title="Example values.yaml" {61,76-83,95-103} - ######################### - # Spectro Cloud Palette # - ######################### + - global: - imagePullSecret: - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo,mongo-1.mongo,mongo-2.mongo" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "connected" #values can be connected or airgap. - isPaletteBaseCluster: false - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: true - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "palette.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackRegistry: - endpoint: "example.harbor.org" # - name: "Palette Packs OCI" # - password: "**************" # - username: "**************" # - baseContentPath: "spectro-packs" # - insecureSkipVerify: false - caCert: "" - - # ociPackEcrRegistry: - # endpoint: "" # - # name: "" # - # accessKey: "" # - # secretKey: "" # - # baseContentPath: "" # - # isPrivate: true - # insecureSkipVerify: false - # caCert: "" - - ociImageRegistry: - endpoint: "" # - name: "" # - password: "" # - username: "" # - baseContentPath: "" # - insecureSkipVerify: false - caCert: "" - mirrorRegistries: "" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" - imageSwapImage: "us-docker.pkg.dev/palette-images/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - tunnel: - preferredServer: - endpoint: "" - servers: - - endpoint: "" - ingress: - msgbroker: - proxyBodySize: "15m" # Default proxy body size for msgbroker ingress - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - ### Image Swap Helm Chart - -10. (Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap - Helm chart. Image Swap rewrites pod image references to pull from your mirror registry. Palette ignores the - `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on - whether you added your image swap values to `palette/values.yaml` or `extras/image-swap/values.yaml`. - - - - - - ```shell - helm upgrade --values palette/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - - - - - ```shell - helm upgrade --values extras/image-swap/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - - - - - ```shell hideClipboard title="Example output" - Release "image-swap" does not exist. Installing it now. - NAME: image-swap - LAST DEPLOYED: Wed Jun 17 14:44:13 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### Reach System Helm Chart - -11. (Proxy environments only) If you are installing Palette VerteX in an environment where a network proxy must be - configured for VerteX to access the internet, install the Reach System chart using the following command. Ensure you - set `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `vertex/values.yaml`. - - ```shell - helm upgrade --values vertex/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "reach-system" does not exist. Installing it now. - NAME: reach-system - LAST DEPLOYED: Fri Jan 30 18:40:57 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - - -
    - - Update containerd to use proxy configurations - - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. - - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` - -
    - - - - ### Installation - -12. Install the Palette Helm Chart using the following command. - - ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "hubble" does not exist. Installing it now. - NAME: hubble - LAST DEPLOYED: Wed Jun 17 21:41:31 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -13. Track the installation process using the command below. Palette is ready when the deployments in the namespaces - `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The - installation takes between two to three minutes to complete. - - - - ```shell - kubectl get pods --all-namespaces --watch - ``` - - :::tip - - For a more user-friendly experience, use the open source tool [k9s](https://k9scli.io/) to monitor the installation - process. - - ::: - -14. Create a DNS CNAME record that is mapped to the Palette `traefik-ingress-controller` load balancer. You can use the - following command to retrieve the load balancer IP address. You may require the assistance of your network - administrator to create the DNS record. - - ```shell - kubectl get service traefik-ingress-controller --namespace ingress-traefik \ - --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' - ``` - - :::warning - - If Palette has only one tenant and you use local accounts with Single Sign-On (SSO) disabled, you can access Palette - using the IP address or any domain name that resolves to that IP. However, once you enable SSO, users must log in - using the tenant-specific subdomain. For example, if you create a tenant named `tenant1` and the domain name you - assigned to Palette is `palette.example.com`, the tenant URL will be `tenant1.palette.example.com`. We recommend you - create an additional wildcard DNS record to map all tenant URLs to the Palette load balancer. For example, - `*.palette.example.com`. - - ::: - -15. Use the custom domain name or the IP address of the load balancer to visit the Palette system console. Open a web - browser and paste the custom domain URL in the address bar and append the value `/system`. Replace the domain name - in the URL with your custom domain name or the IP address of the load balancer. Alternatively, you can use the load - balancer IP address with the appended value `/system` to access the system console. - - The first time you visit the Palette system console, a warning message about a not trusted SSL certificate may - appear. This is expected, as you have not yet uploaded your SSL certificate to Palette. You can ignore this warning - message and proceed. - - ![Screenshot of the Palette system console showing Username and Password fields.](/palette_installation_install-on-vmware_palette-system-console.webp) - -16. Log in to the system console using the default credentials. Refer to the - [password requirements](../../system-management/account-management/credentials.md#password-requirements-and-security) - documentation page to learn more about password requirements - - | **Parameter** | **Value** | - | ------------- | --------- | - | Username | `admin` | - | Password | `admin` | - - After logging in, you are prompted to create a new password. Enter a new password and save your changes. You will be - redirected to the Palette system console. Use the username `admin` and your new password to log in to the system - console. You can create additional system administrator accounts and assign roles to users in the system console. - Refer to the [Account Management](../../system-management/account-management/account-management.md) documentation - page for more information. - -17. After logging in, a summary page is displayed. Palette is installed with a self-signed SSL certificate. To assign a - different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority - files to Palette. You can upload the files using the Palette system console. Refer to the - [Configure HTTPS Encryption](../../system-management/ssl-certificate-management.md) page for instructions on how to - upload the SSL certificate files to Palette. - - :::warning - - If you plan to deploy host clusters into different networks, you may require a reverse proxy. Check out the - [Configure Reverse Proxy](../../system-management/reverse-proxy.md) guide for instructions on how to configure a - reverse proxy for Palette. - - ::: +## Install Palette -You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the `values.yaml` -file, as you can refer to it for future upgrades. + + +### Cert-Manager Helm Chart + +3. + +### Spectro Management CRDs Helm Chart + +6. + +### Palette Helm Chart + +7. + +### Image Swap Helm Chart + +10. + +### Reach System Helm Chart + +11. + +### Installation + +12. ## Validate -Use the following steps to validate your Palette installation. - - - - - -1. Open up a web browser and navigate to the Palette system console. To access the system console, open a web browser - and paste the `env.rootDomain` value you provided in the address bar and append the value `/system`. You can also use - the IP address of the load balancer. - -2. Log in using the default credentials. After logging in, you are prompted to create a new password. Enter a new - password and save your changes. You are redirected to the Palette system console. - - - - - -1. Open a terminal session with access to the cluster you installed Palette on. - -2. Verify all pods in all namespaces are running. - - ```shell - kubectl get pods --all-namespaces - ``` - - ```shell hideClipboard title="Example output" - NAMESPACE NAME READY STATUS RESTARTS AGE - cert-manager cert-manager-5fb779d887-mz2vb 1/1 Running 0 8m46s - cert-manager cert-manager-cainjector-764f9646d4-7nhpq 1/1 Running 0 8m46s - cert-manager cert-manager-webhook-85b8dbdddd-fkn6z 1/1 Running 0 8m46s - cp-system spectro-cp-ui-5dffbcdc78-gk8st 1/1 Running 0 7m14s - hubble-system auth-7f4c7ff9c-2clwp 1/1 Running 0 6m8s - hubble-system auth-7f4c7ff9c-j84bt 1/1 Running 0 6m7s - hubble-system cloud-8f8467c95-9r8bp 1/1 Running 0 6m7s - hubble-system cloud-8f8467c95-pvcv4 1/1 Running 0 6m8s - hubble-system configserver-5bc8f9fdcb-mbt66 1/1 Running 0 6m8s - hubble-system event-5fbf6b7f44-bmzdk 1/1 Running 0 6m8s - hubble-system event-5fbf6b7f44-cxc58 1/1 Running 0 6m7s - hubble-system event-5fbf6b7f44-zhr9h 1/1 Running 0 6m7s - hubble-system foreq-8487bf9bbf-847vj 1/1 Running 0 6m7s - hubble-system hashboard-66f957cfdf-k48wn 1/1 Running 0 6m7s - hubble-system hashboard-66f957cfdf-pddx7 1/1 Running 0 6m6s - hubble-system hutil-7cc6975bb5-5mhjp 1/1 Running 0 6m6s - hubble-system hutil-7cc6975bb5-jwzr5 1/1 Running 0 6m7s - hubble-system memstore-7d59d65f67-j8lls 1/1 Running 0 6m6s - hubble-system mgmt-54fb5f487d-dj2tz 1/1 Running 0 7m14s - hubble-system mongo-0 2/2 Running 0 6m33s - hubble-system mongo-1 2/2 Running 0 5m47s - hubble-system mongo-2 2/2 Running 0 4m57s - hubble-system mongodb-key-manager-helm-k6294 0/1 Completed 0 7m15s - hubble-system msgbroker-0 1/1 Running 0 7m15s - hubble-system msgbroker-1 1/1 Running 0 6m43s - hubble-system oci-proxy-78cd749dc9-jfs86 1/1 Running 0 6m6s - hubble-system reloader-reloader-55d78d877b-7tnkq 1/1 Running 0 6m6s - hubble-system specman-0 1/1 Running 0 6m2s - hubble-system spectro-tunnel-74d559dd65-hlwch 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-knrfq 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-pb6pr 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-xcvk9 1/1 Running 0 6m5s - hubble-system spectrocluster-jobs-7dc76bf6c7-pjc7l 1/1 Running 0 6m5s - hubble-system spectrocluster-reconciler-dcfd55ff5-gnfjg 1/1 Running 0 6m4s - hubble-system spectroclusterop-58966f7f54-grznt 1/1 Running 0 6m4s - hubble-system spectroclusterop-58966f7f54-jj9m6 1/1 Running 0 6m4s - hubble-system spectrossh-589d975d4d-82vm2 1/1 Running 0 6m4s - hubble-system system-d48fdbc9-ffzq9 1/1 Running 0 6m8s - hubble-system system-d48fdbc9-sztrr 1/1 Running 0 6m8s - hubble-system timeseries-f465b4c99-8h8c7 1/1 Running 0 6m4s - hubble-system timeseries-f465b4c99-jlzlj 1/1 Running 0 6m3s - hubble-system timeseries-f465b4c99-z27d8 1/1 Running 0 6m3s - hubble-system user-697c6f8bf-fgwtp 1/1 Running 0 6m3s - hubble-system user-697c6f8bf-wcqxk 1/1 Running 0 6m3s - ingress-traefik traefik-ingress-controller-5dctd 1/1 Running 0 7m15s - ingress-traefik traefik-ingress-controller-tx6st 1/1 Running 0 7m16s - ingress-traefik traefik-ingress-controller-zf25w 1/1 Running 0 7m16s - jet-system jet-796fc87c5d-vpvtz 1/1 Running 0 4m1s - kube-system aws-node-8xqnx 2/2 Running 0 121m - kube-system aws-node-gtr64 2/2 Running 0 121m - kube-system aws-node-h7pdv 2/2 Running 0 121m - kube-system coredns-566b9b9d-hck47 1/1 Running 0 129m - kube-system coredns-566b9b9d-jpnrs 1/1 Running 0 129m - kube-system ebs-csi-controller-7dfbb6bd58-nwcjl 6/6 Running 0 113m - kube-system ebs-csi-controller-7dfbb6bd58-w8kxz 6/6 Running 0 113m - kube-system ebs-csi-node-9r6fk 3/3 Running 0 113m - kube-system ebs-csi-node-vp744 3/3 Running 0 113m - kube-system ebs-csi-node-xb69v 3/3 Running 0 113m - kube-system kube-proxy-59qgr 1/1 Running 0 121m - kube-system kube-proxy-krrzd 1/1 Running 0 121m - kube-system kube-proxy-lbsgp 1/1 Running 0 121m - ui-system spectro-ui-56749c5f84-98m89 1/1 Running 0 7m15s - ``` - -3. Verify the `hubble` release is deployed. - - ```shell - helm status hubble - ``` - - ```shell title="Example output" hideClipboard - NAME: hubble - LAST DEPLOYED: Thu Jun 18 18:33:18 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - - - + ## Next Steps diff --git a/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md index 9509bbb3d82..6ee7015d3cc 100644 --- a/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md @@ -10,3 +10,105 @@ sidebar_position: 5 tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] keywords: ["self-hosted", "vertex", "image pull secret", "hardened images", "security"] --- + + + +## When to Configure Image Pull Secret + +Depending on how your environment retrieves images, you may or may not need to configure Spectro Cloud's image pull +secret. + +### Configuration Required + + + +### Configuration Not Required + + + +## Configure Image Pull Secret + +Depending on your installation method, you can configure Spectro Cloud's image pull secret during or after installing +self-hosted Palette. + +### During Installation + + + +#### Helm Chart Installations + + + +#### Palette CLI Installations + +[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI] + +### Post-Installation + + + +#### Prerequisites + + + +#### Enablement + + + +#### Validate + + diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md index bdd5705a2f5..e89f159467b 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md @@ -1,6 +1,6 @@ --- sidebar_label: "Install VerteX" -title: "Install VerteX" +title: "Install Airgap Self-Hosted Palette VerteX" description: "Learn how to deploy airgap VerteX to a Kubernetes cluster using a Helm Chart." icon: "" hide_table_of_contents: false @@ -9,935 +9,134 @@ tags: ["vertex", "enterprise"] keywords: ["self-hosted", "vertex"] --- -You can use the Palette VerteX Helm Chart to install VerteX in a multi-node Kubernetes cluster in your airgap production -environment. +You can use the Palette VerteX Helm chart to install Palette VerteX in a multi-node Kubernetes cluster in your +production environment. -This installation method is common in secure environments with restricted network access that prohibits using VerteX -SaaS. Review our [architecture diagrams](../../../../architecture/networking-ports.md) to ensure your Kubernetes cluster -has the necessary network connectivity for VerteX to operate successfully. - -:::warning - -Complete the [Environment Setup](./kubernetes-airgap-instructions.md) steps before proceeding with the installation. - -::: +This installation method is common in secure environments with restricted network access that prohibits using Palette +VerteX SaaS. Review our [architecture diagrams](../../../../architecture/networking-ports.md) to ensure your Kubernetes +cluster has the necessary network connectivity for Palette VerteX to operate successfully. ## Prerequisites -- [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) is installed and available. - -- [Helm](https://helm.sh/docs/intro/install/) is installed and available. - -- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using - `kubectl` commands and have sufficient permissions to install VerteX. We recommend using a role with `cluster-admin` - permissions to install VerteX. - -- Ensure `unzip` or a similar extraction utility is installed on your system. - -- The Kubernetes cluster must be set up on a version of Kubernetes that is compatible to your upgraded version. Refer to - the [Kubernetes Requirements](../../install-palette-vertex.md#kubernetes-requirements) section to find the version - required for your Palette installation. - -- Ensure the Kubernetes cluster does not have Cert Manager installed. VerteX requires a unique Cert Manager - configuration to be installed as part of the installation process. If Cert Manager is already installed, you must - uninstall it before installing VerteX. - -- Palette requires a Container Storage Interface (CSI) to create Persistent Volumes, which are used to store persistent - data. You may install any CSI that is compatible with your Kubernetes cluster. - -- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named - `hubble` with the permission `readWriteAnyDatabase`. Refer to the - [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a - database user in Atlas. - -- We recommended the following resources for VerteX. Refer to the - [VerteX size guidelines](../../../install-palette-vertex/install-palette-vertex.md#size-guidelines) for additional - sizing information. - - - 8 CPUs per node. - - - 16 GB Memory per node. - - - 110 GB Disk Space per node. - - - A minimum of three worker nodes or three untainted control plane nodes. - - - AMD64 (also known as x86_64) architecture. ARM-based nodes are not supported. - -- The following network ports must be accessible for VerteX to operate successfully. - - - TCP/443: Inbound and outbound to and from the VerteX management cluster. - - - TCP/6443: Outbound traffic from the VerteX management cluster to the deployed clusters' Kubernetes API server. - -- Ensure you have an SSL certificate that matches the domain name you will assign to VerteX. You will need this to - enable HTTPS encryption for VerteX. Reach out to your network administrator or security team to obtain the SSL - certificate. You need the following files: - - - x509 SSL certificate file in the base64 format. - - - x509 SSL certificate key file in the base64 format. - - - x509 SSL certificate authority file in the base64 format. - -- Ensure the OS and Kubernetes cluster you are installing VerteX onto is FIPS-compliant. Otherwise, VerteX and its - operations will not be FIPS-compliant. - -- A [StorageClass](https://kubernetes.io/docs/concepts/storage/storage-classes/) to manage persistent storage, with the - annotation `storageclass.kubernetes.io/is-default-class` set to `true`. To override the default StorageClass for a - workload, modify the `storageClass` parameter. Check out the - [Change the default StorageClass](https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/) - page to learn more about modifying StorageClasses. - -- Palette VerteX uses Traefik as the ingress controller. If you already have an ingress controller deployed in the - cluster, set the `ingress.enabled` parameter to `false` in the `values.yaml` file. - -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS - encryption for VerteX. - -- If you are installing VerteX behind a network proxy server, ensure you have the Certificate Authority (CA) certificate - file in the base64 format. You will need this to enable VerteX to communicate with the network proxy server. - -- Access to the VerteX Helm Charts. Refer to the [Access VerteX](../../../vertex.md#access-palette-vertex) for - instructions on how to request access to the Helm Chart. - :::warning -Do not use a VerteX-managed Kubernetes cluster when installing VerteX. VerteX-managed clusters contain the VerteX agent -and VerteX-created Kubernetes resources that will interfere with the installation. - -::: - -## Install VerteX - -The following instructions are agnostic to the Kubernetes distribution you are using. Depending on the underlying -infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match your -environment. Reach out to our support team if you need assistance. - -1. Open a terminal session and navigate to the directory where you downloaded the Palette VerteX install ZIP file - provided by our support team. Unzip the file to a directory named `vertex-install`. - - ```shell - unzip charts.zip -d vertex-install - ``` - -2. Navigate to the `vertex-install` directory. - - ```shell - cd vertex-install - ``` - -3. Open the file `extras/cert-manager/values.yaml` with a text editor of your choice. This example uses Vim. - - ```shell - vim extras/cert-manager/values.yaml - ``` - -4. Append `` to each image, along with the `` where you want to store your images. - - ```yaml {2-5} hideClipboard title="Example output" - image: - cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` - - In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. - - ```yaml {2-5} hideClipboard title="Example output" - image: - cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` +- Complete the [Environment Setup](./kubernetes-airgap-instructions.md) steps before proceeding with the installation. -5. Install Cert-Manager using the following command. +- Do not use a VerteX-managed Kubernetes cluster when installing VerteX. VerteX-managed clusters contain the VerteX + agent and VerteX-created Kubernetes resources that will interfere with the installation of VerteX. - ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "cert-manager" does not exist. Installing it now. - NAME: cert-manager - LAST DEPLOYED: Wed Jun 17 12:54:27 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -6. Extract the image-swap TGZ file. - - ```shell - tar -xvzf extras/image-swap/image-swap-*.tgz -C extras/image-swap - ``` - -7. Open the file `extras/image-swap/image-swap/values.yaml` with a text editor of your choice. This example uses Vim. - - ```shell - vim extras/image-swap/image-swap/values.yaml - ``` - -8. Append the values you used for `` and `` used in step 4 to each image. - - ```yaml hideClipboard - config: - imageSwapImages: - imageSwapInitImage: "//us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" - imageSwapImage: "//us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" - ``` - -9. (Non-EKS clusters only) If you are not installing Palette VerteX on an EKS cluster, set `isEKSCluster` to `false`. - - ```yaml - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - ``` - -10. Update the `ociImageRegistry` section with the proper configuration values for your OCI registry. Use the same - `` and `` values used in steps 4 and 8. - - ```yaml hideClipboard - ociImageRegistry: - endpoint: "" - name: "Airgap Images OCI" - password: "" - username: "" - baseContentPath: "" - insecureSkipVerify: true - caCert: "" - mirrorRegistries: "docker.io::/repository/docker.io,gcr.io:://gcr.io,ghcr.io:://ghcr.io,k8s.gcr.io:://k8s.gcr.io,registry.k8s.io:://registry.k8s.io,quay.io:://quay.io,us-docker.pkg.dev:://us-docker.pkg.dev" - ``` - - :::info - - Include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::/v2//docker.io`. - - ::: - -11. Install the image-swap Helm chart using the following command. - - ```shell - helm upgrade --values extras/image-swap/image-swap/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "image-swap" does not exist. Installing it now. - NAME: image-swap - LAST DEPLOYED: Mon Jan 29 17:04:23 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - :::tip - - If you need to override the image-swap registry configuration post-deployment, refer to the - [Override Registry Configuration](../../../system-management/registry-override.md) page for instructions. - - ::: - -12. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by - VerteX, including Traefik CRDs, and must be installed before the main VerteX Helm Chart. - - ```shell - helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz - ``` - - ```shell hideClipboard title="Example output" - Release "spectro-mgmt-crds" does not exist. Installing it now. - NAME: spectro-mgmt-crds - LAST DEPLOYED: Mon Jan 29 16:35:00 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -13. Open the file `vertex/values.yaml` using a text editor of your choice. This example uses Vim. - - ```shell - vim vertex/values.yaml - ``` - -14. Open the **values.yaml** file in the **spectro-mgmt-plane** folder with a text editor of your choice. The - **values.yaml** file contains the default values for the VerteX installation parameters. However, you must populate - the following parameters before installing VerteX. You can learn more about the parameters on the **values.yaml** - file on the [Helm Configuration Reference](../vertex-helm-ref.md) page. - - Ensure you provide the proper `ociImageRegistry.mirrorRegistries` values if you are using a self-hosted OCI - registry. You can find the placeholder string in the `ociImageRegistry` section of the **values.yaml** file. - - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `global.imagePullSecret.dockerConfigJson` | The base64-encoded contents of your `config.json` containing your registry credentials. Refer to [Helm Configuration Reference](../vertex-helm-ref.md#image-pull-secret) for more information. | string | - | `env.rootDomain` | The URL name or IP address you will use for the VerteX installation. | string | - | `config.installationMode` | The installation mode for VerteX. The values can be `connected` or `airgap`. Set this value to `airgap`. | string | - | `ociPackEcrRegistry` | The OCI registry credentials for the VerteX FIPS packs repository. | object | - | `ociImageRegistry` | The OCI registry credentials for the VerteX images repository. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in [image swap format](https://github.com/phenixblue/imageswap-webhook/blob/master/docs/configuration.md) to use for pulling images. For example: `docker.io::harbor.example.org/airgap-images/docker.io,gcr.io::harbor.example.org/airgap-images/gcr.io`.

    **NOTE:** Include `/v2` in your endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. | string | - | `imageSwapImages` | The image swap configuration for VerteX. If you are using an OCI registry, such as Harbor. Replace the prefix URLs with your OCI registry URL that includes the image namespace or project: `/`. | object | - | `imageSwapConfig.isEKSCluster` | If you are NOT installing VerteX on an EKS cluster, set this value to `false`. | boolean | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reach-system` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters for VerteX to use a network proxy in your environment. | object | - - :::info - - If you are installing VerteX by pulling required images from a private mirror registry, you will need to provide the - credentials to your registry in the **values.yaml** file. For more information, refer to - [Helm Configuration Reference](../vertex-helm-ref.md#image-pull-secret). - - ::: - - Save the **values.yaml** file after you have populated the required parameters mentioned in the table. - - :::warning - - VerteX VerteX does not support insecure connections. Ensure you have the Certificate Authority (CA) available, in - PEM format, when using a custom packs and image registry. Otherwise, VerteX will not be able to pull packs and - images from the registry. Use the `caCert` parameter to provide the base64-encoded CA certificate. - - ::: - - Select one of the following tabs to review an example of the **values.yaml** file with the required parameters - highlighted. - - - - - - - ```yaml {30,60,75-82,94-102,117-119} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - create: false - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "airgap" #values can be connected or airgap. - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: false - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackRegistry: - endpoint: "my-oci-registry.com" # - name: "Airgap Packs OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-packs" # - insecureSkipVerify: false - caCert: "" - - # ociPackEcrRegistry: - # endpoint: "" # - # name: "" # - # accessKey: "" # - # secretKey: "" # - # baseContentPath: "" # - # isPrivate: true - # insecureSkipVerify: false - # caCert: "" - - ociImageRegistry: - endpoint: "my-oci-registry.com" # - name: "Airgap Images OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-images" # - insecureSkipVerify: true - caCert: "" - mirrorRegistries: "docker.io::my-oci-registry.com/spectro-images/docker.io,gcr.io::my-oci-registry.com/spectro-images/gcr.io,ghcr.io::my-oci-registry.com/spectro-images/ghcr.io,k8s.gcr.io::my-oci-registry.com/spectro-images/k8s.gcr.io,registry.k8s.io::my-oci-registry.com/spectro-images/registry.k8s.io,quay.io::my-oci-registry.com/spectro-images/quay.io,us-docker.pkg.dev::my-oci-registry.com/spectro-images/us-docker.pkg.dev" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - imageSwapImage: "my-oci-registry.com/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - - ingress: - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt : LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - ```yaml {30,60,84-92,94-102,117-119} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - create: false - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "" - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "airgap" #values can be connected or airgap. - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: false - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the traefik-ingress-controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.internal == false - # - Optional if ingress.internal == true (leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.example.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - # ociPackRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackEcrRegistry: - endpoint: "123456789.dkr.ecr.us-east-1.amazonaws.com" # - name: "Airgap Packs OCI" # - accessKey: "**************" # - secretKey: "**************" # - baseContentPath: "production-fips" # - isPrivate: true - insecureSkipVerify: true - caCert: "" - - ociImageRegistry: - endpoint: "public.ecr.aws/123456789" # - name: "Airgap Images OCI" # - password: "" # - username: "" # - baseContentPath: "spectro-images" # - insecureSkipVerify: false - caCert: "" - mirrorRegistries: "docker.io::public.ecr.aws/123456789/spectro-images/docker.io,gcr.io::public.ecr.aws/123456789/spectro-images/gcr.io,ghcr.io::public.ecr.aws/123456789/spectro-images/ghcr.io,k8s.gcr.io::public.ecr.aws/123456789/spectro-images/k8s.gcr.io,registry.k8s.io::public.ecr.aws/123456789/spectro-images/registry.k8s.io,quay.io::public.ecr.aws/123456789/spectro-images/quay.io,us-docker.pkg.dev::public.ecr.aws/123456789/spectro-images/us-docker.pkg.dev" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "public.ecr.aws/123456789/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - imageSwapImage: "public.ecr.aws/123456789/us-docker.pkg.dev/palette-images-fips/palette/thewebroot/imageswap:v1.5.3-spectro-4.5.1" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - - ingress: - # When enabled, the Traefik ingress controller is installed. - enabled: true - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert is generated. - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURqekNDQW5lZ0F3SUJBZ0lVZTVMdXBBZGljd0Z1SFJpWWMyWEgzNTFEUzJJd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk1qY3hNREV6TVRNeU5ERXlXakI3TVFzd0NRWURWUVFHRXdKVlV6RUxNQWtHCkExVUVDQk1DUTBFeEV6QVJCZ05WQkFjVENsTmhiblJoUTJ4aGNtRXhGVEFUQmdOVkJBb1RERk53WldOMGNtOUQKYkc5MVpERUxNQWtHQTFVRUN4TUNTVlF4SmpBa0JnTlZCQU1USFhCeWIzaDVMbk5oYlhCc1pTNXpjR1ZqZEhKdgpZMnh2ZFdRdVkyOXRNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXd5bEt3MmlxClBXM2JrQU0wV3RhaEFLbEppcWFHd05LUDVRRTZ6ZW5NM2FURko3TjIwN0dWcUNGYzJHTDNodmNhTDFranZjeEkKK2lybHpkbm9hcVhUSmV3ZkJiTGs2SGVhZmdXUVp3NHNNeE5QRUVYYlNXYm54Mm03Y2FlbVJiUWZSQWhPWXRvWgpIWG1IMzQ1Q25mNjF0RnhMeEEzb0JRNm1yb0JMVXNOOUh2WWFzeGE5QUFmZUNNZm5sYWVBWE9CVmROalJTN1VzCkN5NmlSRXpEWFgvem1nOG5WWFUwemlrcXdoS3pqSlBJd2FQa2ViaXVSdUJYdEZ0VlQwQmFzS3VqbURzd0lsRFQKVmR4SHRRQUVyUmM4Q2Nhb20yUkpZbTd1aHNEYlo2WVFzS3JiMmhIbU5rNENVWUd5eUJPZnBwbzR2bFd1S2FEcgpsVFNYUXlPN0M0ejM1d0lEQVFBQm8xNHdYREJhQmdOVkhSRUVVekJSZ2dsc2IyTmhiR2h2YzNTSEJIOEFBQUdDCkhYQnliM2g1TG5OaGJYQnNaUzV6Y0dWamRISnZZMnh2ZFdRdVkyOXRnaDhxTG5CeWIzaDVMbk5oYlhCc1pTNXoKY0dWamRISnZZMnh2ZFdRdVkyOXRNQTBHQ1NxR1NJYjNEUUVCQ3dVQUE0SUJBUUEvRFJFVm54SWJRdi9uMDEvSQpJd1d0ekhKNGNHOUp6UlB6dmszNUcvRGJOVzZYZ0M3djBoWlFIVHg5bzMrckxoSUFiWTNmbjc1VEtlN3hMRWpiCkI3M3pGWURJSStkYzM5NkQzZU51M2NxRGIvY01kYmlFalhod2ttZk9NRm9qMnpOdHJIdzFsSjA0QlNFMWw1YWgKMDk0Vy9aaEQ2YTVLU3B0cDh1YUpKVmNrejRYMEdRWjVPYjZadGdxZVVxNytqWVZOZ0tLQzJCMW1SNjMyMDNsZwozVFZmZEkrdmI3b292dVdOOFRBVG9qdXNuS25WMmRMeTFBOWViWXYwMEM3WWZ6Q0NhODgrN2dzTGhJaUJjRHBPClJkWjU3QStKanJmSU5IYy9vNm5YWFhDZ2h2YkFwUVk1QnFnMWIzYUpUZERNWThUY0hoQVVaQzB5eU04bXcwMnQKWHRRQwotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFb3dJQkFBS0NBUUVBd3lsS3cyaXFQVzNia0FNMFd0YWhBS2xKaXFhR3dOS1A1UUU2emVuTTNhVEZKN04yCjA3R1ZxQ0ZjMkdMM2h2Y2FMMWtqdmN4SStpcmx6ZG5vYXFYVEpld2ZCYkxrNkhlYWZnV1FadzRzTXhOUEVFWGIKU1dibngybTdjYWVtUmJRZlJBaE9ZdG9aSFhtSDM0NUNuZjYxdEZ4THhBM29CUTZtcm9CTFVzTjlIdllhc3hhOQpBQWZlQ01mbmxhZUFYT0JWZE5qUlM3VXNDeTZpUkV6RFhYL3ptZzhuVlhVMHppa3F3aEt6akpQSXdhUGtlYml1ClJ1Qlh0RnRWVDBCYXNLdWptRHN3SWxEVFZkeEh0UUFFclJjOENjYW9tMlJKWW03dWhzRGJaNllRc0tyYjJoSG0KTms0Q1VZR3l5Qk9mcHBvNHZsV3VLYURybFRTWFF5TzdDNHozNXdJREFRQUJBb0lCQUFPVVZFeTFOTG9mczdFMgpmZFZVcm10R3I1U2RiVWRJRlYrTDREbzZtWWxQSmxhT0VoWGI0ZlROZDloNEtEWVBmaWwwSnhXcUU0U1RHTmZuCnNUMlRnUVhuQ01LZi8xYk1Lc2M0N3VjVStYYU9XaHJnVFI5UmhkckFjN0duODRLL3hQc0ljL2VZTEhHLzh1QUUKeWUvLzVmRkM2QmpXY0hUM1NkTlZnd3duamJudG5XTXIzTFJBVnJBamZBckxveWUwS0F2YytYdXJLTEVCcmMyVQpjaHlDbitZemJKN0VlSG44UXdQNGdBNXVSK0NCMFJPeFErYXIzS3M5YUhkZTQ1OEVNNEtLMnpUOXA4RWZRc1lFCkFtNUpxWjliR0JEVHV1dEkyNm9GK0pLQ1IzZzhXNERRcHVYRUZoVjlya0pMSm13RDhQb0JaclF6UzZvdmJhdkkKRk42QVM4RUNnWUVBOEcxQzFxZVh4dTQ4aEYxak5MTCswRmxkeWdFem9SMmFoRGJCai8weUZkQVVjU2pYTzk0NAozN1dORTBUUG10WG1Vc3NZTlBTR21XaWI2OUhicEFoMTY3SWVwNE9LaVlZdkozYm1oUC9WNzFvK3M0SWJlSHh1CkVJbWVVckFOZWRoQURVQnZ4c1lXRWxlVlVJSFFRcjY1VHM2ZjIrWkpTKzg4TU05bUorL3BmcmNDZ1lFQXo4MXgKR3JiSE5oak56RjhZMjhiK0hMNW5rdDR0SUdkU3hnbW9PMFFJeGkrQVNZTzB0WW42VFk0ZHI5ZXErMzE3b21ZawpMbDNtNENORDhudG1vYzRvWnM4SUpDQ0IrZjNqcTY4OHdoQU9vVHZ4dDhjZVJqOFRhRHl1SHZwS043OVNsVVd2CjBJd2ZRNDNIemd3SWJiSWhjcTRJVGswanI0VHdWbThia283VElGRUNnWUJoNnUzVXhHN0JHeGZVaE1BNW4waSsKREJkeGhPbkZEV3gzdW1FOHhrN1dxV2NaNnhzMWk3eTRCNVhNS2pNdkNUeURyYWxQTCtOOXFTZ1BjK216TmFybwo4aU1mOENmRStMeE5vMVFoQ0p6Vm5YaDUzVnhZeHJ5QXlidU1TNTFCYVh3MHFYQ2NrT0krV0NNOHBaSHZEUVFsCmYydUZ3SlZMY3NTZDBHbjNpL01ab3dLQmdBY1BzUjg2Uk15MnpROTd6OGx3R3FSNVorV2F2U2ZUdXdGVnhLeTIKNUNGdjdja1J1NnRMbEFEY3FtK1dRWTRvTm5KUFREMXpIV3hTWm5XdjhjM2Z4b212MFZRQThzbSs4ZVNjb05EcgpZTVBqMkpQcEpVTTMwMzRBU2Q1dG5PWUdEMVZaTjk4N1U3aWs4Ynd6dG5tYnl2MHRvc1NlWkc4TGNtdE5mVDllCnNSZnhBb0dCQUpTV1lDellyTlRMNnRUSnh5M2FqWm5jZkxrMEV0eWNCd05FRXZHVzVSVE9LOUFYTE96RzN0eHUKajZqWlRpaUFRU09aaVd0clJHU0U0bEkyQ1MvcjNjd3VuSGlnZlovd1dKZldkZ0JpRnZqOTVFbUVQWUZaRDRobQpkT3l5UHhRRXFTRmprQ21BS2plOFBpTDdpU01GbGhBZTZQWFljQlExdCtzd01UeXBnY3RrCi0tLS0tRU5EIFJTQSBQUklWQVRFIEtFWS0tLS0tCg== - ca: - crt : LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURNVENDQWhtZ0F3SUJBZ0lVSHhWK0ljVGZHUElzdW8yY3dqQ0Q0Z2RSTFFRd0RRWUpLb1pJaHZjTkFRRUwKQlFBd0tERW1NQ1FHQTFVRUF3d2RjSEp2ZUhrdWMyRnRjR3hsTG5Od1pXTjBjbTlqYkc5MVpDNWpiMjB3SGhjTgpNakl4TURFME1UTXlOREV5V2hjTk16WXdOakl5TVRNeU5ERXlXakFvTVNZd0pBWURWUVFEREIxd2NtOTRlUzV6CllXMXdiR1V1YzNCbFkzUnliMk5zYjNWa0xtTnZiVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0MKQVFvQ2dnRUJBSy90WXBHVi9HRURUWnZzL25QQ2lOK0U3K1dOQ21GeU1NQjdkazVOT3JzQWZIaVVvZ1JRVUo0WQptSjhwVmYrSzhTRFBsdGNYcW40WVVTbmxiUERsVlBkWU5zOTEwT3RaS1EwNW96aUtGV2pNbS85NHlLSjVyVzNsCndDNEN0ayttUm9Ib0ZQQS81dmFVbVZHdlVadjlGY0JuL0pKN2F4WnRIQk1PRiticXQ0Zmd0ci9YMWdOeWhPVzUKZTVScGpESkozRjJTVnc5NUpBQSt4a3V3UitFSmVseEtnQVpxdDc0ejB4U2ROODZ0QzNtK0wxRGs2WVVlQWEzZApvM3Rsa3ZkeDV6dUJvSmI2QmpZWEV4UE1PbThRcHFNVWRLK3lDZUdrem9XQStDOUtFdGtVaERCWktENStNWXRZCktVMUh1RXJCbmw2Z3BuWTRlbzJjVTRxdkNwZzZ4S3NDQXdFQUFhTlRNRkV3SFFZRFZSME9CQllFRklKMkRkTjgKc2ZtVjRCT1ZFL0FjZ0VEejArNmlNQjhHQTFVZEl3UVlNQmFBRklKMkRkTjhzZm1WNEJPVkUvQWNnRUR6MCs2aQpNQThHQTFVZEV3RUIvd1FGTUFNQkFmOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQWhQVi9RMVl1YWVTOTZVCmhjVGQ4RWdJaHhpbHFiTWlTQm5WaVdrdlJzWk94UUIwNTFScWtwT3g0UTRsckdaOGVJWWc3T0trTTdzejhuTVQKL2pxS21sZDY0MzJCcURCMlNkNVp5ZFdReHAwU1laRTlnVWszYk9KRGtZVXQ4b1cvZDBWeG9uU05LQVN3QmZKaApWV1VZUUlpNm55K0ZZZmtuRFNvRnFlY2Z3SDBQQVUraXpnMkI3KzFkbko5YisyQ21IOUVCallOZ2hoNlFzVlFQCkh2SkdQQURtandPNkJOam5HK0Z3K0Z6cmFXUTNCTjAwb08zUjF6UmgxZERmTTQzR3oxRmZGRW5GSXI5aGFuUnQKWHJFZm8vZWU5bjBLWUFESEJnV1g4dlhuNHZrRmdWRjgwYW9MUUJSQTBxWXErcW1pVlp6YnREeE9ldFEyRWFyTQpyNmVWL0lZPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg== - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - :::warning - - Ensure you configure the `values.yaml` file with the required parameters before proceeding. For the parameter - `ociImageRegistry.mirrorRegistries`, include `/v2` in your endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - -15. This step is only required if you are installing VerteX in an environment where a network proxy must be configured - for VerteX to access the internet. If you are not using a network proxy, skip to the next step. - - Install the reach-system chart using the following command. Point to the **values.yaml** file you configured in - step 9. - - ```shell - helm upgrade --values vertex/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install - ``` - - ```shell hideClipboard - Release "reach-system" does not exist. Installing it now. - NAME: reach-system - LAST DEPLOYED: Mon Jan 29 17:04:23 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - -
    - How to update containerd to use proxy configurations - - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. - - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` - -
    - -16. Install the VerteX Helm Chart using the following command. - - ```shell - helm upgrade --values vertex/values.yaml \ - hubble vertex/spectro-mgmt-plane-*.tgz --install - ``` - - ```shell hideClipboard - Release "hubble" does not exist. Installing it now. - NAME: hubble - LAST DEPLOYED: Mon Jan 29 17:07:51 2024 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -17. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces - `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The - installation takes between two to three minutes to complete. - - - - ```shell - kubectl get pods --all-namespaces --watch - ``` - - :::tip - - For a more user-friendly experience, use the open source tool [k9s](https://k9scli.io/) to monitor the installation - process. - - ::: - -18. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the - following command to retrieve the load balancer IP address. You may require the assistance of your network - administrator to create the DNS record. - - ```shell - kubectl get service traefik-ingress-controller --namespace ingress-traefik \ - --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' - ``` - - :::warning - - If Palette VerteX has only one tenant and you use local accounts with Single Sign-On (SSO) disabled, you can access - Palette VerteX using the IP address or any domain name that resolves to that IP. However, once you enable SSO, users - must log in using the tenant-specific subdomain. For example, if you create a tenant named `tenant1` and the domain - name you assigned to Palette VerteX is `vertex.example.com`, the tenant URL will be `tenant1.vertex.example.com`. We - recommend you create an additional wildcard DNS record to map all tenant URLs to the Palette VerteX load balancer. - For example, `*.vertex.example.com`. - - ::: - -19. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the - system console, open a web browser, paste the custom domain URL in the address bar, and append the value `/system`. - - The first time you visit the VerteX system console, a warning message about a not-trusted SSL certificate may - appear. This is expected, as you have not yet uploaded your SSL certificate to VerteX. You can ignore this warning - message and proceed. - - ![Screenshot of the VerteX system console showing Username and Password fields.](/vertex_install-on-kubernetes_install_system-console.webp) - -20. Log in to the system console using the following default credentials. Refer to the - [password requirements](../../../system-management/account-management/credentials.md#password-requirements-and-security) - documentation page to learn more about password requirements. - - | **Parameter** | **Value** | - | ------------- | --------- | - | Username | `admin` | - | Password | `admin` | - - After login, you will be prompted to create a new password. Enter a new password and save your changes. You will be - redirected to the VerteX system console. Use the username `admin` and your new password to log in to the system - console. You can create additional system administrator accounts and assign roles to users in the system console. - Refer to the [Account Management](../../../system-management/account-management/account-management.md) documentation - page for more information. - -21. After login, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a - different SSL certificate, you must upload the SSL certificate, SSL certificate key, and SSL certificate authority - files to VerteX. You can upload the files using the VerteX system console. Refer to the - [Configure HTTPS Encryption](../../../system-management/ssl-certificate-management.md) page for instructions on how - to upload the SSL certificate files to Palette. - - :::warning - - If you plan to deploy host clusters into different networks, you may require a reverse proxy. Check out the - [Configure Reverse Proxy](../../../system-management/reverse-proxy.md) guide for instructions on how to configure a - reverse proxy for VerteX. - - ::: +::: -You now have a self-hosted instance of VerteX installed in a Kubernetes cluster. Make sure you retain the -**values.yaml** file, as you may need it for future upgrades. +### Kubernetes Cluster + + + +- (FIPS compliance only) The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. + Otherwise, Palette VerteX and its operations will not be FIPS-compliant. + +### Local Environment + + + +### Other Prerequisites + + + +## Install Palette VerteX + + + +### Cert-Manager Helm Chart + +3. + +### Spectro Management CRDs Helm Chart + +7. + +### VerteX Helm Chart + +8. + +### Image Swap Helm Chart + +11. + +### Reach System Helm Chart + +12. + +### Installation + +13. ## Validate -Use the following steps to validate the VerteX installation. - -1. Open up a web browser and navigate to the VerteX system console. To access the system console, open a web browser, - paste the `env.rootDomain` value you provided in the address bar, and append the value `/system` in the following - format: `/system`. You can also use the IP address of the load balancer. - -2. Log in using the credentials you received from our support team. After login, you will be prompted to create a new - password. Enter a new password and save your changes. You will be redirected to the VerteX system console. - -3. Open a terminal session and issue the following command to verify the VerteX installation. The command should return - a list of deployments in the `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` - namespaces. - - ```shell - kubectl get pods --all-namespaces --output custom-columns="NAMESPACE:metadata.namespace,NAME:metadata.name,STATUS:status.phase" \ - | grep --extended-regexp '^(cp-system|hubble-system|ingress-traefik|jet-system|ui-system)\s' - ``` - - Your output should look similar to the following. - - ```shell hideClipboard - cp-system spectro-cp-ui-689984f88d-54wsw Running - hubble-system auth-85b748cbf4-6drkn Running - hubble-system auth-85b748cbf4-dwhw2 Running - hubble-system cloud-fb74b8558-lqjq5 Running - hubble-system cloud-fb74b8558-zkfp5 Running - hubble-system configserver-685fcc5b6d-t8f8h Running - hubble-system event-68568f54c7-jzx5t Running - hubble-system event-68568f54c7-w9rnh Running - hubble-system foreq-6b689f54fb-vxjts Running - hubble-system hashboard-897bc9884-pxpvn Running - hubble-system hashboard-897bc9884-rmn69 Running - hubble-system hutil-6d7c478c96-td8q4 Running - hubble-system hutil-6d7c478c96-zjhk4 Running - hubble-system mgmt-85dbf6bf9c-jbggc Running - hubble-system mongo-0 Running - hubble-system mongo-1 Running - hubble-system mongo-2 Running - hubble-system msgbroker-6c9b9fbf8b-mcsn5 Running - hubble-system oci-proxy-7789cf9bd8-qcjkl Running - hubble-system packsync-28205220-bmzcg Succeeded - hubble-system spectrocluster-6c57f5775d-dcm2q Running - hubble-system spectrocluster-6c57f5775d-gmdt2 Running - hubble-system spectrocluster-6c57f5775d-sxks5 Running - hubble-system system-686d77b947-8949z Running - hubble-system system-686d77b947-cgzx6 Running - hubble-system timeseries-7865bc9c56-5q87l Running - hubble-system timeseries-7865bc9c56-scncb Running - hubble-system timeseries-7865bc9c56-sxmgb Running - hubble-system user-5c9f6c6f4b-9dgqz Running - hubble-system user-5c9f6c6f4b-hxkj6 Running - ingress-traefik traefik-ingress-controller-9dmzq Running - ingress-traefik traefik-ingress-controller-tpwtf Running - ingress-traefik traefik-ingress-controller-xz4jf Running - jet-system jet-6599b9856d-t9mr4 Running - ui-system spectro-ui-76ffdf67fb-rkgx8 Running - ``` + ## Next Steps diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md index 07a37d2b592..beb4389ad35 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md @@ -9,12 +9,12 @@ tags: ["vertex", "enterprise"] keywords: ["self-hosted", "vertex"] --- -You can use the Palette VerteX Helm Chart to install VerteX in a multi-node Kubernetes cluster in your production -environment. +You can use the Palette VerteX Helm chart to install Palette VerteX in a multi-node Kubernetes cluster in your +production environment. -This installation method is common in secure environments with restricted network access that prohibits using VerteX -SaaS. Review our [architecture diagrams](../../../architecture/networking-ports.md) to ensure your Kubernetes cluster -has the necessary network connectivity for VerteX to operate successfully. +This installation method is common in secure environments with restricted network access that prohibits using Palette +VerteX SaaS. Review our [architecture diagrams](../../../architecture/networking-ports.md) to ensure your Kubernetes +cluster has the necessary network connectivity for Palette VerteX to operate successfully. ## Prerequisites @@ -40,937 +40,107 @@ and VerteX-created Kubernetes resources that will interfere with the installatio ### Local Environment -- Access to the target Kubernetes cluster's kubeconfig file. You must be able to interact with the cluster using - `kubectl` commands and have sufficient permissions to install VerteX. We recommend using a role with cluster-admin - permissions to install VerteX. - -- The following software installed and available: - - - [kubectl](https://kubernetes.io/docs/tasks/tools/#kubectl) - - [Helm](https://helm.sh/docs/intro/install/) - -- Ensure `unzip` or a similar extraction utility is installed on your system. - -- Access to the VerteX Helm Charts. Refer to the [Access VerteX](../../vertex.md#access-palette-vertex) for instructions - on how to request access to the Helm Chart. + - An image pull secret from Spectro Cloud customer support, required to pull images from Spectro Cloud OCI registries. This is not required if you plan to use [mirror registries](../../system-management/registry-override.md) or - [image swaps](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to + [image swap](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. ### Other Prerequisites -- If you are using a _self-hosted MongoDB_ instance, such as MongoDB Atlas, ensure the MongoDB database has a user named - `hubble` with the permission `readWriteAnyDatabase`. Refer to the - [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for guidance on how to create a - database user in Atlas. - -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS - encryption for VerteX. - -- (Proxy environments only) If you are installing VerteX behind a network proxy server, ensure VerteX has access to the - required domains and ports. Refer to the [Required Domains](../install-palette-vertex.md#proxy-requirements) section - for more information. - -- (Proxy environments only) If you are installing VerteX behind a network proxy server, ensure you have the Certificate - Authority (CA) certificate file in the base64 format. You will need this to enable VerteX to communicate with the - network proxy server. - -## Install VerteX - -The following instructions are written agnostic to the Kubernetes distribution you are using. Depending on the -underlying infrastructure provider and your Kubernetes distribution, you may need to modify the instructions to match -your environment. Reach out to our support team if you need assistance. - -1. Open a terminal session and navigate to the directory where you downloaded the Palette VerteX install ZIP file - provided by our support team. Unzip the file to a directory named `vertex-install`. - - ```shell - unzip charts.zip -d vertex-install - ``` - -2. Navigate to the `vertex-install` directory. - - ```shell - cd vertex-install - ``` - - ### Cert-Manager Helm Chart - -3. Open the file `extras/cert-manager/values.yaml` using a text editor of your choice. This example uses Vim. - - ```shell - vim extras/cert-manager/values.yaml - ``` - -4. If you plan to pull images from Spectro Cloud OCI registries, paste the image pull secret received from your - customer support representative into the `imagePullSecret.dockerConfigJson` field. It is not required if you plan to - use mirror registries or image swap. - - Alternately, if you plan to pull images from a private registry that requires authentication, use the base64-encoded - contents of your `config.json` containing the registry credentials. Refer to - [Helm Configuration Reference](./vertex-helm-ref.md#image-pull-secret) for more information. - - :::info - - If you omit the image pull secret during installation, you must provide it through the system console. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. - - ::: - - ```yaml title="Example configuration" hideClipboard {5} - imagePullSecret: - # When true, render Secret spectro-image-pull-secret in the cert-manager namespace. - # Pods automatically reference that pull secret when create is true or the secret already exists (PEM-10596). - create: false - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # Used when create is true: base64-encoded dockerconfigjson - ``` - -5. Install the Cert-Manager Helm chart. - - ```shell - helm upgrade --install cert-manager \ - ./extras/cert-manager/cert-manager-*.tgz \ - --namespace cert-manager \ - --create-namespace \ - --values ./extras/cert-manager/values.yaml - ``` - - ```shell hideClipboard title="Example output" - Release "cert-manager" does not exist. Installing it now. - NAME: cert-manager - LAST DEPLOYED: Wed Jun 17 12:54:27 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### Spectro Management CRDs Helm Chart - -6. Install the Spectro Management CRDs chart. This chart contains Custom Resource Definitions (CRDs) required by - Palette VerteX, including Traefik CRDs, and must be installed before the main Palette VerteX Helm chart. When the - chart is installed, the custom resource types are registered with the Kubernetes API server; no pods are deployed. - - ```shell - helm upgrade --install spectro-mgmt-crds \ - extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ - --values extras/spectro-mgmt-crds/values.yaml - ``` - - ```shell hideClipboard title="Example output" - Release "spectro-mgmt-crds" does not exist. Installing it now. - NAME: spectro-mgmt-crds - LAST DEPLOYED: Wed Jun 17 21:17:39 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### VerteX Helm Chart - -7. Open the file `vertex/values.yaml` using a text editor of your choice. This example uses Vim. - - ```shell - vim vertex/values.yaml - ``` - -8. The file `vertex/values.yaml` contains the default values for the Palette VerteX installation parameters. You must - populate the following parameters before installing Palette VerteX. For a complete list of fields and additional - information, refer to [Helm Configuration Reference](./vertex-helm-ref.md). - - | **Parameter** | **Description** | **Type** | - | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `global.imagePullSecret.dockerConfigJson` | If you plan to pull images from Spectro Cloud OCI registries (without mirror registries or image swap configured) or images from private registries that require authentication, paste your image pull secret here. This must match the image pull secret configured for [Cert-Manager](#cert-manager-helm-chart). If you omit the image pull secret during installation, you must provide it through the system console. Refer to [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) for more information. | string | - | `env.rootDomain` | The URL name or IP address you will use for the Palette installation. | string | - | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for Palette VerteX FIPS packs. These credentials are provided by our support team. | object | - | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | Set `reach-system.enabled` to `true` and configure the `reach-system.proxySettings` parameters to configure Palette VerteX to use a network proxy in your environment | object | - | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your Palette VerteX installation. | string | - - #### Self-Hosted OCI Registries - - The following parameters are required if you pull Palette VerteX images from a self-hosted OCI registry instead of a - Spectro Cloud OCI registry or AWS ECR. - - :::tip - - If you would prefer to keep your image swap values in a separate location, you can use the following table to - complete the `extras/image-swap/values.yaml` file instead. - - ```shell - tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ - vim extras/image-swap/values.yaml - ``` - - ::: - - | **Parameter** | **Description** | **Type** | - | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | - | `ociImageRegistry` | Configure the registry endpoint, credentials, and `mirrorRegistries` values. Refer to the [Helm Configuration Reference](./vertex-helm-ref.md#oci-image-registry) page for parameter descriptions. | object | - | `ociImageRegistry.mirrorRegistries` | A comma-separated list of mirror registries in image swap format that maps public registry paths to your private registry. Refer to the [Helm Configuration Reference](./vertex-helm-ref.md#oci-image-registry) page for examples. | string | - | `imageSwapImages` | The Image Swap init and webhook images. If you host these images in your OCI registry, replace the image paths with your registry URL and namespace or project. | object | - | `imageSwapConfig.isEKSCluster` | Set to `true` if you are installing Palette on an Amazon EKS cluster. Set to `false` for all other Kubernetes distributions. | boolean | - - :::info - - Include `/v2` in your mirror registry endpoints if you are using a - [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. - Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - - ::: - -9. Save the completed `vertex/values.yaml` file. Expand the following sections to review an example of the - `vertex/values.yaml` file with the required parameters highlighted. - - - - - - ```yaml {8,60,84-93} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "connected" #values can be connected or airgap. - isPaletteBaseCluster: false - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: false - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the ingress controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) - # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.docs-test.spectrocloud.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - # ociPackRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackEcrRegistry: - endpoint: "https://415789037893.dkr.ecr.us-west-2.amazonaws.com" # - name: "Palette Packs" # - accessKey: "**********" # - secretKey: "**********" # - baseContentPath: "production-fips" # - isPrivate: true - insecureSkipVerify: false - caCert: "" - credentialType: "" - - # ociImageRegistry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # baseContentPath: "" # - # insecureSkipVerify: false - # caCert: "" - # mirrorRegistries: "" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" - imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - tunnel: - preferredServer: - endpoint: "" - servers: - - endpoint: "" - ingress: - # When enabled the Traefik ingress controller would be installed - enabled: true - - # Port allocation behaviour based on traefik.hostPort: - # - # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. - # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. - traefik: - # Whether to front the Traefik ingress controller with a cloud - # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) - hostPort: false - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity - key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity - ca: - crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - ```yaml {4,55,84-93} - ######################### - # Spectro Cloud Palette # - ######################### - - global: - imagePullSecret: - # Provide your own base64 encoded dockerconfigjson value below if using ImagePullSecret for Private registry Authentication - dockerConfigJson: "abcdEFGhiJKlmnOPQrSTUVwX..." # omitted for brevity - - # MongoDB Configuration - mongo: - # Whether to deploy MongoDB in-cluster (internal == true) or use Mongo Atlas - internal: true - - # Mongodb URL. Only change if using Mongo Atlas. - databaseUrl: "mongo-0.mongo.hubble-system.svc.cluster.local,mongo-1.mongo.hubble-system.svc.cluster.local,mongo-2.mongo.hubble-system.svc.cluster.local" - # Mongo Atlas password, base64 encoded. Only enter if using Mongo Atlas. - databasePassword: "" - - #No. of mongo replicas to run, default is 3 - replicas: 3 - # The following only apply if mongo.internal == true - cpuLimit: "2000m" - memoryLimit: "4Gi" - pvcSize: "20Gi" - storageClass: "" # leave empty to use the default storage class - - config: - installationMode: "connected" #values can be connected or airgap. - isPaletteBaseCluster: false - - # SSO SAML Configuration (Optional for self-hosted type) - sso: - saml: - enabled: false - acsUrlRoot: "myfirstpalette.spectrocloud.com" - acsUrlScheme: "https" - audienceUrl: "https://www.spectrocloud.com" - entityId: "https://www.spectrocloud.com" - apiVersion: "v1" - - # Email Configurations. (Optional for self-hosted type) - email: - enabled: false - emailId: "noreply@spectrocloud.com" - smtpServer: "smtp.gmail.com" - smtpPort: 587 - insecureSkipVerifyTls: false - fromEmailId: "noreply@spectrocloud.com" - password: "" # base64 encoded SMTP password - - env: - # rootDomain is a DNS record which will be mapped to the ingress controller load balancer - # E.g., myfirstpalette.spectrocloud.com - # - Mandatory if ingress.traefik.hostPort == false (LoadBalancer mode) - # - Optional if ingress.traefik.hostPort == true (hostPort / appliance mode, leave empty) - # - # IMPORTANT: a DNS record must be created separately and it must be a wildcard to account for Organization prefixes - # E.g., *.myfirstpalette.spectrocloud.com - rootDomain: "vertex.docs-test.spectrocloud.com" - - # stableEndpointAccess is used when deploying EKS clusters in Private network type. - # When your Saas installed instance have connectivity to the private VPC where you want to launch the cluster set the stableEndpointAccess to true - cluster: - stableEndpointAccess: false - - # registry: - # endpoint: "" # - # name: "" # - # password: "" # - # username: "" # - # insecureSkipVerify: false - # caCert: "" - - ociPackRegistry: - endpoint: "example.harbor.org" # - name: "VerteX Packs OCI" # - password: "**************" # - username: "**************" # - baseContentPath: "spectro-packs" # - insecureSkipVerify: false - caCert: "" - - # ociPackEcrRegistry: - # endpoint: "" # - # name: "" # - # accessKey: "" # - # secretKey: "" # - # baseContentPath: "" # - # isPrivate: true - # insecureSkipVerify: false - # caCert: "" - - ociImageRegistry: - endpoint: "example.harbor.org" # - name: "VerteX Images OCI" # - password: "**************" # - username: "**************" # - baseContentPath: "spectro-images" # - insecureSkipVerify: false - caCert: "" - mirrorRegistries: "" # See instructions below. - - # Instruction for mirrorRegistries. - # ---------------------------------- - # Please provide the registry endpoint for the following registries, separated by double colons (::): - # docker.io - # gcr.io - # ghcr.io - # k8s.gcr.io - # registry.k8s.io - # quay.io - # For each registry, follow this example format: - # docker.io::/v2/,gcr.io::/v2/,ghcr.io::/v2/,k8s.gcr.io::/v2/,registry.k8s.io::/v2/,quay.io::/v2/,us-docker.pkg.dev::/v2/ - # Replace with your actual registry endpoint and , , , , , and with the specific endpoint details for each registry. - - imageSwapImages: - imageSwapInitImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap-init:v1.5.3-spectro-4.9.0" - imageSwapImage: "us-docker.pkg.dev/palette-images-fips/third-party/thewebroot/imageswap:v1.5.3-spectro-4.9.0" - - imageSwapConfig: - isEKSCluster: true #If the Cluster you are trying to install is EKS cluster set value to true else set to false - - grpc: - external: false - endpoint: "" #Please provide DNS endpoint with the port eg: msg.spectrocloud.com:443 - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the GRPC load balancer service. If empty, a dynamic IP will be generated. - grpcStaticIP: "" - caCertificateBase64: "" #Please provide caCertificate for the grpc server Cert - serverCrtBase64: "" - serverKeyBase64: "" - insecureSkipVerify: false - tunnel: - preferredServer: - endpoint: "" - servers: - - endpoint: "" - ingress: - # When enabled the Traefik ingress controller would be installed - enabled: true - - # Port allocation behaviour based on traefik.hostPort: - # - # traefik.hostPort=false → Traefik: 80/443 (LoadBalancer Service) -- default behaviour for self-hosted / cloud setups with an external LB. - # traefik.hostPort=true → Traefik: 80/443 (bound to node hostPort) -- appliance / on-prem setup with no external LB. - traefik: - # Whether to front the Traefik ingress controller with a cloud - # load balancer (hostPort == false) or bind directly to node host ports (hostPort == true) - hostPort: false - - ingress: - # Default SSL certificate and key for the ingress controller (Optional) - # A wildcard cert for config.env.rootDomain, e.g., *.myfirstpalette.spectrocloud.com - # If left blank, a self-signed cert will be generated (when terminating TLS upstream of the ingress controller) - certificate: "" - key: "" - - #If ACM is enabled please use grpc as a non internal and bring grpc on different LB. Provide certificate and dns for it. - annotations: {} - # AWS example - # service.beta.kubernetes.io/aws-load-balancer-internal: "true" - # service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - # service.beta.kubernetes.io/aws-load-balancer-ssl-cert: - # service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "https" - # service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: '*' - - # Azure example - # service.beta.kubernetes.io/azure-load-balancer-internal: "true" - # service.beta.kubernetes.io/azure-dns-label-name: myserviceuniquelabel - - # Static IP for the Ingress load balancer service. If empty, a dynamic IP will be generated. - ingressStaticIP: "" - - # For Service like AWS Load Balancer using https we would want to terminate the HTTPS at Load Balancer. - terminateHTTPSAtLoadBalancer: false - - frps: - frps: - enabled: false - frpHostURL: proxy.sample.spectrocloud.com - server: - crt: LS0tLS1CRUdJTiBDRVJU... # omitted for brevity - key: LS0tLS1CRUdJTiBSU0Eg... # omitted for brevity - ca: - crt: LS0tLS1CRUdJTiBDRVJ... # omitted for brevity - service: - annotations: {} - - ui-system: - enabled: true - ui: - nocUI: - enable: true - mapBoxAccessToken: "" # Leave Empty to use Default Access Token from Palette - mapBoxStyledLayerID: "" # Leave Empty to use Default Style Layer ID - - reachSystem: - enabled: false - proxySettings: - http_proxy: "" - https_proxy: "" - no_proxy: "" - ca_crt_path: "" # Set the 'ca_crt_path' parameter to the location of the certificate file on each node. This file should contain the Proxy CA Certificate, in case the Proxy being used requires a certificate. - scheduleOnControlPlane: true - ``` - - - - - - ### Image Swap Helm Chart - -10. (Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap - Helm chart. Image Swap rewrites pod image references to pull from your mirror registry. Palette VerteX ignores the - `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on - whether you added your image swap values to `vertex/values.yaml` or `extras/image-swap/values.yaml`. - - - - - - ```shell - helm upgrade --values vertex/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - - - - - ```shell - helm upgrade --values extras/image-swap/values.yaml \ - image-swap extras/image-swap/image-swap-*.tgz --install - ``` - - - - - - ```shell hideClipboard title="Example output" - Release "image-swap" does not exist. Installing it now. - NAME: image-swap - LAST DEPLOYED: Wed Jun 17 14:44:13 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - ### Reach System Helm Chart - -11. (Proxy environments only) If you are installing Palette VerteX in an environment where a network proxy must be - configured for VerteX to access the internet, install the Reach System chart using the following command. Ensure you - set `reach-system.enabled` to `true` and configure `reach-system.proxySettings` in `vertex/values.yaml`. - - ```shell - helm upgrade --values vertex/values.yaml \ - reach-system extras/reach-system/reach-system-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "reach-system" does not exist. Installing it now. - NAME: reach-system - LAST DEPLOYED: Fri Jan 30 18:40:57 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - - -
    - - Update containerd to use proxy configurations - - If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy - settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at ` /etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for - guidance. - - ``` - [Service] - Environment="HTTP_PROXY=http://example.com:9090" - Environment="HTTPS_PROXY=http://example.com:9090" - Environment="NO_PROXY=127.0.0.1,localhost,100.64.0.0/17,192.168.0.0/16,172.16.0.0/12,10.0.0.0/8,,.cluster.local" - ``` - -
    - - - - ### Installation - -12. Install the VerteX Helm Chart using the following command. - - ```shell - helm upgrade --values vertex/values.yaml \ - hubble vertex/spectro-mgmt-plane-*.tgz --install - ``` - - ```shell hideClipboard title="Example output" - Release "hubble" does not exist. Installing it now. - NAME: hubble - LAST DEPLOYED: Wed Jun 17 21:41:31 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - -13. Track the installation process using the command below. VerteX is ready when the deployments in the namespaces - `cp-system`, `hubble-system`, `ingress-traefik`, `jet-system`, and `ui-system` reach the _Ready_ state. The - installation takes between two to three minutes to complete. - - - - ```shell - kubectl get pods --all-namespaces --watch - ``` - - :::tip - - For a more user-friendly experience, use the open source tool [k9s](https://k9scli.io/) to monitor the installation - process. - - ::: - -14. Create a DNS CNAME record that is mapped to the VerteX `traefik-ingress-controller` load balancer. You can use the - following command to retrieve the load balancer IP address. If you need assistance creating the DNS record, consult - with your network administrator. - - ```shell - kubectl get service traefik-ingress-controller --namespace ingress-traefik \ - --output jsonpath='{.status.loadBalancer.ingress[0].hostname}' - ``` - - :::warning - - If Palette VerteX has only one tenant and you use local accounts with Single Sign-On (SSO) disabled, you can access - Palette VerteX using the IP address or any domain name that resolves to that IP. However, once you enable SSO, users - must log in using the tenant-specific subdomain. For example, if you create a tenant named `tenant1` and the domain - name you assigned to Palette VerteX is `vertex.example.com`, the tenant URL will be `tenant1.vertex.example.com`. We - recommend you create an additional wildcard DNS record to map all tenant URLs to the Palette VerteX load balancer. - For example, `*.vertex.example.com`. - - ::: - -15. Use the custom domain name or the IP address of the load balancer to visit the VerteX system console. To access the - system console, open a web browser and paste the custom domain URL in the address bar and append the value - `/system`. Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. - Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system - console. - - The first time you visit the VerteX system console, a warning message about a not-trusted SSL certificate may - appear. This is expected, as you still need to upload your SSL certificate to VerteX. You can ignore this warning - message and proceed. - - ![Screenshot of the VerteX system console showing Username and Password fields.](/vertex_install-on-kubernetes_install_system-console.webp) - -16. Log in to the system console using the following default credentials. Refer to the - [password requirements](../../system-management/account-management/credentials.md#password-requirements-and-security) - documentation page to learn more about password requirements. - - | **Parameter** | **Value** | - | ------------- | --------- | - | Username | `admin` | - | Password | `admin` | - - After logging in, you must create a new password. Once you create your password, you are redirected to the VerteX - system console. Use the username `admin` and your new password to log in to the system console. You can create - additional system administrator accounts and assign roles to users in the system console. Refer to the - [Account Management](../../system-management/account-management/account-management.md) documentation page for more - information. - -17. After logging in, a summary page is displayed. VerteX is installed with a self-signed SSL certificate. To assign a - different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority - files to VerteX. You can upload the files using the VerteX system console. Refer to the - [Configure HTTPS Encryption](../../system-management/ssl-certificate-management.md) page for instructions on how to - upload the SSL certificate files to VerteX. - - :::warning + - If you plan to deploy host clusters into different networks, you may require a reverse proxy. Check out the - [Configure Reverse Proxy](../../system-management/reverse-proxy.md) guide for instructions on how to configure a - reverse proxy for VerteX. +## Install Palette VerteX - ::: + -You now have a self-hosted instance of Palette installed in a Kubernetes cluster. Make sure you retain the `values.yaml` -file, as you can refer to it for future upgrades. +### Cert-Manager Helm Chart + +3. + +### Spectro Management CRDs Helm Chart + +6. + +### VerteX Helm Chart + +7. + +### Image Swap Helm Chart + +10. + +### Reach System Helm Chart + +11. + +### Installation + +12. ## Validate -Use the following steps to validate your Palette VerteX installation. - - - - - -1. Open up a web browser and navigate to the Palette VerteX system console. To access the system console, open a web - browser and paste the `env.rootDomain` value you provided in the address bar and append the value `/system`. You can - also use the IP address of the load balancer. - -2. Log in using the default credentials. After logging in, you are prompted to create a new password. Enter a new - password and save your changes. You are redirected to the Palette VerteX system console. - - - - - -1. Open a terminal session with access to the cluster you installed Palette VerteX on. - -2. Verify all pods in all namespaces are running. - - ```shell - kubectl get pods --all-namespaces - ``` - - ```shell hideClipboard title="Example output" - NAMESPACE NAME READY STATUS RESTARTS AGE - cert-manager cert-manager-5fb779d887-mz2vb 1/1 Running 0 8m46s - cert-manager cert-manager-cainjector-764f9646d4-7nhpq 1/1 Running 0 8m46s - cert-manager cert-manager-webhook-85b8dbdddd-fkn6z 1/1 Running 0 8m46s - cp-system spectro-cp-ui-5dffbcdc78-gk8st 1/1 Running 0 7m14s - hubble-system auth-7f4c7ff9c-2clwp 1/1 Running 0 6m8s - hubble-system auth-7f4c7ff9c-j84bt 1/1 Running 0 6m7s - hubble-system cloud-8f8467c95-9r8bp 1/1 Running 0 6m7s - hubble-system cloud-8f8467c95-pvcv4 1/1 Running 0 6m8s - hubble-system configserver-5bc8f9fdcb-mbt66 1/1 Running 0 6m8s - hubble-system event-5fbf6b7f44-bmzdk 1/1 Running 0 6m8s - hubble-system event-5fbf6b7f44-cxc58 1/1 Running 0 6m7s - hubble-system event-5fbf6b7f44-zhr9h 1/1 Running 0 6m7s - hubble-system foreq-8487bf9bbf-847vj 1/1 Running 0 6m7s - hubble-system hashboard-66f957cfdf-k48wn 1/1 Running 0 6m7s - hubble-system hashboard-66f957cfdf-pddx7 1/1 Running 0 6m6s - hubble-system hutil-7cc6975bb5-5mhjp 1/1 Running 0 6m6s - hubble-system hutil-7cc6975bb5-jwzr5 1/1 Running 0 6m7s - hubble-system memstore-7d59d65f67-j8lls 1/1 Running 0 6m6s - hubble-system mgmt-54fb5f487d-dj2tz 1/1 Running 0 7m14s - hubble-system mongo-0 2/2 Running 0 6m33s - hubble-system mongo-1 2/2 Running 0 5m47s - hubble-system mongo-2 2/2 Running 0 4m57s - hubble-system mongodb-key-manager-helm-k6294 0/1 Completed 0 7m15s - hubble-system msgbroker-0 1/1 Running 0 7m15s - hubble-system msgbroker-1 1/1 Running 0 6m43s - hubble-system oci-proxy-78cd749dc9-jfs86 1/1 Running 0 6m6s - hubble-system reloader-reloader-55d78d877b-7tnkq 1/1 Running 0 6m6s - hubble-system specman-0 1/1 Running 0 6m2s - hubble-system spectro-tunnel-74d559dd65-hlwch 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-knrfq 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-pb6pr 1/1 Running 0 6m5s - hubble-system spectrocluster-6885954988-xcvk9 1/1 Running 0 6m5s - hubble-system spectrocluster-jobs-7dc76bf6c7-pjc7l 1/1 Running 0 6m5s - hubble-system spectrocluster-reconciler-dcfd55ff5-gnfjg 1/1 Running 0 6m4s - hubble-system spectroclusterop-58966f7f54-grznt 1/1 Running 0 6m4s - hubble-system spectroclusterop-58966f7f54-jj9m6 1/1 Running 0 6m4s - hubble-system spectrossh-589d975d4d-82vm2 1/1 Running 0 6m4s - hubble-system system-d48fdbc9-ffzq9 1/1 Running 0 6m8s - hubble-system system-d48fdbc9-sztrr 1/1 Running 0 6m8s - hubble-system timeseries-f465b4c99-8h8c7 1/1 Running 0 6m4s - hubble-system timeseries-f465b4c99-jlzlj 1/1 Running 0 6m3s - hubble-system timeseries-f465b4c99-z27d8 1/1 Running 0 6m3s - hubble-system user-697c6f8bf-fgwtp 1/1 Running 0 6m3s - hubble-system user-697c6f8bf-wcqxk 1/1 Running 0 6m3s - ingress-traefik traefik-ingress-controller-5dctd 1/1 Running 0 7m15s - ingress-traefik traefik-ingress-controller-tx6st 1/1 Running 0 7m16s - ingress-traefik traefik-ingress-controller-zf25w 1/1 Running 0 7m16s - jet-system jet-796fc87c5d-vpvtz 1/1 Running 0 4m1s - kube-system aws-node-8xqnx 2/2 Running 0 121m - kube-system aws-node-gtr64 2/2 Running 0 121m - kube-system aws-node-h7pdv 2/2 Running 0 121m - kube-system coredns-566b9b9d-hck47 1/1 Running 0 129m - kube-system coredns-566b9b9d-jpnrs 1/1 Running 0 129m - kube-system ebs-csi-controller-7dfbb6bd58-nwcjl 6/6 Running 0 113m - kube-system ebs-csi-controller-7dfbb6bd58-w8kxz 6/6 Running 0 113m - kube-system ebs-csi-node-9r6fk 3/3 Running 0 113m - kube-system ebs-csi-node-vp744 3/3 Running 0 113m - kube-system ebs-csi-node-xb69v 3/3 Running 0 113m - kube-system kube-proxy-59qgr 1/1 Running 0 121m - kube-system kube-proxy-krrzd 1/1 Running 0 121m - kube-system kube-proxy-lbsgp 1/1 Running 0 121m - ui-system spectro-ui-56749c5f84-98m89 1/1 Running 0 7m15s - ``` - -3. Verify the `hubble` release is deployed. - - ```shell - helm status hubble - ``` - - ```shell title="Example output" hideClipboard - NAME: hubble - LAST DEPLOYED: Thu Jun 18 18:33:18 2026 - NAMESPACE: default - STATUS: deployed - REVISION: 1 - TEST SUITE: None - ``` - - - - + ## Next Steps diff --git a/src/theme/MDXComponents/MDXComponents.ts b/src/theme/MDXComponents/MDXComponents.ts index 8c86b4095e7..1ea3d8990d5 100644 --- a/src/theme/MDXComponents/MDXComponents.ts +++ b/src/theme/MDXComponents/MDXComponents.ts @@ -1,5 +1,6 @@ import MDXComponents from "@theme-original/MDXComponents"; import customMdxComponents from "@site/src/components/mdx/index"; +import CodeBlock from "@theme/CodeBlock"; import Tabs from "@theme/Tabs"; import TabItem from "@theme/TabItem"; import Tooltip from "@site/src/components/Tooltip/Tooltip"; @@ -30,6 +31,7 @@ import FullUrlLink from "@site/src/components/FullUrlLink"; export default { ...MDXComponents, ...customMdxComponents, + CodeBlock, Accordion, AccordionPanel, Tabs, From 06c3da0f67c0526d347a145cb34a221391f7c967 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 08:29:00 -0400 Subject: [PATCH 07/22] Fixing broken links --- .../image-pull-secret/_image-pull-secret-during-install.mdx | 2 +- .../image-pull-secret/_image-pull-secret-helm-install.mdx | 3 +-- .../image-pull-secret/_image-pull-secret-validate.mdx | 5 +---- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx index b0046b54be7..495beb1f201 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx @@ -9,6 +9,6 @@ Palette CLI. :::info Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the -secret [post-installation](#configure-image-pull-secret-post-installation) using the system console. +secret [post-installation](#post-installation) using the system console. ::: \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx index e998f0741e0..251603fd4ef 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx @@ -8,8 +8,7 @@ you can apply your image pull secret during the installation process. | **File** | **Parameter** | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| {props.helm}/values.yaml | | +| {props.helm}/values.yaml | | | `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | For the full installation process, refer to the diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx index 63683184869..80d6a570337 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx @@ -20,10 +20,7 @@ partial_name: image-pull-secret-validate 4. Verify that the **Pull secret** field displays a masked secret. - {props.edition === 'vertex' - ? Configuring an image pull secret in the system console. - : Configuring an image pull secret in the system console - } + {props.edition === 'vertex' ? Configuring an image pull secret in the system console. : Configuring an image pull secret in the system console.} From 4b1a61522d2efa64287640463dae48fd04b971d0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 12:40:51 +0000 Subject: [PATCH 08/22] Optimised images with calibre/image-actions --- .../configure-image-pull-secret_palette.webp | Bin 48160 -> 29522 bytes ...tall-on-vmware_palette-system-console.webp | Bin 51034 -> 24358 bytes ...-on-kubernetes_install_system-console.webp | Bin 57010 -> 26908 bytes 3 files changed, 0 insertions(+), 0 deletions(-) diff --git a/static/assets/docs/images/configure-image-pull-secret_palette.webp b/static/assets/docs/images/configure-image-pull-secret_palette.webp index 06547d00cf91cd83fdb6f0ad95e4b4dc1d41f70f..fe5f5eec64079743fe02f2c8bec6dd9c3c6357f7 100644 GIT binary patch literal 29522 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%0AZ0e-;9#j} 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 literal 51034 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

    y>5*SgkqK_oga_H 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 Date: Wed, 24 Jun 2026 09:03:02 -0400 Subject: [PATCH 09/22] Apply suggestions from code review Co-authored-by: Amanda Churi Filanowski --- .../_image-pull-secret-config-not-required.mdx | 2 +- .../kubernetes-install/_kubernetes-install-other-prereqs.mdx | 2 +- .../install-palette/install-on-kubernetes/palette-helm-ref.md | 4 +--- .../install-on-kubernetes/vertex-helm-ref.md | 4 +--- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx index 26df429de95..d0e2e140790 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx @@ -8,7 +8,7 @@ that the secret propagates to your workload clusters. This happens automatically constraints from your workload clusters to the Palette or Palette VerteX management plane. [THESE REQUIRE MANUAL INTERVENTION STEPS THAT WE DON'T HAVE YET.] -- **SaaS deployments** — Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action +- **SaaS deployments** - Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action is needed; for dedicated SaaS customers with access to the system console, consult with your customer support representative. diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx index b940306bd5e..9d1a7b6bc33 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-other-prereqs.mdx @@ -7,7 +7,7 @@ partial_name: kubernetes-install-other-prereqs `hubble` with the permission `readWriteAnyDatabase`. Refer to the [Add a Database User](https://www.mongodb.com/docs/guides/atlas/db-user/) guide for more information. -- A custom domain and the ability to update Domain Name System (DNS) records. You will need this to enable HTTPS +- A custom domain and the ability to update DNS records. You will need this to enable HTTPS encryption for {props.version}. - (Proxy environments only) If you are installing {props.version} behind a network proxy server, ensure {props.version} has access to the diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index 1afd3da9f33..0ed39df6ec0 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -72,11 +72,9 @@ global: :::info To obtain the base64-encoded version of your `config.json` file, use the following command. Replace -`` with the path to your `config.json` file. The `tr -d '\n'` removes new line characters +`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters and produces the output on a single line. -```shell -cat | base64 | tr -d '\n' ``` ::: diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md index 36cf07e4459..6162b748fb1 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md @@ -73,11 +73,9 @@ global: :::info To obtain the base64-encoded version of your `config.json` file, use the following command. Replace -`` with the path to your `config.json` file. The `tr -d '\n'` removes new line characters +`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters and produces the output on a single line. -```shell -cat | base64 | tr -d '\n' ``` ::: From d8bb652cef95b152e0b346e7bb7aa2c2c7348620 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 13:04:49 +0000 Subject: [PATCH 10/22] ci: auto-formatting prettier issues --- .../install-on-kubernetes/palette-helm-ref.md | 8 ++++---- .../install-on-kubernetes/vertex-helm-ref.md | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index 0ed39df6ec0..e95b42dd65f 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -72,10 +72,10 @@ global: :::info To obtain the base64-encoded version of your `config.json` file, use the following command. Replace -`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters -and produces the output on a single line. +`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line +characters and produces the output on a single line. -``` +```` ::: @@ -113,7 +113,7 @@ mongo: memoryLimit: "4Gi" pvcSize: "20Gi" storageClass: "" -``` +```` ## Config diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md index 6162b748fb1..ebd3df912cf 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md @@ -73,10 +73,10 @@ global: :::info To obtain the base64-encoded version of your `config.json` file, use the following command. Replace -`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters -and produces the output on a single line. +`` with the path to your `config.json` file. The `tr --delete '\n'` removes new line +characters and produces the output on a single line. -``` +```` ::: @@ -114,7 +114,7 @@ mongo: memoryLimit: "4Gi" pvcSize: "20Gi" storageClass: "" -``` +```` ## Config From 379c064f42ec1fca8f21bfe352887eac4c12043c Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 10:05:17 -0400 Subject: [PATCH 11/22] Moving pages, redirects, minor cleanup --- .../_image-pull-secret-config-not-required.mdx | 2 +- .../_image-pull-secret-helm-install.mdx | 2 +- .../_image-pull-secret-prereqs.mdx | 2 +- .../_image-pull-secret-validate.mdx | 2 +- .../edgeforge-workflow/validate-user-data.md | 4 ++-- .../install-on-kubernetes/install.md | 4 ++-- .../install-on-kubernetes/palette-helm-ref.md | 8 ++++---- .../configure-image-pull-secret.md | 2 +- .../docs-content/release-notes/announcements.md | 8 ++++---- .../docs-content/release-notes/release-notes.md | 4 ++-- .../install-on-kubernetes/install.md | 4 ++-- .../install-on-kubernetes/vertex-helm-ref.md | 8 ++++---- .../configure-image-pull-secret.md | 2 +- redirects.js | 11 +++++++++++ .../configure-image-pull-secret_vertex.webp | Bin 0 -> 50386 bytes 15 files changed, 37 insertions(+), 26 deletions(-) rename docs/docs-content/enterprise-version/{configure-image-pull-secret => system-management}/configure-image-pull-secret.md (99%) rename docs/docs-content/vertex/{configure-image-pull-secret => system-management}/configure-image-pull-secret.md (99%) create mode 100644 static/assets/docs/images/configure-image-pull-secret_vertex.webp diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx index d0e2e140790..cb72220eae0 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx @@ -5,7 +5,7 @@ partial_name: image-pull-secret-config-not-required Image pull secrets are managed by Spectro Cloud. While you do not need to configure the pull secret, you must ensure that the secret propagates to your workload clusters. This happens automatically unless there are connectivity -constraints from your workload clusters to the Palette or Palette VerteX management plane. [THESE REQUIRE MANUAL +constraints from your workload clusters to the {props.version} management plane. [THESE REQUIRE MANUAL INTERVENTION STEPS THAT WE DON'T HAVE YET.] - **SaaS deployments** - Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx index 251603fd4ef..d98113ddd6a 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx @@ -8,7 +8,7 @@ you can apply your image pull secret during the installation process. | **File** | **Parameter** | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| {props.helm}/values.yaml | | +| {props.helm}/values.yaml | | | `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | For the full installation process, refer to the diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx index 1465fdd6ee2..e3539959e34 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-prereqs.mdx @@ -10,6 +10,6 @@ partial_name: image-pull-secret-prereqs edition={props.edition} text="system console" url="/system-management/#access-the-system-console/" - /> + />. - An image pull secret provided by Spectro Cloud support. \ No newline at end of file diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx index 80d6a570337..fc0fc4ca9ff 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-validate.mdx @@ -20,7 +20,7 @@ partial_name: image-pull-secret-validate 4. Verify that the **Pull secret** field displays a masked secret. - {props.edition === 'vertex' ? Configuring an image pull secret in the system console. : Configuring an image pull secret in the system console.} + {props.edition === 'vertex' ? Configuring an image pull secret in the system console. : Configuring an image pull secret in the system console.} diff --git a/docs/docs-content/clusters/edge/edgeforge-workflow/validate-user-data.md b/docs/docs-content/clusters/edge/edgeforge-workflow/validate-user-data.md index 1fb6f279404..4edcb7c6cba 100644 --- a/docs/docs-content/clusters/edge/edgeforge-workflow/validate-user-data.md +++ b/docs/docs-content/clusters/edge/edgeforge-workflow/validate-user-data.md @@ -46,8 +46,8 @@ However, this process is also executed automatically when you build the Edge ins :::deprecated -The Palette Edge CLI is deprecated and new image versions will no longer be published. We recommend using the -[Palette CLI](/automation/palette-cli/) CanvOS directory instead. +The Palette Edge CLI is deprecated and new image versions will no longer be published. We recommend using the CanvOS +directory instead. ::: diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md index 453f3ab784a..5e4c4dd095e 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/install.md @@ -37,8 +37,8 @@ agent and Palette-created Kubernetes resources that will interfere with the inst - An image pull secret from Spectro Cloud customer support, required to pull images from Spectro Cloud OCI registries. This is not required if you plan to use [mirror registries](../../system-management/registry-override.md) or [image swap](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. + [Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for + more information. ### Other Prerequisites diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index e95b42dd65f..f7a652aa6f0 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -41,8 +41,8 @@ The global block allows you to provide configurations that apply globally to the Spectro Cloud's image pull secret will be required in an upcoming release for any users pulling images from a Spectro Cloud-owned registry. This is a breaking change. We recommend obtaining your secret as soon as possible to avoid service disruptions. Refer to -[Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) -for more information. +[Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for +more information. ::: @@ -53,8 +53,8 @@ management plane, workload clusters, and PCGs. The secret serves the following p - **Spectro Cloud registry authentication** - Authenticates with Spectro Cloud's registries to pull security-hardened images. These images are used by the management plane, workload clusters, and PCGs. To obtain this secret, contact your Spectro Cloud customer support representative. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. + [Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for + more information. - **Private registry authentication** - If you host Palette images in your own private registry, the secret provides the credentials needed to pull those images. diff --git a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md similarity index 99% rename from docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md rename to docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md index fea19bd6ed9..205df22ddf1 100644 --- a/docs/docs-content/enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md @@ -6,7 +6,7 @@ description: images." icon: "" hide_table_of_contents: false -sidebar_position: 5 +sidebar_position: 29 tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] --- diff --git a/docs/docs-content/release-notes/announcements.md b/docs/docs-content/release-notes/announcements.md index 79d7e63bdd5..224f34f8363 100644 --- a/docs/docs-content/release-notes/announcements.md +++ b/docs/docs-content/release-notes/announcements.md @@ -24,10 +24,10 @@ Use the [Find Breaking Changes](breaking-changes.md) page to list all the breaki Stay informed about the upcoming breaking changes in Palette and Palette VerteX. Use the information below to prepare for the changes in your environment. -| Change | Target Date | Published Date | -| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------- | -| Spectro Cloud is transitioning to the use of security-hardened images. As a result, retrieving images from Spectro Cloud OCI registries will now require a Spectro Cloud image pull secret. TThis secret is intended for long-term use and is configured once. Image pulls from Spectro Cloud registries will not be allowed unless a valid image pull secret is configured.

    This change primarily affects non-airgap environments that do not configure mirror registries or image swap; it does not apply to airgapped environments, which pull images from their own registries. To obtain your image pull secret, contact your Spectro Cloud customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for more information. | _To be announced_ | June 28, 2026 | -| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | +| Change | Target Date | Published Date | +| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------- | -------------- | +| Spectro Cloud is transitioning to the use of security-hardened images. As a result, retrieving images from Spectro Cloud OCI registries will now require a Spectro Cloud image pull secret. This secret is intended for long-term use and is configured once. Image pulls from Spectro Cloud registries will not be allowed unless a valid image pull secret is configured.

    This change primarily affects non-airgap environments that do not configure mirror registries or image swap; it does not apply to airgapped environments, which pull images from their own registries. To obtain your image pull secret, contact your Spectro Cloud customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/system-management/configure-image-pull-secret.md) for more information. | _To be announced_ | June 28, 2026 | +| [AWS GovCloud](../clusters/public-cloud/aws/add-aws-accounts.md#aws-govcloud) and [Azure Government cloud](../clusters/public-cloud/azure/azure-cloud.md#azure-government-cloud), currently disabled in the Palette UI, will be removed from the [Palette API](/api/category/palette-api-v1/), [Spectro Cloud Terraform provider](https://registry.terraform.io/providers/spectrocloud/spectrocloud/latest/docs), and [Spectro Cloud Crossplane provider](https://marketplace.upbound.io/providers/crossplane-contrib/provider-palette) in an upcoming release. To continue deploying and managing clusters using AWS GovCloud or Azure Government cloud, use [Palette VerteX](../vertex/vertex.md) instead. | _To be announced_ | May 3, 2026 | diff --git a/docs/docs-content/release-notes/release-notes.md b/docs/docs-content/release-notes/release-notes.md index df52b54703d..bdcac0e2916 100644 --- a/docs/docs-content/release-notes/release-notes.md +++ b/docs/docs-content/release-notes/release-notes.md @@ -40,8 +40,8 @@ tags: ["release-notes"] disruptions later. To obtain your image pull secret, contact your customer support representative. Refer to - [Configure Image Pull Secret](../enterprise-version/configure-image-pull-secret/configure-image-pull-secret.md) for - more information, including how to implement the image pull secret using the system console. + [Configure Image Pull Secret](../enterprise-version/system-management/configure-image-pull-secret.md) for more + information, including how to implement the image pull secret using the system console. diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md index beb4389ad35..3c41a83fc36 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md @@ -50,8 +50,8 @@ and VerteX-created Kubernetes resources that will interfere with the installatio - An image pull secret from Spectro Cloud customer support, required to pull images from Spectro Cloud OCI registries. This is not required if you plan to use [mirror registries](../../system-management/registry-override.md) or [image swap](../../../clusters/cluster-management/image-swap.md) when pulling images. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. + [Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for + more information. ### Other Prerequisites diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md index ebd3df912cf..d8b7b471a79 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md @@ -42,8 +42,8 @@ The global block allows you to provide configurations that apply globally to the Spectro Cloud's image pull secret will be required in an upcoming release for any users pulling images from a Spectro Cloud-owned registry. This is a breaking change. We recommend obtaining your secret as soon as possible to avoid service disruptions. Refer to -[Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) -for more information. +[Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for +more information. ::: @@ -54,8 +54,8 @@ management plane, workload clusters, and PCGs. The secret serves the following p - **Spectro Cloud registry authentication** - Authenticates with Spectro Cloud's registries to pull security-hardened images. These images are used by the management plane, workload clusters, and PCGs. To obtain this secret, contact your Spectro Cloud customer support representative. Refer to - [Configure Image Pull Secret for Security-Hardened Images](../../configure-image-pull-secret/configure-image-pull-secret.md) - for more information. + [Configure Image Pull Secret for Security-Hardened Images](../../system-management/configure-image-pull-secret.md) for + more information. - **Private registry authentication** - If you host Palette images in your own private registry, the secret provides the credentials needed to pull those images. diff --git a/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md b/docs/docs-content/vertex/system-management/configure-image-pull-secret.md similarity index 99% rename from docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md rename to docs/docs-content/vertex/system-management/configure-image-pull-secret.md index 6ee7015d3cc..1ee96a75ae6 100644 --- a/docs/docs-content/vertex/configure-image-pull-secret/configure-image-pull-secret.md +++ b/docs/docs-content/vertex/system-management/configure-image-pull-secret.md @@ -6,7 +6,7 @@ description: images." icon: "" hide_table_of_contents: false -sidebar_position: 5 +sidebar_position: 29 tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] keywords: ["self-hosted", "vertex", "image pull secret", "hardened images", "security"] --- diff --git a/redirects.js b/redirects.js index 81b2be99b04..458005fc89e 100644 --- a/redirects.js +++ b/redirects.js @@ -1004,6 +1004,17 @@ let redirects = [ from: `/clusters/edge/edgeforge-workflow/palette-canvos/build-rhel-stig-image/`, to: `/clusters/edge/edgeforge-workflow/palette-canvos/build-provider-images/build-rhel-stig-image/`, }, + + // Image Pull Secret + + { + from: `/enterprise-version/configure-image-pull-secret/`, + to: `/enterprise-version/system-management/configure-image-pull-secret/`, + }, + { + from: `/vertex/configure-image-pull-secret/`, + to: `/vertex/system-management/configure-image-pull-secret/`, + }, ]; if (packRedirects.length > 0) { diff --git a/static/assets/docs/images/configure-image-pull-secret_vertex.webp b/static/assets/docs/images/configure-image-pull-secret_vertex.webp new file mode 100644 index 0000000000000000000000000000000000000000..225c9c198bdaec8699ee120674b80c51ac437c9a GIT binary patch literal 50386 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 literal 0 HcmV?d00001 From 7814d8306691bbe59c19db91f8db748d8a8cf847 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 14:06:14 +0000 Subject: [PATCH 12/22] Optimised images with calibre/image-actions --- .../configure-image-pull-secret_vertex.webp | Bin 50386 -> 31140 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/static/assets/docs/images/configure-image-pull-secret_vertex.webp b/static/assets/docs/images/configure-image-pull-secret_vertex.webp index 225c9c198bdaec8699ee120674b80c51ac437c9a..956b775ad81893313edcde1ab44addff59680987 100644 GIT binary patch literal 31140 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 literal 50386 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 From 4f8ad66be26f4c6e3a54bdb8a54555acacc2397c Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 10:52:14 -0400 Subject: [PATCH 13/22] Broken code block + release notes --- .../_image-pull-secret-helm-install.mdx | 2 +- .../install-on-kubernetes/palette-helm-ref.md | 6 +++-- .../release-notes/release-notes.md | 23 ++++++++----------- .../install-on-kubernetes/vertex-helm-ref.md | 6 +++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx index d98113ddd6a..a26a5e9fed8 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-helm-install.mdx @@ -8,7 +8,7 @@ you can apply your image pull secret during the installation process. | **File** | **Parameter** | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| {props.helm}/values.yaml | | +| {props.helm}/values.yaml | | | `extras/cert-manager/values.yaml` | `imagePullSecret.dockerConfigJson` | For the full installation process, refer to the diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md index f7a652aa6f0..48c57a4d7ba 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/palette-helm-ref.md @@ -75,7 +75,9 @@ To obtain the base64-encoded version of your `config.json` file, use the followi `` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters and produces the output on a single line. -```` +```shell +cat | base64 | tr --delete '\n' +``` ::: @@ -113,7 +115,7 @@ mongo: memoryLimit: "4Gi" pvcSize: "20Gi" storageClass: "" -```` +``` ## Config diff --git a/docs/docs-content/release-notes/release-notes.md b/docs/docs-content/release-notes/release-notes.md index bdcac0e2916..9836bc44eef 100644 --- a/docs/docs-content/release-notes/release-notes.md +++ b/docs/docs-content/release-notes/release-notes.md @@ -25,23 +25,20 @@ tags: ["release-notes"] -- Spectro Cloud is transitioning to the exclusive use of security-hardened images for increased security posture. These - images have both a smaller size and attack surface, undergo regular security scans and strict patching schedules, and - contain cryptographic signatures to avoid tampering. As a result, retrieving images from Spectro Cloud-owned - registries will require a Spectro Cloud image pull secret. This secret is intended for long-term use and is configured - in the system console once as part of the initial setup process. - - This change primarily affects connected self-hosted environments that do not configure mirror registries or image - swap; it does not apply to airgapped environments, which pull images from their own registries. Authentication is - automatically handled for SaaS environments and Artifact Studio downloads. While configuring an image pull secret is - not required for the current version of Palette, it is an +- Spectro Cloud is transitioning to the use of security-hardened images. As a result, retrieving images from Spectro + Cloud OCI registries will require a Spectro Cloud image pull secret. This secret is intended for long-term use and is + configured once. + + This change primarily affects non-airgap environments that do not configure mirror registries or image swap; it does + not apply to airgapped environments, which pull images from their own registries. While configuring an image pull + secret is not required for the current version of Palette, it is an [upcoming breaking change](./announcements.md#upcoming-breaking-changes) and will be mandated in a future release. We - recommend that affected environments request and configure an image pull secret as soon as possible to prevent service - disruptions later. + recommend that affected environments configure an image pull secret as soon as possible to prevent service disruptions + later. To obtain your image pull secret, contact your customer support representative. Refer to [Configure Image Pull Secret](../enterprise-version/system-management/configure-image-pull-secret.md) for more - information, including how to implement the image pull secret using the system console. + information. diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md index d8b7b471a79..782e535692c 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/vertex-helm-ref.md @@ -76,7 +76,9 @@ To obtain the base64-encoded version of your `config.json` file, use the followi `` with the path to your `config.json` file. The `tr --delete '\n'` removes new line characters and produces the output on a single line. -```` +```shell +cat | base64 | tr --delete '\n' +``` ::: @@ -114,7 +116,7 @@ mongo: memoryLimit: "4Gi" pvcSize: "20Gi" storageClass: "" -```` +``` ## Config From 31383071566e05b0570ba50d9339ed6ba66d0236 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 13:15:12 -0400 Subject: [PATCH 14/22] parity with uninstall and upgrade helm guides --- .../install-on-kubernetes/uninstall.md | 14 ++-- .../upgrade/upgrade-k8s/airgap.md | 14 ++-- .../upgrade/upgrade-k8s/non-airgap.md | 16 +++-- .../install-on-kubernetes/uninstall.md | 30 +++++--- .../vertex/upgrade/upgrade-k8s/airgap.md | 72 ++++++++++--------- .../vertex/upgrade/upgrade-k8s/non-airgap.md | 38 +++++----- 6 files changed, 109 insertions(+), 75 deletions(-) diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md index 10e60d4799a..9e18519cd4d 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md @@ -67,15 +67,16 @@ to install Palette, this process does not apply. helm uninstall spectro-mgmt-crds ``` -6. (Reach only) If you installed Reach, issue the following command to start uninstalling Reach. This will remove all - resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by - Helm and will require additional manual intervention to remove. +6. (Proxy environments only) If you installed Palette in an environment where a network proxy is configured for Palette + to access the internet, issue the following command to start uninstalling Reach. This will remove all resources + related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and + will require additional manual intervention to remove. ```shell helm uninstall reach-system ``` -7. (Reach only) Issue the following commands to remove the remaining Reach system resources. +7. (Proxy environments only) Issue the following commands to remove the remaining Reach system resources. ```shell kubectl delete ns reach-system @@ -89,13 +90,14 @@ to install Palette, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -8. (Image Swap only) If you installed Image Swap, issue the following command to remove the `image-swap` chart. +8. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, issue the following command to + remove the `image-swap` chart. ```shell helm uninstall image-swap ``` -9. (Image Swap only) Issue the following commands to remove the remaining resources related to `image-swap`. +9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to `image-swap`. ```shell kubectl delete ns imageswap-system diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md index 5495e7ba13f..fea554ffdd0 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md @@ -295,8 +295,11 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet 12. Update the cert-manager chart using the following command. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` ```shell hideClipboard title="Example output" @@ -322,7 +325,8 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet basic `values.yaml` guidance. For a full list of parameters, refer to [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). -15. Upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 14. +15. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart + with the following command. Point to the `palette/values.yaml` file from step 14. ```shell helm upgrade --values palette/values.yaml \ @@ -339,7 +343,9 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -16. Upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 14. +16. (Proxy environments only) If you are upgrading a Palette instance in an environment where a network proxy must be + configured for Palette to access the internet, upgrade the reach-system chart with the following command. Point to + the `palette/values.yaml` file from step 14. ```shell helm upgrade --values palette/values.yaml \ diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md index 62465fe2184..f3a1d387b83 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md @@ -75,8 +75,11 @@ match your environment. 3. Update the cert-manager chart using the following command. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` ```shell hideClipboard title="Example output" @@ -114,8 +117,8 @@ match your environment. `values.yaml` guidance. For a full list of parameters, refer to [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). -6. If you are using a self-hosted OCI registry, upgrade the image-swap chart with the following command. Point to the - `palette/values.yaml` file from step 5. +6. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart + with the following command. Point to the `palette/values.yaml` file from step 5. ```shell helm upgrade --values palette/values.yaml \ @@ -132,8 +135,9 @@ match your environment. TEST SUITE: None ``` -7. If you are upgrading a Palette instance in an environment that requires network proxy configuration, upgrade the - reach-system chart with the following command. Point to the `palette/values.yaml` file from step 5. +7. (Proxy environments only) If you are upgrading a Palette instance in an environment where a network proxy must be + configured for Palette to access the internet, upgrade the reach-system chart with the following command. Point to + the `palette/values.yaml` file from step 5. ```shell helm upgrade --values palette/values.yaml \ diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md index 48fe4c7a67c..c3690a57ab6 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md @@ -40,28 +40,35 @@ install VerteX, this process does not apply. kubectl config current-context ``` -2. Issue the following command to start uninstalling the Vertex management plane. This will only remove the resources - managed by Helm and the remaining resources will require additional manual intervention. +2. Issue the following command to start uninstalling the Palette VerteX management plane. This will only remove the + resources managed by Helm. The remaining resources will require additional manual intervention. ```shell helm uninstall hubble ``` -3. Issue the following command to remove the namespace and custom resource definitions related to Vertex management - plane. +3. Remove the namespace and custom resource definitions related to the Palette VerteX management plane. ```shell - kubectl delete namespace hubble-system || kubectl delete crd spectroclusteractions.jet.cluster.spectrocloud.com + kubectl delete namespace hubble-system + kubectl delete crd spectroclusteractions.jet.cluster.spectrocloud.com ``` -4. Issue the following command to uninstall Cert Manager. Cert Manager does not reply on any Helm hooks and the Helm - uninstall command will uninstall all related resources. +4. Uninstall Cert Manager. ```shell helm uninstall cert-manager + kubectl delete namespace cert-manager ``` -5. (Optional) If you installed Reach, issue the following command to start uninstalling Reach. This will remove all +5. Uninstall the Spectro Management CRDs chart. + + ```shell + helm uninstall spectro-mgmt-crds + ``` + +6. (Proxy environments only) If you installed Palette VerteX in an environment where a network proxy is configured for + Palette VerteX to access the internet, issue the following command to start uninstalling Reach. This will remove all resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and will require additional manual intervention to remove. @@ -69,7 +76,7 @@ install VerteX, this process does not apply. helm uninstall reach-system ``` -6. (Optional) Issue the following commands to remove the remaining Reach system resources. +7. (Proxy environments only) Issue the following commands to remove the remaining Reach system resources. ```shell kubectl delete ns reach-system @@ -83,13 +90,14 @@ install VerteX, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -7. (Optional) If you installed Image Swap, issue the following command to remove the `image-swap` chart. +8. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, issue the following command to + remove the `image-swap` chart. ```shell helm uninstall image-swap ``` -8. (Optional) Issue the following commands to remove the remaining resources related to `image-swap`. +9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to `image-swap`. ```shell kubectl delete ns imageswap-system diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index 496f1c730d1..85cfae53fd7 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -250,50 +250,53 @@ Kubernetes. ::: -8. Navigate to the directory with the Palette VerteX installation zip file. Unzip the file to a **palette-install** - directory. +8. Navigate to the directory where you downloaded the Palette VerteX install zip file provided by our support team. + Unzip the file to a directory named `vertex-install`. ```shell - unzip release-*.zip -d palette-install + unzip charts.zip -d vertex-install ``` -9. Navigate to the release directory inside **palette-install**. +9. Navigate to the `vertex-install` directory. ```shell - cd palette-install/charts/release-* + cd vertex-install ``` -10. In a code editor of your choice, open the **extras/cert-manager/values.yaml** file and replace the - `cainjectorImage`,`controllerImage`, `webhookImage`, and `amceResolverImage` image URLs and with your OCI image - registry URL and the `/spectro-images/` namespace. - - ```yaml {2-5} - image: - cainjectorImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" +10. Open the file `extras/cert-manager/values.yaml` with a text editor of your choice. This example uses Vim. - featureGates: "AdditionalCertificateOutputFormats=true" + ```shell + vim extras/cert-manager/values.yaml ``` - Consider the following example for reference. + Append `` to each image, along with the `` where you want to store your images. - ```yaml {2-5} + ```yaml {2-5} hideClipboard title="Example output" image: - cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.17.0-spectro-4.6.1" - controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.17.0-spectro-4.6.1" - webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.17.0-spectro-4.6.1" - amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.17.0-spectro-4.6.1" + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` - featureGates: "AdditionalCertificateOutputFormats=true" + In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. + + ```yaml {2-5} hideClipboard title="Example output" + image: + cainjectorImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" ``` 11. Update the cert-manager chart using the following command. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` You should receive an output similar to the following. @@ -311,7 +314,9 @@ Kubernetes. 12. Upgrade the Spectro Management CRDs chart. ```shell - helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz + helm upgrade --install spectro-mgmt-crds \ + extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ + --values extras/spectro-mgmt-crds/values.yaml ``` You should receive an output similar to the following. @@ -339,10 +344,11 @@ Kubernetes. ::: -14. Upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 13. +14. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart + with the following command. Point to the `vertex/values.yaml` file from step 13. ```shell - helm upgrade --values palette/values.yaml \ + helm upgrade --values vertex/values.yaml \ image-swap extras/image-swap/image-swap-*.tgz --install ``` @@ -358,10 +364,12 @@ Kubernetes. TEST SUITE: None ``` -15. Upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 13. +15. (Proxy environments only) If you are upgrading a Palette VerteX instance in an environment where a network proxy + must be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following + command. Point to the `vertex/values.yaml` file from step 13. ```shell - helm upgrade --values palette/values.yaml \ + helm upgrade --values vertex/values.yaml \ reach-system extras/reach-system/reach-system-*.tgz --install ``` @@ -380,8 +388,8 @@ Kubernetes. 16. Upgrade Palette VerteX with the following command. ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-*.tgz --install + helm upgrade --values vertex/values.yaml \ + hubble vertex/spectro-mgmt-plane-*.tgz --install ``` You should receive an output similar to the following. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index 0d500d6e10c..fcfd57686d3 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -56,24 +56,27 @@ match your environment. ::: -1. Open a terminal session and navigate to the directory with the Palette VerteX installation zip file. Unzip the file - to a **palette-install** directory. +1. Open a terminal session and navigate to the directory where you downloaded the Palette VerteX install ZIP file + provided by our support team. Unzip the file to a directory named `vertex-install`. ```shell - unzip release-*.zip -d palette-install + unzip charts.zip -d vertex-install ``` -2. Navigate to the release directory inside **palette-install**. +2. Navigate to the `vertex-install` directory. ```shell - cd palette-install/charts/release-* + cd vertex-install ``` 3. Update the cert-manager chart using the following command. ```shell - helm upgrade --values extras/cert-manager/values.yaml \ - cert-manager extras/cert-manager/cert-manager-*.tgz --install + helm upgrade --install cert-manager \ + ./extras/cert-manager/cert-manager-*.tgz \ + --namespace cert-manager \ + --create-namespace \ + --values ./extras/cert-manager/values.yaml ``` You should receive an output similar to the following. @@ -91,7 +94,9 @@ match your environment. 4. Upgrade the Spectro Management CRDs chart. ```shell - helm upgrade --install spectro-mgmt-crds extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz + helm upgrade --install spectro-mgmt-crds \ + extras/spectro-mgmt-crds/spectro-mgmt-crds-*.tgz \ + --values extras/spectro-mgmt-crds/values.yaml ``` You should receive an output similar to the following. @@ -125,11 +130,11 @@ match your environment. ::: -6. If you are using a self-hosted OCI registry, upgrade the image-swap chart with the following command. Point to the - `palette/values.yaml` file from step 5. +6. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart + with the following command. Point to the `vertex/values.yaml` file from step 5. ```shell - helm upgrade --values palette/values.yaml \ + helm upgrade --values vertex/values.yaml \ image-swap extras/image-swap/image-swap-*.tgz --install ``` @@ -145,11 +150,12 @@ match your environment. TEST SUITE: None ``` -7. If you are upgrading a Palette VerteX instance in an environment that requires network proxy configuration, upgrade - the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 5. +7. (Proxy environments only) If you are upgrading a Palette VerteX instance in an environment where a network proxy must + be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following command. + Point to the `vertex/values.yaml` file from step 5. ```shell - helm upgrade --values palette/values.yaml \ + helm upgrade --values vertex/values.yaml \ reach-system extras/reach-system/reach-system-*.tgz --install ``` @@ -168,8 +174,8 @@ match your environment. 8. Upgrade Palette VerteX with the following command. ```shell - helm upgrade --values palette/values.yaml \ - hubble palette/spectro-mgmt-plane-*.tgz --install + helm upgrade --values vertex/values.yaml \ + hubble vertex/spectro-mgmt-plane-*.tgz --install ``` You should receive an output similar to the following. From fc91729150c8964c3e401583799bc3e6df29f49a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 24 Jun 2026 17:17:19 +0000 Subject: [PATCH 15/22] ci: auto-formatting prettier issues --- .../install-palette/install-on-kubernetes/uninstall.md | 3 ++- .../install-palette-vertex/install-on-kubernetes/uninstall.md | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md index 9e18519cd4d..44bbdf6b772 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md @@ -97,7 +97,8 @@ to install Palette, this process does not apply. helm uninstall image-swap ``` -9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to `image-swap`. +9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to + `image-swap`. ```shell kubectl delete ns imageswap-system diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md index c3690a57ab6..0484ed9d874 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md @@ -97,7 +97,8 @@ install VerteX, this process does not apply. helm uninstall image-swap ``` -9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to `image-swap`. +9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to + `image-swap`. ```shell kubectl delete ns imageswap-system From bb5996c2297838d432302e059b632c713bb541c0 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 14:18:51 -0400 Subject: [PATCH 16/22] Minor clarification around image swap --- .../_kubernetes-install-main-chart-airgap.mdx | 2 ++ .../_kubernetes-install-main-chart-non-airgap.mdx | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx index 3d94fc10fec..e589f39dae7 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx @@ -37,6 +37,8 @@ Open the file {props.helm}/values.yaml using a text editor of your If you would prefer to keep your image swap values in a separate location, you can use the following table to complete the `extras/image-swap/values.yaml` file instead. Otherwise, complete the following fields in {props.helm}/values.yaml. + Use the following command to extract and edit the `extras/image-swap/values.yaml` file. + ```shell tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ vim extras/image-swap/values.yaml diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx index 324b7df838d..8f4267bfd74 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx @@ -34,7 +34,9 @@ Open the file {props.helm}/values.yaml using a text editor of your :::tip If you would prefer to keep your image swap values in a separate location, you can use the following table to - complete the `extras/image-swap/values.yaml` file instead. Otherwise, complete the following fields in {props.helm}/values.yaml. + complete the `extras/image-swap/values.yaml` file instead. Otherwise, complete the following fields in {props.helm}/values.yaml. + + Use the following command to extract and edit the `extras/image-swap/values.yaml` file. ```shell tar --extract --verbose --gzip --file extras/image-swap/image-swap-*.tgz --directory extras/ From de8c496c9f201def27be0a1a6e2abf6d08ae7e4c Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Wed, 24 Jun 2026 15:16:29 -0400 Subject: [PATCH 17/22] Removing CLI day-0 until 4.9.c --- .../image-pull-secret/_image-pull-secret-during-install.mdx | 5 ++--- .../system-management/configure-image-pull-secret.md | 4 ---- .../vertex/system-management/configure-image-pull-secret.md | 4 ---- 3 files changed, 2 insertions(+), 11 deletions(-) diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx index 495beb1f201..7d4ba182848 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-during-install.mdx @@ -3,12 +3,11 @@ partial_category: self-hosted partial_name: image-pull-secret-during-install --- -You can add your image pull secret when installing self-hosted {props.version} using Helm charts or the -Palette CLI. +You can add your image pull secret when installing self-hosted {props.version} using Helm charts. :::info -Day-0 secret configuration is not supported for Palette Management Appliance installations. You must configure the +Day-0 secret configuration is not supported for Palette CLI or Palette Management Appliance installations. You must configure the secret [post-installation](#post-installation) using the system console. ::: \ No newline at end of file diff --git a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md index 205df22ddf1..3f7fa728a60 100644 --- a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md @@ -69,10 +69,6 @@ self-hosted Palette. helm="palette" /> -#### Palette CLI Installations - -[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI] - ### Post-Installation -#### Palette CLI Installations - -[AWAITING INSTRUCTIONS FROM ZULFI FOR CLI] - ### Post-Installation Date: Thu, 25 Jun 2026 10:45:35 -0400 Subject: [PATCH 18/22] Apply suggestions from code review Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> Co-authored-by: Amanda Churi Filanowski --- .../_image-pull-secret-config-not-required.mdx | 3 +-- .../_image-pull-secret-config-required.mdx | 2 +- .../_image-pull-secret-during-install.mdx | 12 +++++++----- .../image-pull-secret/_image-pull-secret-intro.mdx | 2 +- .../_image-pull-secret-post-install.mdx | 4 ++-- .../_kubernetes-install-cert-manager-airgap.mdx | 2 +- .../_kubernetes-install-cluster-prereqs.mdx | 14 +++++++------- .../kubernetes-install/_kubernetes-install-end.mdx | 14 ++++++-------- .../_kubernetes-install-main-chart-airgap.mdx | 6 ++++-- .../_kubernetes-install-main-chart-non-airgap.mdx | 6 ++++-- .../_kubernetes-install-reach-system.mdx | 5 ++--- .../configure-image-pull-secret.md | 2 ++ .../upgrade/upgrade-k8s/airgap.md | 2 +- .../vertex/upgrade/upgrade-k8s/airgap.md | 2 +- .../vertex/upgrade/upgrade-k8s/non-airgap.md | 12 +++++++++++- 15 files changed, 51 insertions(+), 37 deletions(-) diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx index cb72220eae0..47e9c86e38d 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-not-required.mdx @@ -5,8 +5,7 @@ partial_name: image-pull-secret-config-not-required Image pull secrets are managed by Spectro Cloud. While you do not need to configure the pull secret, you must ensure that the secret propagates to your workload clusters. This happens automatically unless there are connectivity -constraints from your workload clusters to the {props.version} management plane. [THESE REQUIRE MANUAL -INTERVENTION STEPS THAT WE DON'T HAVE YET.] +constraints from your workload clusters to the {props.version} management plane. - **SaaS deployments** - Image pull secrets are managed automatically on the backend. For multi-tenant SaaS, no action is needed; for dedicated SaaS customers with access to the system console, consult with your customer support diff --git a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx index 0ef5693a013..5a595d968c7 100644 --- a/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx +++ b/_partials/self-hosted/image-pull-secret/_image-pull-secret-config-required.mdx @@ -4,7 +4,7 @@ partial_name: image-pull-secret-config-required --- Non-airgapped self-hosted {props.version} environments that pull images directly from Spectro Cloud-owned OCI -registries must configure an image pull secret. This includes environments that _do not_ use +registries must configure an image pull secret. This _does not_ include environments that use Append `` to each image, along with the `` where you want to store your images. - ```yaml hideClipboard title="Example output" + image: cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx index f923485343f..da2d1b081ea 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cluster-prereqs.mdx @@ -11,8 +11,8 @@ partial_name: kubernetes-install-cluster-prereqs vertexPath="/install-palette-vertex/#size-guidelines" /> for additional sizing information. - - A minimum of three AMD64 (x86_64) nodes. These can be worker nodes or three untainted control plane nodes. ARM-based - nodes are not supported. + - A minimum of three AMD64 (x86_64) nodes. These can be worker nodes or three untainted control plane nodes. + - ARM-based nodes are not supported. - 8 CPUs per node @@ -24,16 +24,16 @@ partial_name: kubernetes-install-cluster-prereqs - **TCP/443** - Inbound and outbound to and from the {props.version} management cluster - - **TCP/6443** - Outbound traffic from the {props.version} management cluster to the deployed cluster's Kubernetes API server. + - **TCP/6443** - Outbound traffic from the {props.version} management cluster to the deployed workload cluster's Kubernetes API server. -- The following SSL certificate files for the domain name you will assign to {props.version}. You must enable HTTPS +- The following TLS/SSL certificate files for the domain name you will assign to {props.version}. You must enable HTTPS encryption for {props.version}. Reach out to your network administrator or security team to obtain these files: - - x509 SSL certificate file in base64 format + - x509 TLS/SSL certificate file in base64 format - - x509 SSL certificate key file in base64 format + - x509 TLS/SSL certificate key file in base64 format - - x509 SSL certificate authority file in base64 format + - x509 TLS/SSL certificate authority file in base64 format - The Kubernetes cluster must use a Kubernetes version compatible with your {props.version} version. Refer to Use the custom domain name or the IP address of the load balancer to visit the {props.version} system console. To access the - system console, open a web browser and paste the custom domain URL in the address bar and append the value - `/system`. Replace the domain name in the URL with your custom domain name or the IP address of the load balancer. - Alternatively, you can use the load balancer IP address with the appended value `/system` to access the system - console. + system console, open a web browser and paste the custom domain URL or the IP address of the load balancer in the address bar, and append the value + `/system`. - The first time you visit the {props.version} system console, a warning message about a not-trusted SSL certificate may - appear. This is expected, as you still need to upload your SSL certificate to {props.version}. You can ignore this warning + The first time you visit the {props.version} system console, a warning message about a not-trusted TLS/SSL certificate may + appear. This is expected, as you still need to upload your TLS/SSL certificate to {props.version}. You can ignore this warning message and proceed. {props.edition === 'vertex' @@ -89,8 +87,8 @@ Install the {props.version} Helm Chart using the following command. url="/system-management/account-management/" /> for more information. -

  • After logging in, a summary page is displayed. {props.version} is installed with a self-signed SSL certificate. To assign a - different SSL certificate you must upload the SSL certificate, SSL certificate key, and SSL certificate authority +
  • After logging in, a summary page is displayed. {props.version} is installed with a self-signed TLS/SSL certificate. To assign a + different TLS/SSL certificate, you must upload the SSL certificate, TLS/SSL certificate key, and TLS/SSL certificate authority files to {props.version}. You can upload the files using the {props.version} system console. Refer to {props.helm}/values.yaml using a text editor of your Include `/v2` in your mirror registry endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. + + Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. ::: -
  • Save the completed {props.helm}/values.yaml file. Expand the following sections to review an example of the +
  • Save the completed {props.helm}/values.yaml file. You can review the following examples of the {props.helm}/values.yaml file with the required parameters highlighted.
  • diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx index 8f4267bfd74..59ef313bd0c 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx @@ -57,13 +57,15 @@ Open the file {props.helm}/values.yaml using a text editor of your Include `/v2` in your mirror registry endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other - registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. + + Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. ::: -
  • Save the completed {props.helm}/values.yaml file. Expand the following sections to review an example of the +
  • Save the completed {props.helm}/values.yaml file. You can review the following examples of the {props.helm}/values.yaml file with the required parameters highlighted.
  • diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx index 7867819a120..fe40a6a1902 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx @@ -31,11 +31,10 @@ partial_name: kubernetes-install-reach-system If your Kubernetes cluster is behind a network proxy, ensure the containerd service is configured to use proxy settings. You can do this by updating the containerd configuration file on each node in the cluster. The - configuration file is typically located at `/etc/systemd/system/containerd.service.d/http-proxy.conf`. Below is an - example of the configuration file. Replace the values with your proxy settings. Ask your network administrator for + configuration file is typically located at `/etc/systemd/system/containerd.service.d/http-proxy.conf`. The following example shows configured proxy settings. Replace the values with your proxy settings. Ask your network administrator for guidance. - ``` + [Service] Environment="HTTP_PROXY=http://example.com:9090" Environment="HTTPS_PROXY=http://example.com:9090" diff --git a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md index 3f7fa728a60..4c66ab7e444 100644 --- a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md @@ -24,6 +24,8 @@ keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "se Depending on how your environment retrieves images, you may or may not need to configure Spectro Cloud's image pull secret. +Review the following sections to learn if your environment requires configuration. + ### Configuration Required ` to each image, along with the `` where you want to store your images. - ```yaml {2-5} hideClipboard title="Example output" + image: cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index 85cfae53fd7..79cad57bf30 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -271,7 +271,7 @@ Kubernetes. Append `` to each image, along with the `` where you want to store your images. - ```yaml {2-5} hideClipboard title="Example output" + image: cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index fcfd57686d3..5d885b5144b 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -126,7 +126,17 @@ match your environment. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. +- Ensure that the `values.yaml` file is ready before proceeding. If you are using a self-hosted OCI registry, make sure +that the `ociImageRegistry.mirrorRegistries` parameter in your `values.yaml` includes the necessary mirror links. + +- Include `/v2` in your endpoints if you are using a + [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. + Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other + registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. + + Including `/v2` + for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. ::: From fc7c7887f5c3ed1c7b179a4db535076d4232f77e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 14:47:29 +0000 Subject: [PATCH 19/22] ci: auto-formatting prettier issues --- .../upgrade/upgrade-k8s/airgap.md | 19 +++++++++++-------- .../vertex/upgrade/upgrade-k8s/airgap.md | 19 +++++++++++-------- .../vertex/upgrade/upgrade-k8s/non-airgap.md | 12 ++++++------ 3 files changed, 28 insertions(+), 22 deletions(-) diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md index fdfbd907052..e37ac6af2f3 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md @@ -274,13 +274,16 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet 11. Append `` to each image, along with the `` where you want to store your images. - - image: - cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` + image: cainjectorImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + + ```` In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. @@ -290,7 +293,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` + ```` 12. Update the cert-manager chart using the following command. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index 79cad57bf30..d45f2087574 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -271,13 +271,16 @@ Kubernetes. Append `` to each image, along with the `` where you want to store your images. - - image: - cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` + image: cainjectorImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: + "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + + ```` In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. @@ -287,7 +290,7 @@ Kubernetes. controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ``` + ```` 11. Update the cert-manager chart using the following command. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index 5d885b5144b..acd2957218e 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -126,19 +126,19 @@ match your environment. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: + - Ensure that the `values.yaml` file is ready before proceeding. If you are using a self-hosted OCI registry, make sure -that the `ociImageRegistry.mirrorRegistries` parameter in your `values.yaml` includes the necessary mirror links. + that the `ociImageRegistry.mirrorRegistries` parameter in your `values.yaml` includes the necessary mirror links. - Include `/v2` in your endpoints if you are using a [Harbor registry with a proxy cache](https://goharbor.io/docs/2.1.0/administration/configure-proxy-cache/) project. Harbor proxy cache projects use `/v2` as part of their internal URL routing for cached images. For all other registries, omit `/v2`, as the container runtime automatically appends `/v2` when making API calls. - - Including `/v2` - for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. For example: - `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. - ::: + Including `/v2` for non-proxy-cache registries results in a doubled `/v2/v2/` path, which causes image pull failures. + For example: `docker.io::harbor.example.org/v2/proxy-cache-project/docker.io`. + + ::: 6. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart with the following command. Point to the `vertex/values.yaml` file from step 5. From b30e632a13e69ab48c984ddfa80ed810edc0e7b1 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Thu, 25 Jun 2026 12:38:47 -0400 Subject: [PATCH 20/22] Apply suggestions from code review Co-authored-by: Ben Radstone <56587332+benradstone@users.noreply.github.com> --- .../kubernetes-install/_kubernetes-install-image-swap.mdx | 2 +- .../_kubernetes-install-main-chart-airgap.mdx | 2 +- .../_kubernetes-install-main-chart-non-airgap.mdx | 2 +- .../_kubernetes-install-reach-system.mdx | 2 +- .../install-palette/install-on-kubernetes/uninstall.md | 8 ++++---- .../enterprise-version/upgrade/upgrade-k8s/airgap.md | 4 ++-- .../enterprise-version/upgrade/upgrade-k8s/non-airgap.md | 4 ++-- .../install-on-kubernetes/airgap-install/install.md | 2 +- .../install-on-kubernetes/install.md | 2 +- .../install-on-kubernetes/uninstall.md | 8 ++++---- docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md | 4 ++-- .../docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md | 4 ++-- 12 files changed, 22 insertions(+), 22 deletions(-) diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx index c7ab3bceadc..acc1228f529 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-image-swap.mdx @@ -3,7 +3,7 @@ partial_category: self-hosted partial_name: kubernetes-install-image-swap --- -(Self-hosted OCI registry only) If you plan to use image swap for self-hosted OCI registries, install the Image Swap +_(Self-hosted OCI registry only)_ If you plan to use image swap for self-hosted OCI registries, install the Image Swap Helm chart. Image swap rewrites pod image references to pull from your mirror registry. {props.version} ignores the `mirrorRegistries` configuration unless the Image Swap chart is installed. Choose the correct command based on whether you added your image swap values to {props.helm}/values.yaml or `extras/image-swap/values.yaml`. diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx index 2db0589a5d9..2b8db6a58cd 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-airgap.mdx @@ -24,7 +24,7 @@ Open the file {props.helm}/values.yaml using a text editor of your | `config.installationMode` | Determines whether your {props.version} installation should have a default connection to the internet. Set to `airgap`. | string | | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for {props.version} FIPS packs. These credentials are provided by our support team. If using images from a self-hosted OCI registry instead, leave these sections blank and refer to the [Self-Hosted OCI Registries](#self-hosted-oci-registries) table instead. | object | | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | (Proxy environments only) Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | + | `reachSystem` | _(Proxy environments only)_ Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your {props.version} installation. | string | #### Self-Hosted OCI Registries diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx index 59ef313bd0c..f396726db75 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-main-chart-non-airgap.mdx @@ -23,7 +23,7 @@ Open the file {props.helm}/values.yaml using a text editor of your | `env.rootDomain` | The URL name or IP address you will use for the {props.version} installation. | string | | `ociPackRegistry` or `ociPackEcrRegistry` | The OCI registry credentials for {props.version} FIPS packs. These credentials are provided by our support team. If using images from a self-hosted OCI registry instead, leave these sections blank and refer to the [Self-Hosted OCI Registries](#self-hosted-oci-registries) table instead. | object | | `ingress.enabled` | Whether to install the Traefik ingress controller. Set to `false` if you already have an ingress controller deployed in the cluster. | boolean | - | `reachSystem` | (Proxy environments only) Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | + | `reachSystem` | _(Proxy environments only)_ Set `reachSystem.enabled` to `true` and configure the `reachSystem.proxySettings` parameters to configure {props.version} to use a network proxy in your environment | object | | `mongo.storageClass` | If you do not have a default storage class in your cluster (the annotation `"storageclass.kubernetes.io/is-default-class":"true"`), enter the name of the storage class to use for your {props.version} installation. | string | #### Self-Hosted OCI Registries diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx index fe40a6a1902..922e95c86c8 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx @@ -3,7 +3,7 @@ partial_category: self-hosted partial_name: kubernetes-install-reach-system --- -(Proxy environments only) If you are installing {props.version} in an environment where a network proxy must be +_(Proxy environments only)_ If you are installing {props.version} in an environment where a network proxy must be configured for {props.version} to access the internet, install the Reach System chart using the following command. :::warning diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md index 44bbdf6b772..64a22cf08c4 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md @@ -67,7 +67,7 @@ to install Palette, this process does not apply. helm uninstall spectro-mgmt-crds ``` -6. (Proxy environments only) If you installed Palette in an environment where a network proxy is configured for Palette +6. _(Proxy environments only)_ If you installed Palette in an environment where a network proxy is configured for Palette to access the internet, issue the following command to start uninstalling Reach. This will remove all resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and will require additional manual intervention to remove. @@ -76,7 +76,7 @@ to install Palette, this process does not apply. helm uninstall reach-system ``` -7. (Proxy environments only) Issue the following commands to remove the remaining Reach system resources. +7. _(Proxy environments only)_ Issue the following commands to remove the remaining Reach system resources. ```shell kubectl delete ns reach-system @@ -90,14 +90,14 @@ to install Palette, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -8. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, issue the following command to +8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command to remove the `image-swap` chart. ```shell helm uninstall image-swap ``` -9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to +9. _(Self-hosted OCI registry only)_ Issue the following commands to remove the remaining resources related to `image-swap`. ```shell diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md index e37ac6af2f3..129adac6499 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md @@ -328,7 +328,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet basic `values.yaml` guidance. For a full list of parameters, refer to [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). -15. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart +15. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 14. ```shell @@ -346,7 +346,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet TEST SUITE: None ``` -16. (Proxy environments only) If you are upgrading a Palette instance in an environment where a network proxy must be +16. _(Proxy environments only)_ If you are upgrading a Palette instance in an environment where a network proxy must be configured for Palette to access the internet, upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 14. diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md index f3a1d387b83..594c932a4ac 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/non-airgap.md @@ -117,7 +117,7 @@ match your environment. `values.yaml` guidance. For a full list of parameters, refer to [Helm Configuration Reference](../../install-palette/install-on-kubernetes/palette-helm-ref.md). -6. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart +6. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, upgrade the image-swap chart with the following command. Point to the `palette/values.yaml` file from step 5. ```shell @@ -135,7 +135,7 @@ match your environment. TEST SUITE: None ``` -7. (Proxy environments only) If you are upgrading a Palette instance in an environment where a network proxy must be +7. _(Proxy environments only)_ If you are upgrading a Palette instance in an environment where a network proxy must be configured for Palette to access the internet, upgrade the reach-system chart with the following command. Point to the `palette/values.yaml` file from step 5. diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md index e89f159467b..a33f320f568 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/airgap-install/install.md @@ -37,7 +37,7 @@ cluster has the necessary network connectivity for Palette VerteX to operate suc helm="vertex" /> -- (FIPS compliance only) The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. +- _(FIPS compliance only)_ The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. Otherwise, Palette VerteX and its operations will not be FIPS-compliant. ### Local Environment diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md index 3c41a83fc36..60d76a98051 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/install.md @@ -35,7 +35,7 @@ and VerteX-created Kubernetes resources that will interfere with the installatio helm="vertex" /> -- (FIPS compliance only) The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. +- _(FIPS compliance only)_ The OS and Kubernetes cluster you are installing Palette VerteX onto must be FIPS-compliant. Otherwise, Palette VerteX and its operations will not be FIPS-compliant. ### Local Environment diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md index 0484ed9d874..a1953f08879 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md @@ -67,7 +67,7 @@ install VerteX, this process does not apply. helm uninstall spectro-mgmt-crds ``` -6. (Proxy environments only) If you installed Palette VerteX in an environment where a network proxy is configured for +6. _(Proxy environments only)_ If you installed Palette VerteX in an environment where a network proxy is configured for Palette VerteX to access the internet, issue the following command to start uninstalling Reach. This will remove all resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and will require additional manual intervention to remove. @@ -76,7 +76,7 @@ install VerteX, this process does not apply. helm uninstall reach-system ``` -7. (Proxy environments only) Issue the following commands to remove the remaining Reach system resources. +7. _(Proxy environments only)_ Issue the following commands to remove the remaining Reach system resources. ```shell kubectl delete ns reach-system @@ -90,14 +90,14 @@ install VerteX, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -8. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, issue the following command to +8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command to remove the `image-swap` chart. ```shell helm uninstall image-swap ``` -9. (Self-hosted OCI registry only) Issue the following commands to remove the remaining resources related to +9. _(Self-hosted OCI registry only)_ Issue the following commands to remove the remaining resources related to `image-swap`. ```shell diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index d45f2087574..01e501de477 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -347,7 +347,7 @@ Kubernetes. ::: -14. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart +14. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, upgrade the image-swap chart with the following command. Point to the `vertex/values.yaml` file from step 13. ```shell @@ -367,7 +367,7 @@ Kubernetes. TEST SUITE: None ``` -15. (Proxy environments only) If you are upgrading a Palette VerteX instance in an environment where a network proxy +15. _(Proxy environments only)_ If you are upgrading a Palette VerteX instance in an environment where a network proxy must be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following command. Point to the `vertex/values.yaml` file from step 13. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index acd2957218e..f0fffc94160 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -140,7 +140,7 @@ match your environment. ::: -6. (Self-hosted OCI registry only) If you use image swap for self-hosted OCI registries, upgrade the image-swap chart +6. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, upgrade the image-swap chart with the following command. Point to the `vertex/values.yaml` file from step 5. ```shell @@ -160,7 +160,7 @@ match your environment. TEST SUITE: None ``` -7. (Proxy environments only) If you are upgrading a Palette VerteX instance in an environment where a network proxy must +7. _(Proxy environments only)_ If you are upgrading a Palette VerteX instance in an environment where a network proxy must be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following command. Point to the `vertex/values.yaml` file from step 5. From d51a77effe8111f9445e50b7292f7d3508340048 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2026 16:40:47 +0000 Subject: [PATCH 21/22] ci: auto-formatting prettier issues --- .../install-on-kubernetes/uninstall.md | 12 ++++++------ .../install-on-kubernetes/uninstall.md | 4 ++-- .../vertex/upgrade/upgrade-k8s/non-airgap.md | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md index 64a22cf08c4..96e015c4943 100644 --- a/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/enterprise-version/install-palette/install-on-kubernetes/uninstall.md @@ -67,10 +67,10 @@ to install Palette, this process does not apply. helm uninstall spectro-mgmt-crds ``` -6. _(Proxy environments only)_ If you installed Palette in an environment where a network proxy is configured for Palette - to access the internet, issue the following command to start uninstalling Reach. This will remove all resources - related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by Helm and - will require additional manual intervention to remove. +6. _(Proxy environments only)_ If you installed Palette in an environment where a network proxy is configured for + Palette to access the internet, issue the following command to start uninstalling Reach. This will remove all + resources related to Reach that are managed by Helm. However, some resources created by Helm hooks are not managed by + Helm and will require additional manual intervention to remove. ```shell helm uninstall reach-system @@ -90,8 +90,8 @@ to install Palette, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command to - remove the `image-swap` chart. +8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command + to remove the `image-swap` chart. ```shell helm uninstall image-swap diff --git a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md index a1953f08879..f4b114f0209 100644 --- a/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md +++ b/docs/docs-content/vertex/install-palette-vertex/install-on-kubernetes/uninstall.md @@ -90,8 +90,8 @@ install VerteX, this process does not apply. kubectl delete clusterrole reach-proxy-role ``` -8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command to - remove the `image-swap` chart. +8. _(Self-hosted OCI registry only)_ If you use image swap for self-hosted OCI registries, issue the following command + to remove the `image-swap` chart. ```shell helm uninstall image-swap diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md index f0fffc94160..ad26290ff1d 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/non-airgap.md @@ -160,9 +160,9 @@ match your environment. TEST SUITE: None ``` -7. _(Proxy environments only)_ If you are upgrading a Palette VerteX instance in an environment where a network proxy must - be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following command. - Point to the `vertex/values.yaml` file from step 5. +7. _(Proxy environments only)_ If you are upgrading a Palette VerteX instance in an environment where a network proxy + must be configured for Palette VerteX to access the internet, upgrade the reach-system chart with the following + command. Point to the `vertex/values.yaml` file from step 5. ```shell helm upgrade --values vertex/values.yaml \ From 74962f7cf98ffb43a3e34930dc5ac715c2f16817 Mon Sep 17 00:00:00 2001 From: Amanda Churi Filanowski Date: Thu, 25 Jun 2026 14:47:59 -0400 Subject: [PATCH 22/22] Sidebar adjustment + broken codeblocks --- ...kubernetes-install-cert-manager-airgap.mdx | 2 +- .../_kubernetes-install-reach-system.mdx | 2 +- .../configure-image-pull-secret.md | 2 +- .../upgrade/upgrade-k8s/airgap.md | 19 ++++++++----------- .../vertex/upgrade/upgrade-k8s/airgap.md | 19 ++++++++----------- 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx index cbd34bd73e0..45e9e151064 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-cert-manager-airgap.mdx @@ -12,7 +12,7 @@ Open the file `extras/cert-manager/values.yaml` using a text editor of your choi
  • Append `` to each image, along with the `` where you want to store your images.
  • - + ```yaml image: cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" diff --git a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx index 922e95c86c8..671f0c687be 100644 --- a/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx +++ b/_partials/self-hosted/kubernetes-install/_kubernetes-install-reach-system.mdx @@ -34,7 +34,7 @@ _(Proxy environments only)_ If you are installing {props.version} in an environm configuration file is typically located at `/etc/systemd/system/containerd.service.d/http-proxy.conf`. The following example shows configured proxy settings. Replace the values with your proxy settings. Ask your network administrator for guidance. - + ``` [Service] Environment="HTTP_PROXY=http://example.com:9090" Environment="HTTPS_PROXY=http://example.com:9090" diff --git a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md index 4c66ab7e444..d8d81a426db 100644 --- a/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md +++ b/docs/docs-content/enterprise-version/system-management/configure-image-pull-secret.md @@ -6,7 +6,7 @@ description: images." icon: "" hide_table_of_contents: false -sidebar_position: 29 +sidebar_position: 35 tags: ["self-hosted", "account", "image pull secret", "hardened images", "security"] keywords: ["self-hosted", "palette", "image pull secret", "hardened images", "security"] --- diff --git a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md index 129adac6499..36cb5472bb4 100644 --- a/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/enterprise-version/upgrade/upgrade-k8s/airgap.md @@ -274,16 +274,13 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet 11. Append `` to each image, along with the `` where you want to store your images. - image: cainjectorImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - - ```` + ```yaml + image: + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. @@ -293,7 +290,7 @@ This guide takes you through the process of upgrading a self-hosted airgap Palet controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ```` + ``` 12. Update the cert-manager chart using the following command. diff --git a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md index 01e501de477..2893d22aed0 100644 --- a/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md +++ b/docs/docs-content/vertex/upgrade/upgrade-k8s/airgap.md @@ -271,16 +271,13 @@ Kubernetes. Append `` to each image, along with the `` where you want to store your images. - image: cainjectorImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" - controllerImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" - webhookImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" - amceResolverImage: - "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - - ```` + ```yaml + image: + cainjectorImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-cainjector:v1.19.3-spectro-4.8.b" + controllerImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" + webhookImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" + amceResolverImage: "//us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" + ``` In the example below, we used `harbor.docs.spectro.dev` for the registry and `spectro-images` for the repository. @@ -290,7 +287,7 @@ Kubernetes. controllerImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-controller:v1.19.3-spectro-4.8.b" webhookImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-webhook:v1.19.3-spectro-4.8.b" amceResolverImage: "harbor.docs.spectro.dev/spectro-images/us-docker.pkg.dev/palette-images-fips/palette/spectro-cert-manager/cert-manager-acmesolver:v1.19.3-spectro-4.8.b" - ```` + ``` 11. Update the cert-manager chart using the following command.