# In-Transit compression- Dev Preview: ODF External Mode
## Important
***Applying compression prior to encryption has security implications as it reduces the level of security of messages between peers.
Applying compression after encryption is not efficient and the cost reduction would be very minimal.
So In case both encryption and compression are enabled, compression setting will be ignored by ceph and message will not be compressed. This behaviour can be overriden [by referering this.](https://docs.ceph.com/en/quincy/rados/configuration/msgr2/#confval-mscompresssecure)***
## Important
***For in-transit compression to work we need at least ceph v17 quincy***
## Cases
1. nil--->Compression(✅)
Compression is enabled by patching storagecluster
2. Compression--->nil(✅)
Compression is disabled afterwards
3. Compression,Encryption(❌)
Both encryption & Compression are enabled together
❌ - Encryption & Compression don't work together, only encryption will work
❌ - Encryption can't be turned off on the fly for existing volumes using it
---
## Case-1: Compression is enabled by patching storagecluster
### Creation of storagecluster
#### Creating storagesystem without encryption or compression
* While creating storagecluster don't include encryption enabled or compression enabled in network connections Spec.
* Wait for the storagecluster to become ready & all it's conditions to say successful/completed.
```
~ $ oc get storagecluster
NAME AGE PHASE EXTERNAL CREATED AT VERSION
ocs-external-storagecluster 60m Ready true 2023-07-27T07:10:02Z 4.14.0
```
```
~ $ oc get storagecluster ocs-external-storagecluster -o=jsonpath='{.status.conditions}' | jq
[
{
"lastHeartbeatTime": "2023-07-27T07:10:02Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Version check successful",
"reason": "VersionMatched",
"status": "False",
"type": "VersionMismatch"
},
{
"lastHeartbeatTime": "2023-07-27T08:58:29Z",
"lastTransitionTime": "2023-07-27T07:10:03Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "ReconcileComplete"
},
{
"lastHeartbeatTime": "2023-07-27T08:58:29Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Available"
},
{
"lastHeartbeatTime": "2023-07-27T08:58:29Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Progressing"
},
{
"lastHeartbeatTime": "2023-07-27T08:58:29Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Degraded"
},
{
"lastHeartbeatTime": "2023-07-27T08:58:29Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Upgradeable"
}
]
```
---
### Check if csi is configured to use v1 6789 port
```
~ $ oc get cm rook-ceph-csi-config -o=jsonpath='{.data.csi-cluster-config-json}' | jq
[
{
"clusterID": "openshift-storage",
"monitors": [
"10.1.115.118:6789",
"10.1.115.119:6789",
"10.1.115.120:6789"
],
"namespace": "openshift-storage"
}
]
```
---
### Create workload to test later after enabling compression
#### Create a rbd pvc & a pod to use it
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: normal-rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-ceph-rbd
EOF
```
```
~ $ oc get pvc | grep normal
normal-rbd-pvc Bound pvc-2001b9a3-0d28-475a-9c4f-56d820c331b5 1Gi RWO ocs-storagecluster-ceph-rbd 30s
```
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: normal-rbd-pod
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: rbd-storage
persistentVolumeClaim:
claimName: normal-rbd-pvc
containers:
- name: nginx-container
image: quay.io/mparida/nginx:latest
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: rbd-storage
EOF
```
```
~ $ oc get pods | grep normal
normal-rbd-pod 1/1 Running 0 27s
```
#### rsh into the pod & try using the mounted volume
```
~ $ oc rsh normal-rbd-pod
# cd /usr/share/nginx/html
# ls
lost+found
# touch a
# ls
a lost+found
# sync && exit
```
---
#### Create a cephfs pvc & a pod to use it
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: normal-cephfs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-cephfs
EOF
```
```
~ $ oc get pvc | grep normal
normal-cephfs-pvc Bound pvc-5564dfa1-58d7-4679-82e6-f5280157bbe5 1Gi RWO ocs-storagecluster-cephfs 8s
normal-rbd-pvc Bound pvc-2001b9a3-0d28-475a-9c4f-56d820c331b5 1Gi RWO ocs-storagecluster-ceph-rbd 5m15s
```
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: normal-cephfs-pod
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: cephfs-storage
persistentVolumeClaim:
claimName: normal-cephfs-pvc
containers:
- name: nginx-container
image: quay.io/mparida/nginx:latest
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: cephfs-storage
EOF
```
```
~ $ oc get pods | grep normal
normal-cephfs-pod 1/1 Running 0 31s
normal-rbd-pod 1/1 Running 0 6m47s
```
#### rsh into the pod & try using the mounted volume
```
~ $ oc rsh normal-cephfs-pod
# cd /usr/share/nginx/html
# ls
# touch a
# ls
a
# sync && exit
```
---
### Enabling Compression
#### Patching the storagecluster to enable compression
```
oc patch storagecluster ocs-external-storagecluster -n openshift-storage --type json --patch '[{ "op": "replace", "path": "/spec/network", "value": {"connections": {"compression": {"enabled": true}}} }]'
```
#### Wait for the storagecluster to get ready & all it's conditions to say successful/completed.
```
~ $ oc get storagecluster
NAME AGE PHASE EXTERNAL CREATED AT VERSION
ocs-external-storagecluster 60m Ready true 2023-07-27T07:10:02Z 4.14.0
```
```
~ $ oc get storagecluster ocs-external-storagecluster -o=jsonpath='{.status.conditions}' | jq
[
{
"lastHeartbeatTime": "2023-07-27T07:10:02Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Version check successful",
"reason": "VersionMatched",
"status": "False",
"type": "VersionMismatch"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:10:03Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "ReconcileComplete"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Available"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Progressing"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Degraded"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Upgradeable"
}
]
```
---
### Apply settings on RHCS cluster
#### ssh into the RHCS cluster
#### Apply the in-transit compression ceph configurations
```
# ceph config set global ms_osd_compress_mode force
# ceph config set global rbd_default_map_options ms_mode=prefer-crc
```
#### Check settings on the RHCS cluster
```
# ceph config dump | grep ms
global advanced ms_osd_compress_mode force
global advanced rbd_default_map_options ms_mode=prefer-crc *
```
#### Check ceph mon details, if they have both v1 & v2 addresses
```
# ceph mon dump
epoch 4
fsid 15b49e52-5bf5-11ed-a2e7-0050568fd833
last_changed 2023-06-06T09:40:52.566062+0000
created 2022-11-04T03:59:46.486027+0000
min_mon_release 17 (quincy)
election_strategy: 1
0: [v2:10.1.115.118:3300/0,v1:10.1.115.118:6789/0] mon.rhcs-2-node-1
1: [v2:10.1.115.119:3300/0,v1:10.1.115.119:6789/0] mon.rhcs-2-node-2
2: [v2:10.1.115.120:3300/0,v1:10.1.115.120:6789/0] mon.rhcs-2-node-3
dumped monmap epoch 4
```
### On odf cluster check if csi is configured to use v2 3300 port
```
~ $ oc get cm rook-ceph-csi-config -o=jsonpath='{.data.csi-cluster-config-json}' | jq
[
{
"clusterID": "openshift-storage",
"monitors": [
"10.1.115.118:3300",
"10.1.115.119:3300",
"10.1.115.120:3300"
],
"namespace": "openshift-storage"
}
]
```
---
### Test by creating rbd PVC ,Mounting it in a Pod & using the volume
#### Creating & Checking PVC
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: compression-rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-ceph-rbd
EOF
```
```
~ $ oc get pvc | grep compression
encryption-rbd-pvc Bound pvc-c271e73b-92a4-4710-9a6b-71a6d799830f 1Gi RWO ocs-storagecluster-ceph-rbd 67s
```
#### Creating & Checking Pod
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: compression-rbd-pod
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: rbd-storage
persistentVolumeClaim:
claimName: compression-rbd-pvc
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: rbd-storage
EOF
```
```
~ $ oc get pods | grep compression
encryption-rbd-pod 1/1 Running 0 2m41s
```
#### rsh into the pod and try using the mounted volume
```
$ oc rsh compression-rbd-pod
# cd /usr/share/nginx/html
# ls
lost+found
# touch a
# ls
a lost+found
# sync && exit
```
---
### Test by creating cephfs PVC, Mounting it in a Pod & checking the volume
#### Creating & Checking PVC
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: compression-cephfs-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-cephfs
EOF
```
```
~ $ oc get pvc | grep compression
compression-cephfs-pvc Bound pvc-25e473e2-a013-4707-bf09-14d99e7482f5 1Gi RWO ocs-storagecluster-cephfs 19s
compression-rbd-pvc Bound pvc-c271e73b-92a4-4710-9a6b-71a6d799830f 1Gi RWO ocs-storagecluster-ceph-rbd 67s
```
#### Creating & Checking Pod
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: compression-cephfs-pod
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: cephfs-storage
persistentVolumeClaim:
claimName: compression-cephfs-pvc
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: cephfs-storage
EOF
```
```
~ $ oc get pods | grep compression
compression-cephfs-pod 0/1 ContainerCreating 0 43s
compression-rbd-pod 1/1 Running 0 2m41s
```
#### rsh into the pod & try using the mounted volume
```
$ oc rsh compression-cephfs-pod
# cd /usr/share/nginx/html
# ls
# touch a
# ls
a
# sync && exit
```
---
### Verify if the earlied created volumes are accesible
```
~ $ oc rsh normal-rbd-pod
# cd /usr/share/nginx/html
# ls
a lost+found
# touch b
# ls
a b lost+found
# sync && exit
```
```
~ $ oc rsh normal-cephfs-pod
# cd /usr/share/nginx/html
# ls
a
# touch b
# ls
a b
# sync && exit
```
## Case 2: Compression is disabled afterwards
### Disabling Compression
#### Patching the storagecluster to disable compression
```
oc patch storagecluster ocs-external-storagecluster -n openshift-storage --type json --patch '[{ "op": "replace", "path": "/spec/network", "value": {"connections": {"compression": {"enabled": false}}} }]'
```
#### Wait for the storagecluster to get ready & all it's conditions to say successful/completed.
```
~ $ oc get storagecluster
NAME AGE PHASE EXTERNAL CREATED AT VERSION
ocs-external-storagecluster 60m Ready true 2023-07-27T07:10:02Z 4.14.0
```
```
~ $ oc get storagecluster ocs-external-storagecluster -o=jsonpath='{.status.conditions}' | jq
[
{
"lastHeartbeatTime": "2023-07-27T07:10:02Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Version check successful",
"reason": "VersionMatched",
"status": "False",
"type": "VersionMismatch"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:10:03Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "ReconcileComplete"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Available"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Progressing"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:10:02Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "False",
"type": "Degraded"
},
{
"lastHeartbeatTime": "2023-07-27T09:04:50Z",
"lastTransitionTime": "2023-07-27T07:13:30Z",
"message": "Reconcile completed successfully",
"reason": "ReconcileCompleted",
"status": "True",
"type": "Upgradeable"
}
]
```
---
### Remove settings on RHCS cluster
#### ssh into the RHCS cluster
#### Apply the in-transit compression ceph configurations
```
# ceph config rm global ms_osd_compress_mode
# ceph config rm global rbd_default_map_options
```
#### Check if the settings are removed
```
# ceph config dump | grep ms
```
---
### On odf cluster check if csi is configured back to use v1 6789 port
```
~ $ oc get cm rook-ceph-csi-config -o=jsonpath='{.data.csi-cluster-config-json}' | jq
[
{
"clusterID": "openshift-storage",
"monitors": [
"10.1.115.118:6789",
"10.1.115.119:6789",
"10.1.115.120:6789"
],
"namespace": "openshift-storage"
}
]
```
---
### Create workload to test after disabling compression
#### Create a rbd pvc & a pod to use it
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: normal-rbd-pvc-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-ceph-rbd
EOF
```
```
~ $ oc get pvc | grep normal
normal-cephfs-pvc Bound pvc-dbd3417c-9aa7-435c-b174-a95798e8185d 1Gi RWO ocs-external-storagecluster-cephfs 33m
normal-rbd-pvc Bound pvc-0206e669-1aa2-45f3-94a5-9fafaa9e70f0 1Gi RWO ocs-external-storagecluster-ceph-rbd 34m
normal-rbd-pvc-1 Bound pvc-a8af66e0-ea9b-43dc-b8dc-bd2936db3711 1Gi RWO ocs-external-storagecluster-ceph-rbd 11s
```
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: normal-rbd-pod-1
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: rbd-storage
persistentVolumeClaim:
claimName: normal-rbd-pvc-1
containers:
- name: nginx-container
image: quay.io/mparida/nginx:latest
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: rbd-storage
EOF
```
```
~ $ oc get pods | grep normal
normal-cephfs-pod 1/1 Running 0 33m
normal-rbd-pod 1/1 Running 0 35m
normal-rbd-pod-1 1/1 Running 0 21s
```
#### rsh into the pod & try using the mounted volume
```
~ $ oc rsh normal-rbd-pod-1
# cd /usr/share/nginx/html
# ls
lost+found
# touch a
# ls
a lost+found
# sync && exit
```
---
### Test by creating cephfs PVC ,Mounting it in a Pod & using the volume
#### Create a cephfs pvc & a pod to use it
```
~ $ cat <<EOF | oc create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: normal-cephfs-pvc-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: ocs-external-storagecluster-cephfs
EOF
```
```
~ $ oc get pvc | grep normal
normal-cephfs-pvc Bound pvc-dbd3417c-9aa7-435c-b174-a95798e8185d 1Gi RWO ocs-external-storagecluster-cephfs 35m
normal-cephfs-pvc-1 Bound pvc-4b194783-6b81-4b87-917e-a066828264b4 1Gi RWO ocs-external-storagecluster-cephfs 8s
normal-rbd-pvc Bound pvc-0206e669-1aa2-45f3-94a5-9fafaa9e70f0 1Gi RWO ocs-external-storagecluster-ceph-rbd 36m
normal-rbd-pvc-1 Bound pvc-a8af66e0-ea9b-43dc-b8dc-bd2936db3711 1Gi RWO ocs-external-storagecluster-ceph-rbd 2m21s
```
```
~ % cat <<EOF | oc create -f -
apiVersion: v1
kind: Pod
metadata:
name: normal-cephfs-pod-1
spec:
nodeSelector:
kubernetes.io/hostname: compute-0
volumes:
- name: cephfs-storage
persistentVolumeClaim:
claimName: normal-cephfs-pvc-1
containers:
- name: nginx-container
image: quay.io/mparida/nginx:latest
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: cephfs-storage
EOF
```
```
~ $ oc get pods | grep normal
normal-cephfs-pod 1/1 Running 0 35m
normal-cephfs-pod-1 1/1 Running 0 13s
normal-rbd-pod 1/1 Running 0 37m
normal-rbd-pod-1 1/1 Running 0 2m19s
```
#### rsh into the pod & try using the mounted volume
```
~ $ oc rsh normal-cephfs-pod-1
# cd /usr/share/nginx/html
# ls
# touch a
# ls
a
# sync && exit
```
---
## Case 3: Encryption & Compression are enabled together
### Enabling both encryption & compression
#### Patching the storagecluster
```
oc patch storagecluster ocs-external-storagecluster -n openshift-storage --type json --patch '[{ "op": "replace", "path": "/spec/network", "value": {"connections": {"encryption": {"enabled": true},"compression": {"enabled": true}}} }]'
```
#### Wait for the storagecluster to get ready & all it's conditions to say successful/completed.
---
### Apply settings on RHCS cluster
#### ssh into the RHCS cluster
#### Apply the in-transit encryption & compression ceph configurations
```
# ceph config set global ms_client_mode secure
# ceph config set global ms_cluster_mode secure
# ceph config set global ms_service_mode secure
# ceph config set global rbd_default_map_options ms_mode=secure
# ceph config set global ms_osd_compress_mode force
```
#### Check settings on the RHCS cluster
```
# ceph config dump | grep ms
global basic ms_client_mode secure *
global basic ms_cluster_mode secure *
global advanced ms_osd_compress_mode force
global basic ms_service_mode secure *
global advanced rbd_default_map_options ms_mode=secure *
```
---
### On odf cluster check if csi is configured to use v2 3300 port
```
~ $ oc get cm rook-ceph-csi-config -o=jsonpath='{.data.csi-cluster-config-json}' | jq
[
{
"clusterID": "openshift-storage",
"monitors": [
"10.1.115.118:3300",
"10.1.115.119:3300",
"10.1.115.120:3300"
],
"namespace": "openshift-storage"
}
]
```
---
### Check ocs-operator logs for warning message for both encryption & compression
```
{"level":"info","ts":"2023-07-27T10:27:02Z","logger":"controllers.StorageCluster","msg":"Both in-transit encryption & compression are enabled. To protect security of encrypted messages ceph will ignore compression","Request.Namespace":"openshift-storage","Request.Name":"ocs-external-storagecluster"}
```
---
**This is an unsupported configuration and we should not proceed from here onwards**
We have to decide if we want to use encryption or compression.
---
### If we want to continue with encryption only
#### Patch storagecluster
```
oc patch storagecluster ocs-external-storagecluster -n openshift-storage --type json --patch '[{ "op": "replace", "path": "/spec/network", "value": {"connections": {"compression": {"enabled": false}}} }]'
```
#### changes in RHCS cluster
```
# ceph config rm global ms_osd_compress_mode
```
---
### If we want to continue with compression only
#### Patch storagecluster
```
oc patch storagecluster ocs-external-storagecluster -n openshift-storage --type json --patch '[{ "op": "replace", "path": "/spec/network", "value": {"connections": {"encryption": {"enabled": false}}} }]'
```
#### changes in RHCS cluster
```
# ceph config rm global ms_client_mode
# ceph config rm global ms_cluster_mode
# ceph config rm global ms_service_mode
# ceph config set global rbd_default_map_options ms_mode=prefer-crc
```
#### On odf cluster check if csi is configured back to use v1 6789 port
```
~ $ oc get cm rook-ceph-csi-config -o=jsonpath='{.data.csi-cluster-config-json}' | jq
[
{
"clusterID": "openshift-storage",
"monitors": [
"10.1.115.118:6789",
"10.1.115.119:6789",
"10.1.115.120:6789"
],
"namespace": "openshift-storage"
}
]
```