Cette série d'articles vous aide à mieux comprendre comment mapper les données d'application dans les clusters ODF à l'aide de la boîte à outils Rook et des commandes OpenShift. Cette connaissance et les outils associés peuvent être très utiles pour le dépannage ainsi que pour une compréhension plus approfondie du stockage des données dans ODF. Assurez-vous d'avoir lu les première et deuxième parties avant de lire celle-ci (troisième partie de la série).
Créer un projet de stockage de fichiers
Vous suivrez les mêmes principes que vous avez utilisés jusqu'à présent pour faire quelque chose de similaire au projet de stockage de blocs précédent avec une application qui utilise CephFS d'ODF pour le stockage partagé. Créez un nouveau projet appelé ocs-file-app :
[alexon@bastion ~]$ oc new-project ocs-file-app
Now using project "ocs-file-app" on server "https://api.example.com:6443".
Vous pouvez ajouter des applications à ce projet avec le new-app
commande. Par exemple, pour créer un nouvel exemple d'application en Ruby, essayez :
oc new-app rails-postgresql-example
Ou utilisez kubectl
pour déployer une application Kubernetes simple :
kubectl create deployment hello-node --image=k8s.gcr.io/serve_hostname
Pour cet exemple, utilisez une démonstration de téléchargement de fichiers PHP OpenShift application (que j'ai dérivée du projet de Christian Hernandez - crédits dus) qui servira bien vos intérêts :
[alexon@bastion ~]$ oc new-app openshift/php:7.2-ubi8~https://github.com/AlexonOliveiraRH/openshift-php-upload-demo.git --name=file-uploader
--> Found image 67520c7 (5 weeks old) in image stream "openshift/php" under tag "7.2-ubi8" for "openshift/php:7.2-ubi8"
Apache 2.4 with PHP 7.2
-----------------------
PHP 7.2 available as container is a base platform for building and running various PHP 7.2 applications and frameworks. PHP is an HTML-embedded scripting language. PHP attempts to make it easy for developers to write dynamically generated web pages. PHP also offers built-in database integration for several commercial and non-commercial database management systems, so writing a database-enabled webpage with PHP is fairly simple. The most common use of PHP coding is probably as a replacement for CGI scripts.
Tags: builder, php, php72, php-72
* A source build using source code from https://github.com/AlexonOliveiraRH/openshift-php-upload-demo.git will be created
* The resulting image will be pushed to image stream tag "file-uploader:latest"
* Use 'oc start-build' to trigger a new build
--> Creating resources ...
imagestream.image.openshift.io "file-uploader" created
buildconfig.build.openshift.io "file-uploader" created
deployment.apps "file-uploader" created
service "file-uploader" created
--> Success
Build scheduled, use 'oc logs -f buildconfig/file-uploader' to track its progress.
Application is not exposed. You can expose services to the outside world by executing one or more of the commands below:
'oc expose service/file-uploader'
Run' oc status' to view your app.
[alexon@bastion ~]$ oc expose svc/file-uploader -n ocs-file-app
route.route.openshift.io/file-uploader exposed
[alexon@bastion ~]$ oc scale --replicas=3 deploy/file-uploader -n ocs-file-app
deployment.apps/file-uploader scaled
[alexon@bastion ~]$ oc get pods -n ocs-file-app
NAME READY STATUS
RESTARTS AGE
file-uploader-1-build 0/1 Completed
0 79s
file-uploader-764468fb46-6vlxg 1/1
Running 0 11s
file-uploader-764468fb46-cr4mc 1/1
Running 0 7s
file-uploader-764468fb46-vtsq5 1/1
Running 0 15s
Cette nouvelle application utilise le ocs-storagecluster-cephfs SC :
[alexon@bastion ~]$ oc set volume deploy/file-uploader --add --name=ocs-file-app \
> -t pvc --claim-mode=ReadWriteMany --claim-size=1Gi \
> --claim-name=ocs-file-app --claim-class=ocs-storagecluster-cephfs \
> --mount-path=/opt/app-root/src/uploaded \
> -n ocs-file-app
deployment.apps/file-uploader volume updated
NAME READY STATUS
RESTARTS AGE
file-uploader-1-build 0/1 Completed
0 2m7s
file-uploader-69b547dfd6-gvhfk 1/1
Running 0 33s
file-uploader-69b547dfd6-nzhl8 1/1
Running 0 26s
file-uploader-69b547dfd6-qbj28 1/1
Running 0 15s
[alexon@bastion ~]$ oc get pvc
NAME
STATUS VOLUME
CAPACITY ACCESS MODES STORAGECLASS AGE
ocs-file-app
Bound
pvc-73c1bda0-2256-407d-885d-e5bcfd221b27 1Gi
RWX
ocs-storagecluster-cephfs 44m
Comme test simple, créez un fichier nommé testfile.txt
avec le "Bonjour le monde!" contenu et téléchargez-le dans votre application via l'interface utilisateur de l'application :
[alexon@bastion ~]$ oc get route file-uploader -n ocs-file-app -o jsonpath --template="http://{.spec.host}{'\n'}"
http://file-uploader-ocs-file-app.apps.example.com
[alolivei@alolivei ~]$ echo 'Hello world!' >> testfile.txt
[alolivei@alolivei ~]$ cat testfile.txt
Hello world!
Télécharger le fichier :

Et voici le résultat :

Pour mapper un objet fichier, la procédure est un peu différente de l'objet bloc. En effet, CephFS utilise l'adresse inode du fichier convertie en hexadécimal pour le nommer dans le pool de fichiers. Par conséquent, il est nécessaire de trouver l'objet à l'aide de l'un des pods de l'application dans le répertoire monté à l'intérieur du pod par CephFS, de connaître son inode, puis de convertir le numéro d'inode en hexadécimal, comme dans l'exemple ci-dessous :
[alexon@bastion ~]$ oc get pods
NAME READY STATUS RESTARTS
AGE
file-uploader-1-build 0/1 Completed
0 8m32s
file-uploader-69b547dfd6-gvhfk 1/1
Running 0 6m58s
file-uploader-69b547dfd6-nzhl8 1/1
Running 0 6m51s
file-uploader-69b547dfd6-qbj28 1/1
Running 0 6m40s
[alexon@bastion ~]$ oc rsh file-uploader-69b547dfd6-gvhfk
sh-4.4$ mount | grep csi-vol
172.30.38.159:6789,172.30.136.12:6789,172.30.73.120:6789:/volumes/csi/csi-vol-8a803889-bcce-11eb-8d22-0a580a81023e/3910620a-e68c-424b-8982-8f2b21c26a8a on /opt/app-root/src/uploaded type ceph (rw,relatime,seclabel,name=csi-cephfs-node,secret=<hidden>,acl,mds_namespace=ocs-storagecluster-cephfilesystem)
sh-4.4$ ls /opt/app-root/src/uploaded
testfile.txt
sh-4.4$ stat -c %i /opt/app-root/src/uploaded/testfile.txt | xargs printf '%x\n'
1000000001a
Maintenant que vous avez ces informations, suivez les mêmes étapes qu'auparavant, avec quelques différences mineures, pour trouver l'objet dans ocs-storagecluster-cephfilesystem-data0 pool ainsi que le nœud qui lui est lié, comme suit :
sh-4.4$ ceph df
RAW STORAGE:
CLASS SIZE
AVAIL USED RAW USED %RAW USED
ssd 1.5 TiB 1.2 TiB
253 GiB 256 GiB 16.68
TOTAL 1.5 TiB
1.2 TiB 253 GiB 256 GiB 16.68
POOLS:
POOL
ID STORED OBJECTS USED
%USED MAX AVAIL
ocs-storagecluster-cephblockpool 1 84 GiB 22.45k
253 GiB 19.43 350 GiB
ocs-storagecluster-cephfilesystem-metadata 2
1.5 MiB 26 4.5 MiB 0
350 GiB
ocs-storagecluster-cephfilesystem-data0 3
171 B 2 24 KiB 0
350 GiB
sh-4.4$ rados -p ocs-storagecluster-cephfilesystem-data0 ls | grep 1000000001a
1000000001a.00000000
sh-4.4$ rados -p ocs-storagecluster-cephfilesystem-data0 stat2 1000000001a.00000000
ocs-storagecluster-cephfilesystem-data0/1000000001a.00000000 mtime 2021-05-24T20:33:51.179464+0000, size 13
Il semble que vous ayez trouvé votre objet. Un moyen simple et rapide de le valider est de l'exporter depuis le pool et de vérifier son contenu :
sh-4.4$ rados -p ocs-storagecluster-cephfilesystem-data0 get 1000000001a.00000000
/tmp/output.txt
sh-4.4$ cat /tmp/output.txt
Hello world!
Terminez maintenant le processus et mappez le nœud dans lequel se trouve le fichier :
sh-4.4$ ceph osd map ocs-storagecluster-cephfilesystem-data0 1000000001a.00000000
osdmap e405 pool 'ocs-storagecluster-cephfilesystem-data0' (3) object '1000000001a.00000000' -> pg 3.a8154e0 (3.0) -> up ([2,1,0], p2) acting ([2,1,0], p2)
sh-4.4$ ceph osd status
+----+------------------------------+-------+-------+--------+---------+--------+---------+-----------+
| id |
host |
used | avail | wr ops | wr data | rd ops | rd data | state
|
+----+------------------------------+-------+-------+--------+---------+--------+---------+-----------+
| 0 | ip-10-0-171-63.ec2.internal | 85.4G | 426G | 86 | 1221k
| 0 |
0 | exists,up |
| 1 | ip-10-0-143-192.ec2.internal | 85.4G |
426G | 78 | 1678k |
0 | 0
| exists,up |
| 2 | ip-10-0-154-20.ec2.internal | 85.4G | 426G | 67 | 643k
| 2 |
106 | exists,up |
+----+------------------------------+-------+-------+--------+---------+--------+---------+-----------+
sh-4.4$ ceph osd tree
ID CLASS WEIGHT TYPE NAME
STATUS REWEIGHT PRI-AFF
-1 1.50000 root default
-5 1.50000 region us-east-1
-4 0.50000 zone us-east-1a
-3 0.50000 host ocs-deviceset-gp2-csi-1-data-085b8h
1 ssd 0.50000 osd.1 up 1.00000 1.00000
-10
0.50000 zone us-east-1b
-9 0.50000 host ocs-deviceset-gp2-csi-2-data-0n9lkb
2 ssd 0.50000 osd.2 up 1.00000 1.00000
-14
0.50000 zone us-east-1c
-13
0.50000 host ocs-deviceset-gp2-csi-0-data-0gvt22
0 ssd 0.50000 osd.0 up 1.00000 1.00000
Encore une fois, vous savez que l'objet se trouve dans un PG avec l'OSD ID 2 comme principal, avec ses répliques dans les OSD ID 1 et 0, que cet OSD utilise l'hôte de l'appareil ocs-deviceset-gp2-csi-2- données-0n9lkb sur l'hôte ip-10-0-154-20.ec2.internal . Si vous voulez être sûr qu'il s'agit du bon nœud, vérifiez le périphérique avec lsblk
ou dmsetup
:
[alexon@bastion ~]$ oc debug node/ip-10-0-154-20.ec2.internal
Starting pod/ip-10-0-154-20ec2internal-debug ...
To use host binaries, run `chroot /host`
Pod IP: 10.0.154.20
If you don't see a command prompt, try pressing enter.
sh-4.4# lsblk | grep ocs-deviceset-gp2-csi-2-data-0n9lkb
`-ocs-deviceset-gp2-csi-2-data-0n9lkb-block-dmcrypt 253:0 0 512G
0 crypt
sh-4.4# dmsetup ls | grep ocs-deviceset-gp2-csi-2-data-0n9lkb
ocs-deviceset-gp2-csi-2-data-0n9lkb-block-dmcrypt (253:0)
En utilisant le nom du PV utilisé par le PVC de l'application que vous avez vue précédemment, grep
et voir où sont montés les chemins disponibles pour l'application :
sh-4.4# mount | grep pvc-73c1bda0-2256-407d-885d-e5bcfd221b27
172.30.38.159:6789,172.30.136.12:6789,172.30.73.120:6789:/volumes/csi/csi-vol-8a803889-bcce-11eb-8d22-0a580a81023e/3910620a-e68c-424b-8982-8f2b21c26a8a on /host/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/globalmount type ceph (rw,relatime,seclabel,name=csi-cephfs-node,secret=<hidden>,acl,mds_namespace=ocs-storagecluster-cephfilesystem)
172.30.38.159:6789,172.30.136.12:6789,172.30.73.120:6789:/volumes/csi/csi-vol-8a803889-bcce-11eb-8d22-0a580a81023e/3910620a-e68c-424b-8982-8f2b21c26a8a on /host/var/lib/kubelet/pods/ac40b1fa-a08d-46b5-8bb6-dc55a5638e9e/volumes/kubernetes.io~csi/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/mount type ceph (rw,relatime,seclabel,name=csi-cephfs-node,secret=<hidden>,acl,mds_namespace=ocs-storagecluster-cephfilesystem)
Enfin, regardez le contenu des répertoires, et vous y trouverez votre objet, prêt à être visualisé :
sh-4.4# ls /host/var/lib/kubelet/pods/ac40b1fa-a08d-46b5-8bb6-dc55a5638e9e/volumes/kubernetes.io~csi/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/mount
testfile.txt
sh-4.4# cat /host/var/lib/kubelet/pods/ac40b1fa-a08d-46b5-8bb6-dc55a5638e9e/volumes/kubernetes.io~csi/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/mount/estfile.txt
Hello world!
sh-4.4# ls /host/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/globalmount
testfile.txt
sh-4.4# cat /host/var/lib/kubelet/plugins/kubernetes.io/csi/pv/pvc-73c1bda0-2256-407d-885d-e5bcfd221b27/globalmount/testfile.txt
Hello world!
Vous savez maintenant comment rechercher et mapper les informations d'objet de fichier dans le cluster, un peu comme vous l'avez vu dans l'article 2 avec les informations de bloc.
[ Obtenez ce livre gratuit de Red Hat et O'Reilly - Kubernetes Operators :Automating the Container Orchestration Platform. ]
Récapitulez
L'approche ODF du stockage distribué et évolutif est très différente des autres solutions de stockage. Il peut être difficile de comprendre où les objets d'application sont stockés dans le cluster, ce qui présente des défis lors du dépannage (et de la conception).
Cette série d'articles est une démonstration de base du fonctionnement du mappage d'objets d'application ODF. Dans la première partie, vous avez défini l'environnement et les utilitaires nécessaires. La deuxième partie couvrait le stockage de blocs tandis que la troisième partie examinait les structures de stockage de fichiers. Maintenant que vous savez comment le faire, faites-en bon usage.