Skip to main content

Create and Manage Environments

Environments are defined in the PaletteAI hub cluster. Each Environment contains policies and a topology that dictates workload distribution behavior. You can create an environment that uses the topology-ocm and allows you to get started without having to manually create a Placement. However, if you want to manage your own Placement, and have more control over the Placement namespace, you can create an environment that uses the topology-ocm-byop.

info

Usually, you do not need to create or manage environments directly. When you create a compute pool, PaletteAI automatically creates an environment with a topology policy configured. This handles workload placement to the compute pool's clusters without additional setup.

This page is for advanced users who are bringing their own clusters (outside of Palette) to run workloads, or who need to customize environments beyond what compute pools provide.

Create an Environment With topology-ocm

Use the following steps to create an environment using the topology-ocm.

Prerequisites

  • A text editor of your choice, such as Vi.

  • kubectl installed and available in your $PATH.

  • The KUBECONFIG environment variable set to the path of the PaletteAI hub cluster's kubeconfig file.

    export KUBECONFIG=<kubeconfig-location>
  • At least one ClusterSet binding created and available in the hub cluster for the cluster set you want to target.

    info

    By default, PaletteAI comes with a ClusterSet binding named manged-cluster-set-global that targets the global cluster set. Review the ManagedClusterSets and ManagedClusterSetBindings section to learn more about the PaletteAI default managed cluster sets and bindings.

Enablement

  1. Create a namespace where you want the environment to be created. Replace <namespace> with the name of the namespace you want to create.

    kubectl create namespace <namespace>
    info

    Keeping all environments in the same namespace reduces complexity and allows you to manage all environments in the same place. However, different organizations and teams may want to keep their environments in different namespaces due to RBAC restrictions.

  2. Create a file named environment.yaml.

    touch environment.yaml
  3. Open the environment.yaml file in your preferred text editor and add the following content. Replace <replace-me> with the desired name of the environment and the namespace you created in step 1. Update the numberOfClusters to the number of spoke clusters you want to distribute workloads to. For example, if you want to distribute workloads to at least two spoke clusters, set numberOfClusters to 2. Otherwise, if you remove the numberOfClusters field, all eligible clusters will be selected.

    apiVersion: spectrocloud.com/v1beta1
    kind: Environment
    metadata:
    name: <replace-me>
    namespace: <replace-me>
    spec:
    topology:
    type: topology-ocm
    properties:
    manifestWorkReplicaSet:
    manifestWorkTemplate:
    lifecycle:
    spokeNamespace:
    create: true
    orphan: false
    workload:
    orphan: false
    rolloutStrategy:
    all: {}
    type: All
    hubNamespace: managed-cluster-set-global
    placement:
    numberOfClusters: 1

    If you want to configure a rollout strategy, you can do so by changing the rolloutStrategy section. Refer to the Decision Rollout Strategy documentation to learn more about the options available. You can also learn more about the lifecycle settings on the Environments page.

  4. Apply the environment to the hub cluster.

    kubectl apply --filename environment.yaml
    Example output
    environment.spectrocloud.com/demo-environment created

Validate

  1. Verify that the environment was created successfully and is in a ready state. Replace the environment name and namespace with the correct values for your environment.

    kubectl get environments <environment-name> --namespace <namespace>
    Example output
    NAME                ENVIRONMENT READY
    demo-environment True
  2. Review the environment's details. Replace the environment name and namespace with your environment's name and namespace.

    kubectl describe environment <environment-name> --namespace <namespace>
    Example output
    Name: demo-environment
    Namespace: devops-ns
    Labels: <none>
    Annotations: <none>
    API Version: spectrocloud.com/v1beta1
    Kind: Environment
    Metadata:
    Creation Timestamp: 2025-04-10T20:44:01Z
    Finalizers: spectrocloud.com/environment-finalizer
    Generation: 1
    Resource Version: 4795
    UID: d8d13859-2cc5-4f89-85f2-79d31332c568
    Spec:
    Topology:
    Properties:
    Hub Namespace: managed-cluster-set-global
    Manifest Work Replica Set:
    Manifest Work Template:
    Lifecycle:
    Spoke Namespace:
    Create: true
    Orphan: false
    Workload:
    Orphan: false
    Rollout Strategy:
    All:
    Type: All
    Placement:
    Number Of Clusters: 1
    Type: topology-ocm
    Status:
    Conditions:
    Last Transition Time: 2025-04-10T20:44:01Z
    Reason: TotalSelectedClustersGreaterThanZero
    Status: True
    Type: EnvironmentReady
    Selected Clusters:
    - hub-as-spoke
    Status: Ready
    Total Selected Clusters: 1
    Events: <none>

