Enabling Hybrid Applications when integrated with Red Hat Advanced Cluster Management
After you integrate IBM Cloud Pak for Multicloud Management with Red Hat® Advanced Cluster Management for Kubernetes and disable the Multicloud Management Core, the Hybrid Application Model capabilities are not enabled. To enable the capabilities for creating and managing hybrid applications, you need to deploy the hybrid application operator to your managed cluster.
With the Hybrid Application Model you can create applications and application resources across different deployment platforms, manage the lifecycle of your applications and infrastructure, and deliver observability for the application’s full stack. This model includes default Kubernetes resource definitions and custom resource definitions to represent and manage application components. Hybrid applications can include application resources that are based on the Kubernetes Special Interest Groups (SIG) Application model and based on custom resources that represent non-Kubernetes resources. For instance, you can use the custom resources to represent non-Kuberenetes resources such as virtual machines, cloud services, and containers. For more information, see Managing hybrid applications.
Procedure
-
Log in to your hub cluster using the CLI tool:
oc login --token=*YOUR_TOKEN* --server=*YOUR_SERVER_URL*
-
Configure the hybrid application YAML (
hybridapp.yaml
) file to change the values for thenamespace
andcluster-name
. The following sample file shows the location of thenamespace
andcluster-name
settings within a full YAML file.apiVersion: work.open-cluster-management.io/v1 kind: ManifestWork metadata: name: deploy-hybridapp namespace: kmc2 spec: workload: manifests: - apiVersion: apiextensions.k8s.io/v1beta1 kind: CustomResourceDefinition metadata: name: deployers.core.hybridapp.io spec: group: core.hybridapp.io names: kind: Deployer listKind: DeployerList plural: deployers singular: deployer scope: Namespaced subresources: status: {} validation: openAPIV3Schema: description: Deployer is the Schema for the deployers API properties: apiVersion: description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' type: string kind: description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string metadata: type: object spec: description: DeployerSpec defines the desired state of Deployer properties: capabilities: items: description: PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to. properties: apiGroups: description: APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. items: type: string type: array nonResourceURLs: description: NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, inal step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as "pods" or "secrets") or non-resource URL paths (such as "/api"), but not both. items: type: string type: array resourceNames: description: ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. items: type: string type: array resources: description: Resources is a list of resources this rule applies to. ResourceAll represents all resources. items: type: string type: array verbs: description: Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds. items: type: string type: array required: - verbs type: object type: array clusterScope: type: boolean operatorRef: description: ObjectReference contains enough information to let you inspect or modify the referred object. properties: apiVersion: description: API version of the referent. type: string fieldPath: description: 'If referring to a piece of an object instead of an entire object, this string should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2]. For example, if the object reference is to a container within a pod, this would take on a value like: "spec.containers{name}" (where "name" refers to the name of the container that triggered the event) or if no container name is specified "spec.containers[2]" (container with index 2 in this pod). This syntax is chosen only to have some well-defined way of referencing a part of an object. TODO: this design is not final and this field is subject to change in the future.' type: string kind: description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' type: string name: description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' type: string namespace: description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/' type: string resourceVersion: description: 'Specific resourceVersion to which this reference is made, if any. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency' type: string uid: description: 'UID of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids' type: string type: object placementTarget: description: GroupVersionResource unambiguously identifies a resource. It doesn't anonymously include GroupVersion to avoid automatic coersion. It doesn't use a GroupVersion to avoid custom marshalling properties: group: type: string resource: type: string version: type: string required: - group - resource - version type: object type: description: 'Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file Add custom validation using kubebuilder tags: https://book-v1.book.kubebuilder.io/beyond_basics/generating_crd.html' type: string required: - type type: object status: description: DeployerStatus defines the observed state of Deployer type: object type: object version: v1alpha1 versions: - name: v1alpha1 served: true storage: true - kind: ServiceAccount apiVersion: v1 metadata: name: endpoint-appmgr namespace: open-cluster-management-agent-addon - kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: endpoint-appmgr rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' - kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: name: endpoint-appmgr roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: endpoint-appmgr subjects: - kind: ServiceAccount name: endpoint-appmgr namespace: open-cluster-management-agent-addon - kind: Deployment apiVersion: apps/v1 metadata: name: endpoint-appmgr namespace: open-cluster-management-agent-addon labels: app: application-manager spec: replicas: 1 revisionHistoryLimit: 2 selector: matchLabels: app: application-manager template: metadata: labels: app: application-manager annotations: productName: "IBM Multicloud Manager - Klusterlet" productID: "c18240a57c1c41969d5e81b39435da6c" productVersion: "3.2.1" spec: serviceAccountName: endpoint-appmgr imagePullSecrets: - name: ibm-management-pull-secret containers: - name: ham-resource-discoverer image: docker-na-public.artifactory.swg-devops.com/hyc-cloud-private-integration-docker-local/ibmcom/ham-resource-discoverer:2.3.6 imagePullPolicy: Always env: - name: WATCH_NAMESPACE value: "" - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: OPERATOR_NAME value: "ham-resource-discoverer" resources: limits: cpu: 500m memory: 2Gi requests: cpu: 100m memory: 128Mi securityContext: privileged: false readOnlyRootFilesystem: false allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 1000 capabilities: drop: - ALL command: ["/usr/local/bin/entrypoint"] args: - --alsologtostderr - --cluster-name=kmc2 - --hub-cluster-configfile=/var/run/klusterlet/kubeconfig livenessProbe: exec: command: - ls initialDelaySeconds: 15 periodSeconds: 15 readinessProbe: exec: command: - ls initialDelaySeconds: 15 periodSeconds: 15 volumeMounts: - name: klusterlet-config mountPath: /var/run/klusterlet volumes: - name: klusterlet-config secret: secretName: application-manager-hub-kubeconfig
-
Replace the value for the
cluster-name
withyour-cluster-name
in the file:sed -i -e 's/managedcluster/<your-cluster-name>/g' hybridapp.yaml
-
Apply the
hybridapp.yaml
to deploy the hybrid application operator:kubectl apply -f hybridapp.yaml
-
Verify that the manifestwork
cp4m-hybridapp
is created within the namespaceyour-cluster-name
kubectl get manifestwork -n <your-cluster-name> NAME AGE cp4m-hybridapp 3h16m