### Example output of clusteradm join command Source: https://open-cluster-management.io/docs/getting-started/installation/register-cluster-via-grpc Example output from the clusteradm get token command, showing the format of the join command with placeholders for the token, API server URL, and cluster name. ```bash clusteradm join --hub-token --hub-apiserver --cluster-name ``` -------------------------------- ### Install clusteradm development version Source: https://open-cluster-management.io/docs/getting-started/installation/start-the-control-plane Installs the latest development version (main branch) of clusteradm to $GOPATH/bin/ using go get. ```bash # Installing clusteradm to $GOPATH/bin/ GO111MODULE=off go get -u open-cluster-management.io/clusteradm/... ``` -------------------------------- ### clusteradm install output Source: https://open-cluster-management.io/docs/getting-started/administration/upgrading Expected output after running the install command. Shows the CLI being detected, reinstalled, and installed into /usr/local/bin, along with the version and download URL. ```text Getting the latest clusteradm CLI... Your system is darwin_amd64 clusteradm CLI is detected: Reinstalling clusteradm CLI - /usr/local/bin/clusteradm... Installing v0.1.0 OCM clusteradm CLI... Downloading https://github.com/open-cluster-management-io/clusteradm/releases/download/v0.1.0/clusteradm_darwin_amd64.tar.gz ... clusteradm installed into /usr/local/bin successfully. To get started with clusteradm, please visit https://open-cluster-management.io/getting-started/ ``` -------------------------------- ### Install cluster-proxy addon with helm Source: https://open-cluster-management.io/docs/getting-started/integration/cluster-proxy Installs the cluster-proxy addon into the open-cluster-management-addon namespace, creating the namespace if needed. ```bash $ helm install -n open-cluster-management-addon --create-namespace \ cluster-proxy ocm/cluster-proxy ``` -------------------------------- ### Verify MultiKueue Setup Source: https://open-cluster-management.io/docs/scenarios/clusterprofile-access-providers Commands to verify the MultiKueue setup: list ClusterProfiles in the kueue-system namespace, list MultiKueueClusters, and check the status conditions of a specific MultiKueueCluster (cluster1). ```bash # Check ClusterProfiles kubectl -n kueue-system get clusterprofiles # Check MultiKueueClusters kubectl get multikueuecluster # Verify a specific MultiKueueCluster is active kubectl get multikueuecluster cluster1 -o jsonpath='{.status.conditions}' ``` -------------------------------- ### Install cluster-proxy with proxyServer.entrypointAddress set Source: https://open-cluster-management.io/docs/getting-started/integration/cluster-proxy For non-Kind clusters (e.g., OpenShift), configure the proxy server entrypoint address at install time using the --set flag. ```bash $ helm install -n open-cluster-management-addon --create-namespace \ cluster-proxy ocm/cluster-proxy \ --set "proxyServer.entrypointAddress=
" ``` -------------------------------- ### Install OpenTelemetry addon with automatic Prometheus stack and certificate generation Source: https://open-cluster-management.io/docs/getting-started/administration/monitoring Commands to clone the addon-contrib repository, navigate to the open-telemetry-addon directory, and run make install-all to install certificates, Prometheus, and the addon on the hub cluster. ```bash # Clone the repository git clone https://github.com/open-cluster-management-io/addon-contrib.git cd addon-contrib/open-telemetry-addon # Install everything (certificates, prometheus, addon) oc config use-context kind-hub # run it in hub cluster make install-all ``` -------------------------------- ### Install Argo CD on the Hub cluster Source: https://open-cluster-management.io/docs/getting-started/integration/app-lifecycle Creates the argocd namespace and applies the standard Argo CD installation manifests. ```bash kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml ``` -------------------------------- ### Install clusteradm CLI Source: https://open-cluster-management.io/docs/getting-started/administration/upgrading Downloads and runs the official install script for the clusteradm CLI, which installs the latest version into /usr/local/bin. Requires an existing OCM environment with registration-operator running. ```bash $ curl -L https://raw.githubusercontent.com/open-cluster-management-io/clusteradm/main/install.sh | bash ``` -------------------------------- ### Install the OCM Argo CD add-on Source: https://open-cluster-management.io/docs/getting-started/integration/app-lifecycle Installs the OCM Argo CD add-on on the hub cluster. ```bash clusteradm install hub-addon --names argocd ``` -------------------------------- ### Install managed-serviceaccount addon with Helm and verify pod Source: https://open-cluster-management.io/docs/getting-started/integration/managed-serviceaccount Installs the managed-serviceaccount addon via Helm into the open-cluster-management-addon namespace and verifies the addon manager pod is running. ```bash $ helm install -n open-cluster-management-addon --create-namespace \ managed-serviceaccount ocm/managed-serviceaccount $ kubectl -n open-cluster-management-addon get pod NAME READY STATUS RESTARTS AGE managed-serviceaccount-addon-manager-5m9c95b7d8-xsb94 1/1 Running 1 4d4h ... ``` -------------------------------- ### InstallByLabelStrategy for automatic installation Source: https://open-cluster-management.io/docs/developer-guides/addon Creates ManagedClusterAddOn for selected managed cluster namespaces based on a label selector. Specify the install namespace and label selector to target specific clusters. Configure this strategy on the agent add-on to enable automatic installation. ```go installStrategy := &agent.InstallStrategy{ Type: agent.InstallByLabel, InstallNamespace: "open-cluster-management-agent-addon", LabelSelector: &metav1.LabelSelector{...}, } ``` -------------------------------- ### Verify hub controller pods after installation Source: https://open-cluster-management.io/docs/getting-started/integration/app-lifecycle Expected output after successful installation, showing the argocd-agent-principal and argocd-pull-integration-controller pods running. ```bash $ kubectl -n argocd get pods NAME READY STATUS RESTARTS AGE argocd-agent-principal-xxx 1/1 Running 0 2m argocd-pull-integration-controller-xxx 1/1 Running 0 2m argocd-applicationset-controller-xxx 1/1 Running 0 2m ... ``` -------------------------------- ### Install cluster-proxy Addon with ClusterProfile Flags Source: https://open-cluster-management.io/docs/scenarios/clusterprofile-access-providers Installs the cluster-proxy addon with the flags required for ClusterProfile support: userServer.enabled=true, enableServiceProxy=true, and featureGates.clusterProfileAccessProvider=true (required to provision access providers). ```bash helm install cluster-proxy ocm/cluster-proxy \ -n open-cluster-management-addon \ --create-namespace \ --set userServer.enabled=true \ --set enableServiceProxy=true \ --set featureGates.clusterProfileAccessProvider=true ``` -------------------------------- ### Configure InstallStrategy on agent add-on Source: https://open-cluster-management.io/docs/developer-guides/addon Configures the install strategy for the agent add-on factory. Use this to enable automatic installation of the add-on. The strategy must be defined before building the agent add-on template. ```go agentAddon, err := addonfactory.NewAgentAddonFactory(addonName, FS, "manifests"). WithInstallStrategy(installStrategy). BuildTemplateAgentAddon() ``` -------------------------------- ### Build addon manager image Source: https://open-cluster-management.io/docs/developer-guides/addon Builds the addon manager image from the addon-framework repository. The resulting image contains several example addon managers, including the busybox example. ```bash git clone https://github.com/open-cluster-management-io/addon-framework.git cd addon-framework make images ``` -------------------------------- ### Policy status example Source: https://open-cluster-management.io/docs/getting-started/integration/policy-controllers/policy Example status block showing the Policy status when bound to a Placement using a PlacementBinding. It reports compliance and lists each matching cluster. ```yaml status: compliant: Compliant placement: - placement: placement-hub-cluster placementBinding: binding-policy-namespace status: - clustername: local-cluster clusternamespace: local-cluster compliant: Compliant ``` -------------------------------- ### Confirm managed clusters and clusterset Source: https://open-cluster-management.io/docs/scenarios/distribute-workload-with-placement Shows the expected output of clusteradm get clusters and clusteradm get clustersets after setup. ```bash $ clusteradm get clusters NAME ACCEPTED AVAILABLE CLUSTERSET CPU MEMORY KUBERNETES VERSION cluster1 true True default 24 49265496Ki v1.23.4 cluster2 true True default 24 49265496Ki v1.23.4 ``` ```bash $ clusteradm get clustersets NAME BOUND NAMESPACES STATUS default 2 ManagedClusters selected ``` -------------------------------- ### Setup dev environment by kind Source: https://open-cluster-management.io/docs/scenarios/distribute-workload-with-placement Runs a script to set up a local development environment using kind. ```bash curl -sSL https://raw.githubusercontent.com/open-cluster-management-io/OCM/main/solutions/setup-dev-environment/local-up.sh | bash ``` -------------------------------- ### Setup hub and managed cluster Source: https://open-cluster-management.io/docs/getting-started/quick-start Quickly sets up a hub cluster and 2 managed clusters using kind. ```bash curl -L https://raw.githubusercontent.com/open-cluster-management-io/OCM/main/solutions/setup-dev-environment/local-up.sh | bash ``` -------------------------------- ### Deploy guestbook-app-set Source: https://open-cluster-management.io/docs/getting-started/integration/app-lifecycle Applies the example guestbook ApplicationSet manifest to the hub cluster. ```bash kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/ocm/refs/heads/main/solutions/deploy-argocd-apps-pull/example/guestbook-app-set.yaml ``` -------------------------------- ### Example output of managed cluster status Source: https://open-cluster-management.io/docs/getting-started/installation/register-cluster-via-grpc Example output from the kubectl get managedcluster command, showing the managed cluster is accepted, joined, and available. ```text NAME HUB ACCEPTED MANAGED CLUSTER URLS JOINED AVAILABLE AGE cluster1 true https://hub-grpc.example.com True True 2m ``` -------------------------------- ### Confirm addon installation via kubectl get managedclusteraddon -A Source: https://open-cluster-management.io/docs/scenarios/pushing-kube-api-requests Lists ManagedClusterAddOn resources across all namespaces to confirm that the addons are deployed and available. A new ManagedClusterAddOn is automatically created in the managed cluster's namespace for each installed addon; the output shows all three with AVAILABLE=True. ```bash $ kubectl get managedclusteraddon -A NAMESPACE NAME AVAILABLE DEGRADED PROGRESSING managed1 cluster-gateway True managed1 cluster-proxy True managed1 managed-serviceaccount True ``` -------------------------------- ### RBAC restriction error message Source: https://open-cluster-management.io/docs/scenarios/pushing-kube-api-requests This is an example error message that may appear upon first-time installation when the egress service account lacks proper RBAC permissions in the managed cluster. ```bash Error from server (Forbidden): namespaces is forbidden: User "system:serviceaccount:open-cluster-management-managed-serviceaccount:cluster-gateway" cannot list resource "namespaces" in API group "" at the cluster scope ``` -------------------------------- ### Implement addon manager main.go Source: https://open-cluster-management.io/docs/developer-guides/addon Defines the addon manager entry point. It embeds the manifests folder, builds an agent addon with addonfactory.NewAgentAddonFactory, adds it to the addon manager, and starts the manager. Requires a kubeconfig from InClusterConfig; exits on errors. ```go package main import ( "context" "embed" "os" restclient "k8s.io/client-go/rest" "k8s.io/klog/v2" "open-cluster-management.io/addon-framework/pkg/addonfactory" "open-cluster-management.io/addon-framework/pkg/addonmanager" ) //go:embed manifests var FS embed.FS const ( addonName = "busybox-addon" ) func main() { kubeConfig, err := restclient.InClusterConfig() if err != nil { os.Exit(1) } addonMgr, err := addonmanager.New(kubeConfig) if err != nil { klog.Errorf("unable to setup addon manager: %v", err) os.Exit(1) } agentAddon, err := addonfactory.NewAgentAddonFactory(addonName, FS, "manifests").BuildTemplateAgentAddon() if err != nil { klog.Errorf("failed to build agent addon %v", err) os.Exit(1) } err = addonMgr.AddAgent(agentAddon) if err != nil { klog.Errorf("failed to add addon agent: %v", err) os.Exit(1) } ctx := context.Background() go addonMgr.Start(ctx) <-ctx.Done() } ``` -------------------------------- ### Sample work.yaml content Source: https://open-cluster-management.io/docs/scenarios/distribute-workload-with-placement Example Kubernetes resource definitions for work.yaml, including a ServiceAccount and a Deployment. ```yaml apiVersion: v1 kind: ServiceAccount metadata: namespace: default name: my-sa --- apiVersion: apps/v1 kind: Deployment metadata: namespace: default name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: serviceAccountName: my-sa containers: - name: nginx image: nginx:1.14.2 ports: - containerPort: 80 ``` -------------------------------- ### Generated clusteradm join command Source: https://open-cluster-management.io/docs/getting-started/installation/start-the-control-plane Example command output by clusteradm init to register managed clusters. Save it securely; if lost, use 'clusteradm get token' to retrieve it. The --hub-apiserver URL must be network-accessible from managed clusters. ```bash clusteradm join \ --hub-token \ --hub-apiserver \ --wait \ --cluster-name ``` -------------------------------- ### Set install strategy to Manual in ClusterManagementAddOn Source: https://open-cluster-management.io/docs/developer-guides/addon Set the install strategy type to Manual in the ClusterManagementAddOn to disable automatic addon installation. ```yaml apiVersion: addon.open-cluster-management.io/v1alpha1 kind: ClusterManagementAddOn metadata: annotations: addon.open-cluster-management.io/lifecycle: "addon-manager" name: helloworld spec: installStrategy: type: Manual ``` -------------------------------- ### Install clusteradm CLI tool Source: https://open-cluster-management.io/docs/getting-started/integration/multicluster-controlplane Downloads and installs the latest release of the clusteradm command-line tool. Recommended for installing the multicluster control plane via clusteradm. ```bash curl -L https://raw.githubusercontent.com/open-cluster-management-io/clusteradm/main/install.sh | bash ``` -------------------------------- ### Run clusteradm init Source: https://open-cluster-management.io/docs/getting-started/installation/start-the-control-plane Bootstraps the cluster manager on the hub cluster. By default installs the latest release; use --bundle-version=latest for development builds. For hub cluster versions between v1.16 and v1.19, add --use-bootstrap-token. ```bash # By default, it installs the latest release of the OCM components. # Use e.g. "--bundle-version=latest" to install latest development builds. # NOTE: For hub cluster version between v1.16 to v1.19 use the parameter: --use-bootstrap-token clusteradm init --wait --context ${CTX_HUB_CLUSTER} ``` -------------------------------- ### Verify sample-nginx-pod created by policy Source: https://open-cluster-management.io/docs/getting-started/integration/policy-controllers/configuration-policy Run on the managed cluster to confirm the policy created the missing pod. The output shows the sample-nginx-pod running. ```bash $ kubectl get pod -n default NAME READY STATUS RESTARTS AGE sample-nginx-pod 1/1 Running 0 23s ``` -------------------------------- ### Verify AppliedManifestWork CRD Installation Source: https://open-cluster-management.io/docs/scenarios/deploy-kubernetes-resources Check that the AppliedManifestWork CRD is installed in the managed cluster. ```bash $ kubectl get crd appliedmanifestworks.work.open-cluster-management.io ``` -------------------------------- ### Bootstrap klusterlet for kind (Option B) Source: https://open-cluster-management.io/docs/getting-started/installation/register-cluster-via-grpc Bootstraps the klusterlet without gRPC configuration for kind clusters. This is Option B, which requires manual gRPC configuration afterwards (Step 3). ```bash clusteradm join \ --hub-token \ --hub-apiserver https://hub-grpc.example.com \ --cluster-name "cluster1" \ --wait \ --force-internal-endpoint-lookup \ --context ${CTX_MANAGED_CLUSTER} ``` -------------------------------- ### clusteradm join with resource configuration for KinD clusters Source: https://open-cluster-management.io/docs/getting-started/installation/register-a-cluster Configure CPU and memory resources for klusterlet components in hosted mode on KinD clusters. Includes --resource-qos-class, --resource-limits, and --resource-requests flags, along with --force-internal-endpoint-lookup. ```bash # Configure resource requests and limits for klusterlet components in hosted mode clusteradm join \ --hub-token \ --hub-apiserver \ --wait \ --cluster-name "cluster1" \ --mode hosted \ --managed-cluster-kubeconfig \ --resource-qos-class ResourceRequirement \ --resource-limits cpu=800m,memory=800Mi \ --resource-requests cpu=400m,memory=400Mi \ --force-internal-endpoint-lookup \ --context ``` -------------------------------- ### Verify ManifestWork CRD Installation Source: https://open-cluster-management.io/docs/scenarios/deploy-kubernetes-resources Check that the ManifestWork CRD is installed in the hub cluster. ```bash $ kubectl get crd manifestworks.work.open-cluster-management.io ``` -------------------------------- ### Example of pending CSR Source: https://open-cluster-management.io/docs/getting-started/installation/register-a-cluster Shows an example pending CSR as output of the previous watch command. ```text cluster1-tqcjj 33s kubernetes.io/kube-apiserver-client system:serviceaccount:open-cluster-management:cluster-bootstrap Pending ``` -------------------------------- ### Verify hub pods running Source: https://open-cluster-management.io/docs/getting-started/integration/policy-controllers/policy-framework Verify the policy framework hub pods are running. Expected output shows governance-policy-addon-controller and governance-policy-propagator pods in Running state. ```bash $ kubectl get pods -n ${HUB_NAMESPACE} NAME READY STATUS RESTARTS AGE governance-policy-addon-controller-bc78cbcb4-529c2 1/1 Running 0 94s governance-policy-propagator-8c77f7f5f-kthvh 1/1 Running 0 94s ``` -------------------------------- ### Create KinD cluster and set KUBECONFIG Source: https://open-cluster-management.io/docs/getting-started/integration/multicluster-controlplane Sets up a KinD cluster and exports the KUBECONFIG environment variable. Creates a cluster named multicluster-controlplane and captures the node's internal IP for later use. ```bash export KUBECONFIG=/tmp/kind-controlplane.kubeconfig kind create cluster --name multicluster-controlplane export mc_cp_node_ip=$(kubectl get nodes -o=jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}') ``` -------------------------------- ### Create guestbook ApplicationSet Source: https://open-cluster-management.io/docs/scenarios/integration-with-argocd Creates an ApplicationSet in the argocd namespace that uses the OCM Cluster Decision Resource generator and placement to deploy the guestbook application to selected managed clusters. The requeueAfterSeconds setting makes Argo CD periodically check placement decisions. ```bash cat << EOF | kubectl apply -f - apiVersion: argoproj.io/v1alpha1 kind: ApplicationSet metadata: name: guestbook-app namespace: argocd spec: generators: - clusterDecisionResource: configMapRef: ocm-placement-generator labelSelector: matchLabels: cluster.open-cluster-management.io/placement: guestbook-app-placement requeueAfterSeconds: 30 template: metadata: name: '{{clusterName}}-guestbook-app' spec: project: default source: repoURL: 'https://github.com/argoproj/argocd-example-apps.git' targetRevision: HEAD path: guestbook destination: name: '{{clusterName}}' namespace: guestbook syncPolicy: automated: prune: true syncOptions: - CreateNamespace=true EOF ``` -------------------------------- ### Install cluster-permission Addon (Optional) Source: https://open-cluster-management.io/docs/scenarios/clusterprofile-access-providers Installs the cluster-permission addon (optional) to grant specific permissions to managed service accounts on managed clusters. After installation, create ClusterPermission resources in each managed cluster namespace to define RBAC permissions. ```bash helm install cluster-permission ocm/cluster-permission \ -n open-cluster-management \ --create-namespace ``` -------------------------------- ### Configure resource requests and limits (kind) Source: https://open-cluster-management.io/docs/getting-started/installation/register-a-cluster Configures CPU and memory resources for klusterlet agent components using `clusteradm join` with `--resource-qos-class`, `--resource-limits`, and `--resource-requests` flags. Use for local testing with kind. All components use the same resource requirements. ```bash # Configure resource requests and limits for klusterlet components clusteradm join \ --hub-token \ --hub-apiserver \ --wait \ --cluster-name "cluster1" \ --resource-qos-class ResourceRequirement \ --resource-limits cpu=800m,memory=800Mi \ --resource-requests cpu=400m,memory=400Mi \ --force-internal-endpoint-lookup \ --context ${CTX_MANAGED_CLUSTER} ``` -------------------------------- ### Install OCM addons with helm (cluster-proxy, managed-serviceaccount, cluster-gateway) Source: https://open-cluster-management.io/docs/scenarios/pushing-kube-api-requests Installs the three OCM addons via helm into the open-cluster-management-addon namespace. The cluster-gateway command uses --set manualSecretManagement=false to delegate secret discovery to the managed-serviceaccount addon, and --set konnectivityEgress=true to enable konnectivity tunnels via cluster-proxy; skip the latter if hubs and managed clusters are already mutually accessible. ```bash $ helm -n open-cluster-management-addon install cluster-proxy ocm/cluster-proxy $ helm -n open-cluster-management-addon install managed-serviceaccount ocm/managed-serviceaccount $ helm -n open-cluster-management-addon install cluster-gateway ocm/cluster-gateway-addon-manager \ # Delegating for secret discovery to "managed-serviceaccount" addon. \ # Skip the option for manual secret management. \ --set manualSecretManagement=false \ # Enabling konnectivity tunnels via "cluster-proxy" addon. \ # Skip the option if the hub cluster and the managed clusters are already mutually accessible. \ --set konnectivityEgress=true ``` -------------------------------- ### Example ClusterProfile with access provider Source: https://open-cluster-management.io/docs/scenarios/clusterprofile-access-providers An example ClusterProfile object showing the accessProviders section with provider name 'open-cluster-management'. ```yaml apiVersion: multicluster.x-k8s.io/v1alpha1 kind: ClusterProfile metadata: labels: multicluster.x-k8s.io/clusterset: default open-cluster-management.io/cluster-name: cluster1 x-k8s.io/cluster-manager: open-cluster-management name: cluster1 spec: clusterManager: name: open-cluster-management displayName: cluster1 status: accessProviders: - cluster: certificate-authority-data: extensions: - extension: clusterName: cluster1 name: client.authentication.k8s.io/exec server: https://cluster-proxy-addon-user.open-cluster-management-addon:9092/cluster1 name: open-cluster-management ``` -------------------------------- ### Get kube-apiserver IP Source: https://open-cluster-management.io/docs/scenarios/register-cluster-through-proxy Command to get the IP address of the kube-apiserver on the managed cluster, which should be included in the `noProxy` field. ```bash kubectl -n default describe svc kubernetes | grep IP: ``` -------------------------------- ### Bootstrap klusterlet in singleton mode for local clusters Source: https://open-cluster-management.io/docs/getting-started/installation/register-a-cluster Use this command to bootstrap a klusterlet in singleton mode when both hub and managed clusters run locally. The --force-internal-endpoint-lookup flag is required for local testing. Replace the token, endpoint, and cluster name placeholders with your actual values. ```bash clusteradm join \ --hub-token \ --hub-apiserver \ --wait \ --cluster-name "cluster1" \ # Or other arbitrary unique name --singleton \ --force-internal-endpoint-lookup \ --context ${CTX_MANAGED_CLUSTER} ``` -------------------------------- ### Install PlacementRule CRD Source: https://open-cluster-management.io/docs/getting-started/integration/policy-controllers/policy-framework Install the PlacementRule CRD when using PlacementRules with policies. Required if not using the default Placement API. ```bash kubectl apply -f https://raw.githubusercontent.com/open-cluster-management-io/multicloud-operators-subscription/main/deploy/hub-common/apps.open-cluster-management.io_placementrules_crd.yaml ``` -------------------------------- ### Configure resource requests and limits (GKE, AKS, other cloud providers) Source: https://open-cluster-management.io/docs/getting-started/installation/register-a-cluster Configures CPU and memory resources for klusterlet agent components using `clusteradm join` with `--resource-qos-class`, `--resource-limits`, and `--resource-requests` flags. Use for cloud providers like GKE or AKS. ```bash # Configure resource requests and limits for klusterlet components clusteradm join \ --hub-token \ --hub-apiserver \ --wait \ --cluster-name "cluster1" \ --resource-qos-class ResourceRequirement \ --resource-limits cpu=800m,memory=800Mi \ --resource-requests cpu=400m,memory=400Mi \ --context ${CTX_MANAGED_CLUSTER} ``` -------------------------------- ### Install latest clusteradm release Source: https://open-cluster-management.io/docs/getting-started/installation/start-the-control-plane Downloads and installs the latest release of the clusteradm command-line tool using curl and bash. ```bash curl -L https://raw.githubusercontent.com/open-cluster-management-io/clusteradm/main/install.sh | bash ```