[Draft] Guide: Setting Up a Restricted-Access OpenShift Cluster for SAP EdgeLM

Updated -

Table of Contents

Overview

This guide provides step-by-step instructions for onboarding a shared Red Hat OpenShift cluster into SAP Edge Lifecycle Management (ELM) using a restricted-privilege model. Instead of requiring full cluster-admin rights, ELM will use a dedicated Service Account with a precise, limited set of permissions. The official source of truth for this process is SAP Note 3598460, and this guide serves as an extension of the information provided therein. You can find the note here: https://me.sap.com/notes/3598460.

Intended Audience: This document is for Red Hat OpenShift Cluster Administrators responsible for preparing the cluster environment.

Process Overview

The setup process consists of five main stages:

  1. Prepare Namespaces: Create and configure the dedicated namespaces where all components will reside.
  2. Configure Service Mesh: Deploy and customize the Red Hat OpenShift Service Mesh to manage network traffic.
  3. Apply Permissions (RBAC): Apply the specific, fine-grained permissions that the ELM Service Account needs to operate.
  4. Generate Kubeconfig File: Create a unique Kubeconfig file that authenticates using the newly created Service Account.
  5. Register the Cluster in ELM: Use the generated Kubeconfig to add the cluster as an Edge Node in the ELM user interface.

Step 1: Prepare Namespaces

First, create the required namespaces to isolate the application components. You'll also apply annotations to these namespaces, which are necessary for OpenShift's Security Context Constraints (SCCs). These annotations pre-assign specific User ID (UID) and group ID ranges, ensuring that pods run with the minimum required privileges.

This single block of commands will create all the required namespaces and apply the necessary security annotations and service mesh labels.

# --- Create all required namespaces ---
oc create namespace edgelm  
oc create namespace istio-gateways  
oc create namespace edge-icell  
oc create namespace edge-icell-secrets  
oc create namespace edge-icell-ela  
oc create namespace edge-icell-services
oc create namespace istio-system

# --- Label namespaces for Service Mesh auto-injection ---
oc label namespace edgelm edge-icell edge-icell-secrets edge-icell-ela edge-icell-services istio-system istio-discovery=enabled istio-injection=enabled

# --- Apply the necessary security annotations for SCCs ---
oc annotate namespace edgelm openshift.io/sa.scc.supplemental-groups="67000/1000" --overwrite
oc annotate namespace edge-icell openshift.io/sa.scc.uid-range="10000/100" --overwrite
oc annotate namespace edge-icell openshift.io/sa.scc.supplemental-groups="1000/100" --overwrite
oc annotate namespace edge-icell-ela openshift.io/sa.scc.uid-range="10000/1000" --overwrite
oc annotate namespace edge-icell-ela openshift.io/sa.scc.supplemental-groups="100002/1000" --overwrite
oc annotate namespace edge-icell-services openshift.io/sa.scc.uid-range="100000/1000" --overwrite
oc annotate namespace edge-icell-services openshift.io/sa.scc.supplemental-groups="1000002/1000" --overwrite

Step 2: Configure OpenShift Service Mesh

The SAP Note requires a service mesh to be present. This guide provides a specific, tested configuration for Red Hat OpenShift Service Mesh version 2.x. Support for Red Hat OpenShift Service Mesh 3.x is currently ongoing, and this document will be updated upon official validation.

Key Requirement:

  • OpenShift Service Mesh 2.x Operator needs to be installed by following the steps described in 2.8 Installing the OpenShift Service Mesh Operators
  • The Service Mesh control plane must be installed by following the sections below, typically in the istio-system namespace.

These commands will deploy a standard Service Mesh Control Plane and create a ServiceMeshMemberRoll to include the required namespaces in the mesh. You can adjust the addons according to your requirement.

# --- Command 1: Create the ServiceMeshControlPlane in the 'istio-system' namespace ---
oc apply -f - <<EOF
apiVersion: maistra.io/v2
kind: ServiceMeshControlPlane
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.6
  policy:
    type: Istiod
  telemetry:
    type: Istiod
  addons:
    prometheus:
      enabled: true
    kiali:
      enabled: false
    grafana:
      enabled: true
  security:
    identity:
      type: ThirdParty
  gateways:
    enabled: true
    egress:
      enabled: true
      service: {}
    ingress:
      enabled: true
      service:
        type: LoadBalancer
    openshiftRoute:
      enabled: true
