Adding local scratch devices to DataStage pods

You can help ensure that you do not run out of data storage by adding local scratch devices, which use the EmptyDir volume, to DataStage pods.

If the EmptyDir volume is bare metal, it is the root volume of the nodes unless you specify a dedicated device during the installation. OpenShift® does not enforce quotas on EmptyDir by default. If your pod uses up whole disk space, other pods do not work any longer. If you need to continue to use EmptyDir, you need to pay attention to the disk usage to not run out of space.

If you are expecting to process large amount of data with DataStage®, it is best to install dedicated disks to the worker nodes and assign them as a scratch device. Doing so helps eliminate concern about the impact to other pods when you run out of space. You can create a Persistent Volume (PV) from your local disk and allocate the scratch disk space on this PV.

Procedure

  1. Installing a new disk device to the worker nodes
  2. Creating a PV
  3. Mounting the PVC to a PX runtime instance
  4. Changing the configuration file

Installing a new disk device to the worker nodes

If you can afford to allocate disks to all worker nodes, it makes your scheduling easier. If not, you need to at least add the disk to the same number of worker nodes as the number of DataStage engine pods. Because Cloud Pak for Data uses a StatefulSet to instantiate DataStage engine pods, the scheduler tends to assign one pod per worker node. If not all worker nodes get the disk, the scheduler still assigns the pod to the node where the device is available, but it would not tolerate any machine failure or outage. Refer to the OpenShift document to learn more about the scheduling.

This example assumes that you already attached a new device to the worker node and its device is /dev/sdb. Log in to the worker node with the core user. All operations in this step require root privilege, so use the sudo su - command to become the root user.
[core@worker1 ~]$ sudo su -
  1. Create the file system on the new device and mount it at /var/mnt/scratch:
    mkfs.ext4 /dev/sdb
    mkdir /var/mnt/scratch
    mount /dev/sdb /var/mnt/scratch
    chmod -R 777 /var/mnt/scratch
    semanage fcontext -a -t svirt_sandbox_file_t '/var/mnt/scratch(/.*)?'
    restorecon -RFv /var/mnt/scratch

    This set of commands also assigns the svirt_sandbox_file_t label to the directory to allow the access from the container, which is necessary because SELinux is turned on by default on CoreOS.

  2. Make the mount volume persistent.
    1. Create a mount file in the /etc/systemd/system directory. The naming of the file is important. You need to name the file like the following example:
      <directory_path>-<mount_name>.mount
      
    2. Put a dash "-" between the directories. In this example, the volume is mounted at /var/mnt/scratch. The file name must be var-mnt-scratch.mount. If you do not follow this naming rule, the command to enable this mount fails. See the following example content:
      [Unit]
      Description = Mount a device for scratch
      
      [Mount]
      What=/dev/sdb
      Where=/var/mnt/scratch
      Type=ext4
      
      [Install]
      WantedBy = local-fs.target
    3. Run the systemctl command:
      [root@worker1 ~]# systemctl enable --now /etc/systemd/system/var-mnt-scratch.mount
      
    4. Repeat these steps on all nodes.
      Tip: If you create a script, this process can be much easier.

Creating a PV

  1. Log off from the worker node and come back to your workstation. The device is available on the worker nodes and a PV can be created with it.
  2. Create the PV according to the following example:
    cat << EOF | oc -n $CPD_INSTANCE_NS apply -f -
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: pv-scratch
      labels:
        type: local
    spec:
      storageClassName: local-scratch-class
      capacity:
        storage: 100Gi
      accessModes:
        - ReadWriteOnce
      hostPath:
        path: "/var/mnt/scratch"
    EOF
    
  3. Create a persistent volume claim (PVC) that is to be used in the DataStage engine pods:
    cat << EOF | oc -n $CPD_INSTANCE_NS apply -f -
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-scratch-manual
    spec:
      storageClassName: local-scratch-class
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 100Gi
    EOF
    
  4. Check to see whether the PV was created:
    [root@mymachine ~]# oc get pvc | grep scratch
    pvc-scratch-manual                            Bound    pv-scratch                                 100Gi       RWO            local-scratch-class   22d

    The status Bound appears if the process was successful.

Mounting the PVC to a PX runtime instance

To mount the new PVC to a PX runtime instance, add the PVC to the PX runtime custom resource (CR) under additional_storage.
  1. Retrieve the PX runtime instances:
    oc -n $CPD_INSTANCE_NS get pxruntime
    
  2. Edit the PX runtime instance:
    oc -n $CPD_INSTANCE_NS edit pxruntime <pxruntime-cr-name>
    
  3. Add the new PVC to additional_storage:
    spec:
      additional_storage:                        # mount additional persistent volumes
      - mount_path: /scratch                     # the path to mount the persistent volume
        pvc_name: pvc-scratch-manual            # the name of the associated persistent volume claim
      description: The default DataStage runtime instance
      license:
        accept: true
      parameters:
        scaleConfig: small
        storageClass: nfs-client
        storageSize: 10Gi
    

Changing the configuration file

When the new PVC is mounted, remote shell to the PX runtime pod and use nano to edit the file /px-storage/config/dynamic_config.apt.template.

  1. Remote shell to the PX runtime pod:
    oc -n $CPD_INSTANCE_NS rsh deploy/<pxruntime-cr-name>-ibm-datastage-px-runtime
    
  2. Update the scratch disk location in the /px-storage/config/dynamic_config.apt.template file for versions 4.6.1 or later:
    {
      node "conductor"
      {
       fastname "$conductor" 
       pools "conductor" 
       resource disk "/px-storage/pds_files/node1" {pool "" "export" "node1"}
       resource scratchdisk "/scratch" {pool ""}
      }
      node "compute"
      {
       fastname "$pod" 
       pools "" 
       resource disk "/px-storage/pds_files/node#" {pool "" "export" "node2"}
       resource scratchdisk "/scratch" {pool ""}
      }
    }
    

    For earlier versions, create a new apt config file in /px-storage and set the location of this file to the environment variable APT_CONFIG_FILE.

If you are still in the pod, stay there. If not, exec into any DataStage pod again. The configuration file is stored on the shared file system, so any pod can access the file.

You can create a new configuration file or modify the existing ones. Change the line that starts with resource scratchdisk as shown in the following example:
{
  node "conductor"
  {
   fastname "$conductor" 
   pools "conductor" 
   resource disk "/px-storage/pds_files/node1" {pool "" "export" "node1"}
   resource scratchdisk "/scratch" {pool ""}
  }
  node "compute"
  {
   fastname "$pod" 
   pools "" 
   resource disk "/px-storage/pds_files/node#" {pool "" "export" "node2"}
   resource scratchdisk "/scratch" {pool ""}
  }
}

The configuration file is now ready. Use this file to run your job. Set the file to APT_CONFIG_FILE.