Create an Environment With topology-ocm-byop

For scenarios where you want more granular control over the scheduling logic and spoke cluster selection, you can create an environment using the topology-ocm-byop. The topology-ocm-byop requires a reference to a Placement resource. The Placement is what selects spoke clusters, or to be more specific, the managedClusters that are part of a ManagedClusterSet, and allows you to define priorities and constraints.

Prerequisites

  • A text editor of your choice, such as Vi.

  • kubectl installed and available in your $PATH.

  • The KUBECONFIG environment variable set to the path of the PaletteAI hub cluster's kubeconfig file.

    export KUBECONFIG=<kubeconfig-location>
  • At least one ClusterSet created and available in the hub cluster.

  • A ManagedClusterSetBinding that references at least one ClusterSet that contains the spoke clusters you want to distribute workloads to.

    info

    PaletteAI comes with a default ClusterSet named global and a ManagedClusterSetBinding that references the global cluster set. You can use the global cluster set to distribute workloads to all spoke clusters. Review the ManagedClusterSets and ManagedClusterSetBindings section to learn more about the PaletteAI default managed cluster sets and bindings.

Enablement

  1. Create a namespace where you want the environment to be created. Replace <namespace> with the name of the namespace you want to create.

    kubectl create namespace <namespace>
  2. Create a file named placement.yaml. This file will contain the Placement definition.

    touch placement.yaml
  3. Open the placement.yaml file in your preferred text editor and add the following content. Replace the placeholder values with the desired values for the name, namespace, cluster set name, and the number of clusters. Learn more about the different options available by reviewing OCM's Placement documentation.

    Example placement
    apiVersion: cluster.open-cluster-management.io/v1beta1
    kind: Placement
    metadata:
    name: <replace-me>
    namespace: <replace-me>
    spec:
    numberOfClusters: 1 # If field is omitted, all eligible clusters will be selected
    clusterSets:
    - <replace-me>
    prioritizerPolicy:
    configurations:
    - scoreCoordinate:
    builtIn: ResourceAllocatableMemory

    The Placement defined above uses a priority policy that selects the spoke cluster with the most available memory. Other capabilities, such as predicates, can be used to select clusters based on labels or claim selectors.

  4. Apply the Placement to the hub cluster.

    kubectl apply --filename placement.yaml
  5. Create a file named environment.yaml. This file will contain the Environment definition and reference the Placement you created in the previous step.

    touch environment.yaml
  6. Open the environment.yaml file in your preferred text editor and add the following content. Replace the placeholder values with the respective values for the name, namespace, placement name, and placement namespace. If you want to configure a rollout strategy, you can do so by adding the rolloutStrategy section. Refer to the Decision Rollout Strategy documentation to learn more about the options available.

    apiVersion: spectrocloud.com/v1beta1
    kind: Environment
    metadata:
    name: <replace-me>
    namespace: <replace-me>
    spec:
    topology:
    type: topology-ocm-byop
    properties:
    manifestWorkReplicaSet:
    placementRefs:
    - name: <replace-me>
    rolloutStrategy:
    all: {}
    type: All
    placementNamespace: <replace-me>
  7. Apply the environment to the hub cluster.

    kubectl apply --filename environment.yaml
    Example output
    environment.spectrocloud.com/demo-environment created

Validate

Verify that the environment was created successfully and is in a ready state. Replace the environment name and namespace with the correct values for your environment.