EOF

# --- Command 2: Create the ServiceMeshMemberRoll to add namespaces to the mesh ---
oc apply -f - <<EOF
apiVersion: maistra.io/v1
kind: ServiceMeshMemberRoll
metadata:
  name: default
  namespace: istio-system
spec:
  members:
    - edgelm
    - edge-icell
    - istio-gateways  
    - edge-icell-services
    - edge-icell-secrets
    - edge-icell-ela
EOF

Optional Service Mesh Configurations

The following configurations can be applied to your ServiceMeshControlPlane if required by your environment.

A) Enable HTTP 1.0 Protocol

If your environment requires features like HTTP/1.0 support or Client IP Preservation, you must edit the ServiceMeshControlPlane resource you created above. The following sections provide the complete, modified YAML for each case.

Enable HTTP/1.0 Protocol (Optional)

To enable support for HTTP/1.0 traffic, apply the full YAML configuration below. This version adds the required runtime sections to the base configuration.

kind: ServiceMeshControlPlane
apiVersion: maistra.io/v2
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.6 # this can be different
  policy:
    type: Istiod
  telemetry:
    type: Istiod
  addons:
    prometheus:
      enabled: true
    kiali:
      enabled: false
    grafana:
      enabled: true
  # Additional configuration for the control plane
  security:
    identity:
      type: ThirdParty
  gateways:
    openshiftRoute:
      enabled: true
    egress:
      enabled: true
      service: {}
    enabled: true
    ingress:
      enabled: true
      service:
        type: LoadBalancer
      # Additional configuration to enable HTTP 1.0 support
      runtime:
        container:
          env:
            ISTIO_META_HTTP10: '1'
  # Additional configuration to enable HTTP 1.0 support
  runtime:
    components:
      pilot:
        container:
          env:
            ISTIO_META_HTTP10: '1'
B) Enable Client IP Preservation

Use this configuration when you need to preserve the original client IP address of incoming requests. This is often required for auditing, security logging, or geolocation-based services. By default, the source IP might be translated by network proxies.

kind: ServiceMeshControlPlane
apiVersion: maistra.io/v2
metadata:
  name: basic
  namespace: istio-system
spec:
  version: v2.6 # this can be different
  policy:
    type: Istiod
  telemetry:
    type: Istiod
  addons:
    prometheus:
      enabled: true
    kiali:
      enabled: false
    grafana:
      enabled: true
  # Additional configuration for the control plane
  security:
    identity:
      type: ThirdParty
  gateways:
    openshiftRoute:
      enabled: true
    egress:
      enabled: true
      service: {}
    enabled: true
    ingress:
      enabled: true
      service:
        type: LoadBalancer
        # Additional configuration to enable client IP preservation
        externalTrafficPolicy: Local
        metadata:
          annotations:
            service.beta.kubernetes.io/aws-load-balancer-type: "nlb"

Step 3: Apply Permissions (RBAC)

This step configures the necessary Role-Based Access Control (RBAC) permissions. It applies required Custom Resource Definitions (CRDs), an admission webhook, cluster-wide roles, and specific roles within each namespace. All referenced YAML files are provided in the resources.zip archive attached to the SAP Note.

Cluster-Wide Permissions

# Apply required CRDs and ClusterRoles  
oc apply -f cr-edgelm-cluster-admin.yaml
oc apply -f crb-edgelm-cluster-admin.yaml
oc apply -f crd-helms.yaml
oc apply -f crd-imagereplications.yaml
oc apply -f crd-replicationservices.yaml
oc apply -f crd-sapcloudconnectors.yaml
oc apply -f crd-sourceregistries.yaml
oc apply -f crd-systemmappings.yaml
oc apply -f crd-solacesoftwarebrokers.yaml
# Apply the admission webhook  
oc apply -f webhook-pod-initializer.yaml

Namespace-Specific Permissions

# --- Permissions for 'edgelm' namespace ---
oc apply -f role-edgelm-manage.yaml -n edgelm 
oc apply -f rb-edgelm-manage.yaml -n edgelm 
oc apply -f role-edgelm-admin.yaml -n edgelm
oc apply -f rb-edgelm-admin.yaml -n edgelm

# --- Permissions for 'istio-gateways' namespace ---
oc apply -f role-edgelm-manage.yaml -n istio-gateways 
oc apply -f rb-edgelm-manage.yaml -n istio-gateways 
oc apply -f role-istio-gateways-admin.yaml -n istio-gateways
oc apply -f rb-istio-gateways-admin.yaml -n istio-gateways

# --- Permissions for 'edge-icell' namespace ---
oc apply -f role-edgelm-manage.yaml -n edge-icell 
oc apply -f rb-edgelm-manage.yaml -n edge-icell 
oc apply -f role-edge-icell.yaml -n edge-icell
oc apply -f rb-edge-icell.yaml -n edge-icell
oc apply -f rb-edge-icell-admin.yaml -n edge-icell


# --- Permissions for 'edge-icell-secrets' namespace --- 
oc apply -f role-edgelm-manage.yaml -n edge-icell-ela 
oc apply -f rb-edgelm-manage.yaml -n edge-icell-ela 
oc apply -f role-edge-icell-ela.yaml -n edge-icell-ela
oc apply -f rb-edge-icell-ela.yaml -n edge-icell-ela
oc apply -f rb-edge-icell-ela-admin.yaml -n edge-icell-ela


# --- Permissions for 'edge-icell-secrets' namespace ---  
oc apply -f role-edgelm-manage.yaml -n edge-icell-secrets 
oc apply -f rb-edgelm-manage.yaml -n edge-icell-secrets 
oc apply -f rb-edge-icell-secrets-admin.yaml -n edge-icell-secrets

# --- Permissions for 'edge-icell-services' namespace ---  
oc apply -f role-edgelm-manage.yaml -n edge-icell-services 
oc apply -f rb-edgelm-manage.yaml -n edge-icell-services 
oc apply -f role-edge-icell-services.yaml -n edge-icell-services
oc apply -f rb-edge-icell-services.yaml -n edge-icell-services
oc apply -f rb-edge-icell-services-admin.yaml -n edge-icell-services

Step 4: Generate Kubeconfig File

This script creates the edgelm Service Account and generates a kubeconfig.txt file using a persistent, non-expiring token. ELM will use this file to authenticate to your cluster.

# --- 1. Create the 'edgelm' service account in the 'edgelm' namespace ---  
oc create sa edgelm -n edgelm

# --- 2. Create a secret to hold the long-lived service account token ---  
oc apply -n edgelm -f - <<EOF  
apiVersion: v1  
kind: Secret  
metadata:  
name: edgelm-token  
annotations:  
kubernetes.io/service-account.name: edgelm  
type: kubernetes.io/service-account-token  
EOF

# --- 3. Extract the token and generate the Kubeconfig file ---  
export SECRET_NAME_SA=edgelm-token  
export TOKEN_SA=$(oc get secret ${SECRET_NAME_SA} -n edgelm -ojsonpath='{.data.token}' | base64 -d)  
oc config view --raw --minify > kubeconfig.txt  
oc config unset users --kubeconfig=kubeconfig.txt  
oc config set-credentials edgelm --kubeconfig=kubeconfig.txt --token=${TOKEN_SA}  
oc config set-context --current --kubeconfig=kubeconfig.txt --user=edgelm

echo "Kubeconfig file 'kubeconfig.txt' has been generated successfully."

Step 5: Register the Cluster in ELM

You are now ready to add your cluster as a new Edge Node in the ELM UI.

  1. In the ELM UI, start the Add an Edge Node process.
  2. On the first stage, Provide Edge Node Details, enter a name for your Edge Node.
  3. Crucially, select the checkbox for Restricted Access to Kubernetes cluster.
  4. When prompted for the Kubeconfig, provide the contents of the kubeconfig.txt file you just created.
  5. Proceed with the rest of the configuration as guided by the UI.

Comments