kubectl get environments <environment-name> --namespace <namespace>
Example output
NAME                ENVIRONMENT READY
demo-environment True

Create an Environment With Policies

An environment can contain policies that you can use to override component or trait properties. Use the following steps to create an environment with a policy.

Prerequisites

Enablement

  1. Create a namespace where you want the environment to be created. Replace <namespace> with the name of the namespace you want to create.

    kubectl create namespace <namespace>
  2. Create a file named environment.yaml.

    touch environment.yaml
  3. Open the environment.yaml file in your preferred text editor and add the following content. Replace <replace-me> with the desired name of the environment and the namespace you created in step 1. The example below overrides the trait resources to set the CPU limit to 1000m for all components in the workload that are using the resources trait.

    apiVersion: spectrocloud.com/v1beta1
    kind: Environment
    metadata:
    name: <replace-me>
    namespace: <replace-me>
    spec:
    topology:
    type: topology-ocm
    properties:
    manifestWorkReplicaSet:
    manifestWorkTemplate:
    lifecycle:
    spokeNamespace:
    create: true
    orphan: false
    workload:
    orphan: false
    rolloutStrategy:
    all: {}
    type: All
    hubNamespace: managed-cluster-set-global
    placement:
    numberOfClusters: 1
    policies:
    - name: increase-cpu
    type: override
    properties:
    components:
    - traits:
    - type: resources
    properties:
    limits:
    cpu: '1000m'

    Check out the Override Policy page to learn more about each policy.

  4. Apply the environment to the hub cluster.

    kubectl apply --filename environment.yaml
    Example output
    environment.spectrocloud.com/demo-environment created

Validate

  1. Verify that the environment was created successfully and is in a ready state. Replace the environment name and namespace with the correct values for your environment.

    kubectl get environments <environment-name> --namespace <namespace>
    Example output
    NAME                ENVIRONMENT READY
    demo-environment True
  2. To review the environment's details, use the command below. Replace the environment name and namespace with your environment's name and namespace.

    kubectl describe environment <environment-name> --namespace <namespace>
  3. Check the output and verify the Spec.Policies section contains the policy you defined. The output below is condensed for brevity.

    ...
    Spec:
    Policies:
    Name: limit-cpu
    Properties:
    Components:
    Traits:
    Properties:
    Limits:
    Cpu: 1000m
    Type: resources
    Type: override
    Topology:
    ...

Delete an Environment

If you need to remove an environment, you can do so by deleting the environment resource. Keep in mind that you cannot delete an environment if there are WorkloadDeployment resources that are referencing the environment.

tip

Use the command kubectl get workloaddeployments --all-namespaces in the hub cluster to verify that no WorkloadDeployment resources are referencing the environment. The output contains a column titled ENVIRONMENT-NS that contains the namespace of the environment.

Prerequisites

  • kubectl installed and available in your $PATH.

  • The KUBECONFIG environment variable set to the path of the PaletteAI hub cluster's kubeconfig file.

    export KUBECONFIG=<kubeconfig-location>
  • No active WorkloadDeployment resources referencing the environment you want to delete.

Enablement

Delete the environment using the command below. Replace the environment name and namespace with your environment's name and namespace.

kubectl delete environment <environment-name> --namespace <namespace>
Example output
environment.spectrocloud.com "demo-environment" deleted
tip

If you get an error message stating that the environment is still being referenced by a WorkloadDeployment, you will need to update the respective WorkloadDeployment resource and reference a different environment.

Example error
Error from server: admission webhook "validating.spectrocloud.com.v1beta1.environments" denied the request: unable to delete Environment hello-universe/demo-environment as WorkloadDeployment hello-universe/hello-universe-demo references it

Validate

You can verify that the environment was deleted successfully by using the following command. Replace the environment name and namespace with your deleted environment's name and namespace.

kubectl get environments <environment-name> --namespace <namespace>

If the environment was deleted successfully, the output will contain an error message stating that the environment was not found.

Alternatively, you can verify that the environment was deleted successfully by using the following command.

kubectl get environments --all-namespaces

If the environment was deleted successfully, the output will not contain the environment you deleted.