Exposer un cluster Ceph basé sur Rook à l'extérieur de Kubernetes
16 avr. 2020
- Catégories
- Orchestration de conteneurs
- Tags
- Debug
- Rook
- Ceph
- Docker
- Kubernetes [plus][moins]
Ne ratez pas nos articles sur l'open source, le big data et les systèmes distribués, fréquence faible d’un email tous les deux mois.
Nous avons récemment créé un cluster Hadoop basé sur des containers LXD et nous voulions être en mesure d’appliquer des quotas sur certains filesystems (par exemple : logs de service, repertoires utilisateurs). Les quotas sont une fonctionnalité incluse dans le kernel Linux permettant de limiter l’utilisation d’espace disque d’un utilisateur donné. Par exemple, nous avons des edge nodes que nous fournissons à nos utilisateurs comme espace de travail sécurisé. Ils sont accessibles via SSH et disposent de clients Hadoop et Kubernetes pré-configurés. Nous devons alors nous assurer qu’un utilisateur ne va pas saturer le filesystem avec de la donnée qu’il devrait mettre dans HDFS. CephFS avec Rook semble être un bon compromis étant donné que nous disposions déjà d’un cluster Kubernetes installé et prêt à être utilisé au sein de la même infrastructure. Rook est devenu le standard du stockage distribué dans Kubernetes et nous nous en servirons pour provisionner et gérer notre CephFS.
Cet article explique comment exposer un cluster Rook Ceph pour l’utiliser en dehors de Kubernetes.
Déploiement de Rook
La première étape est d’installer Rook et Ceph dans le cluster Kubernetes. Nous n’irons pas trop dans le détail ici et suivrons simplement les indications du quick start guide de Rook. Si vous rencontrez des difficultés comme par exemple les OSDs qui ne se créent pas, je vous invite à consulter l’article d’Eyal : ”Rook via Ceph n’approvisionne pas mes Persistent Volume Claims !“.
git clone --single-branch --branch release-1.3 https://github.com/rook/rook.git
cd rook/cluster/examples/kubernetes/ceph
kubectl create -f common.yaml
kubectl create -f operator.yaml
kubectl create -f cluster.yaml
kubectl create -f filesystem.yaml
À partir d’ici, nous pouvons monter le filesystem dans un pod Ceph toolbox en suivant les instructions de la documentation de Rook.
Tout d’abord, on crée la toolbox et ouvre un shell dedans :
kubectl create -f toolbox.yaml
kubectl -n rook-ceph exec -it $(kubectl -n rook-ceph get pod -l "app=rook-ceph-tools" -o jsonpath='{.items[0].metadata.name}') bash
On monte ensuite le filesystem :
mkdir /mounted_dir
mon_endpoints=$(grep mon_host /etc/ceph/ceph.conf | awk '{print $3}')
my_secret=$(grep key /etc/ceph/keyring | awk '{print $3}')
mount -t ceph -o mds_namespace=myfs,name=admin,secret=$my_secret $mon_endpoints:/ /mounted_dir
Par défault, le cluster n’est accessible qu’au sein du réseau interne de Kubernetes. En effet, si on affiche le contenu de la variable mon_endpoints
echo $mon_endpoints
10.107.4.123:6789,10.102.4.224:6789,10.99.152.180:6789
Ces adresses IPs sont internes au cluster Kubernetes.
Si on essaye de monter le FS avec ces IPs depuis un noeud externe à Kubernetes, cela ne fonctionnera pas :
mkdir /mounted_dir
mon_endpoints="10.107.4.123:6789,10.102.4.224:6789,10.99.152.180:6789"
my_secret="AQBbQ5BeYf8rOBAAetM2gKeJWeUisAvrbmfQdA=="
mount -t ceph -o mds_namespace=myfs,name=admin,secret=$my_secret $mon_endpoints:/ /mounted_dir
mount: mount 10.107.4.123:6789,10.102.4.224:6789,10.99.152.180:6789:/ on /mounted_dir failed: Connection timed out
En effet, impossible d’ouvrir une connexion vers 10.107.4.123:6789
nc -zv 10.107.4.123 6789
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connection timed out.
Les Ceph monitor daemons sont exposés au travers des services suivants :
kubectl get svc -n rook-ceph
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
rook-ceph-mon-a ClusterIP 10.102.4.224 <none> 6789/TCP,3300/TCP 132m
rook-ceph-mon-b ClusterIP 10.99.152.180 <none> 6789/TCP,3300/TCP 132m
rook-ceph-mon-c ClusterIP 10.107.4.123 <none> 6789/TCP,3300/TCP 132m
Notre première tentative consista à modifier le type de service de ClusterIP à NodePort :
kubectl get svc -n rook-ceph
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
rook-ceph-mon-a NodePort 10.102.4.224 <none> 6789:30243/TCP,3300:30022/TCP 136m
rook-ceph-mon-b NodePort 10.99.152.180 <none> 6789:30637/TCP,3300:30027/TCP 136m
rook-ceph-mon-c NodePort 10.107.4.123 <none> 6789:31302/TCP,3300:30658/TCP 135m
Désormais, on peut contacter les Monitors avec les IPs physiques des noeuds Kubernetes :
nc -zv 10.0.0.70 30243
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 10.0.0.70:30243.
Ncat: 0 bytes sent, 0 bytes received in 0.02 seconds
Mais en essayant de monter le FS :
mkdir /mounted_dir
mon_endpoints="10.0.0.72:30243,10.0.0.72:30637,10.0.0.72:31302"
my_secret="AQBbQ5BeYf8rOBAAetM2gKeJWeUisAvrbmfQdA=="
mount -t ceph -o mds_namespace=myfs,name=admin,secret=$my_secret $mon_endpoints:/ /mounted_dir
mount: mount 10.0.0.72:30243,10.0.0.72:30637,10.0.0.72:31302:/ on /mounted_dir failed: Connection timed out
Cela n’a pas fonctionné. Bien que la machine puisse contacter les monitors du cluster Ceph, ces derniers répondent avec leur IPs internes de Kubernetes. On peut le constater dans les logs kernel juste après le timeout de la commmande mount :
dmesg | grep ceph
[786368.713136] libceph: mon1 (1)10.0.0.72:30637 wrong peer at address
[786370.153821] libceph: wrong peer, want (1)10.0.0.72:30243/0, got (1)10.102.4.224:6789/0
[786370.153825] libceph: mon0 (1)10.0.0.72:30243 wrong peer at address
[786370.729937] libceph: wrong peer, want (1)10.0.0.72:30243/0, got (1)10.102.4.224:6789/0
[786373.225787] libceph: mon2 (1)10.0.0.72:31302 wrong peer at address
[786373.769784] libceph: wrong peer, want (1)10.0.0.72:31302/0, got (1)10.107.4.123:6789/0
Après avoir parcouru les issues GitHub de Rook, nous sommes tombés sur celle-ci implémentée dans cette pull request.
La propriété hostNetwork
peut être configurée à true
pour utiliser le réseau des noeuds au lieu de celui de Kubernetes.
Après avoir ajouter la propriété dans le cluster.yaml comme suivant :
network:
hostNetwork: true
On constate cette fois-ci qu’il n’y a pas de service créé pour exposer les pods Ceph Monitor :
kubectl -n rook-ceph get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
csi-cephfsplugin-metrics ClusterIP 10.96.31.24 <none> 8080/TCP,8081/TCP 10m
csi-rbdplugin-metrics ClusterIP 10.100.212.142 <none> 8080/TCP,8081/TCP 10m
rook-ceph-mgr ClusterIP 10.105.255.14 <none> 9283/TCP 7m25s
rook-ceph-mgr-dashboard ClusterIP 10.98.54.85 <none> 8443/TCP 7m45s
En effet, ces derniers sont joignables par le port 6789 des noeuds Kubernetes :
nc -zv 10.0.0.70 6789
Ncat: Version 7.50 ( https://nmap.org/ncat )
Ncat: Connected to 10.0.0.70:6789.
Ncat: 0 bytes sent, 0 bytes received in 0.02 seconds.
Essayons de monter le filesystem une nouvelle fois :
mon_endpoints="10.0.0.72:6789,10.0.0.72:6789,10.0.0.72:6789"
my_secret="AQDfh5BeSlxfDBAALWOd8Atlc9GtLaOs4lGB/A=="
mount -t ceph -o mds_namespace=myfs,name=admin,secret=$my_secret $mon_endpoints:/ /mounted_dir
df -h /mounted_dir/
Filesystem Size Used Avail Use% Mounted on
10.0.0.72:6789,10.0.0.72:6789,10.0.0.72:6789:/ 332G 0 332G 0% /mounted_dir
C’est prêt ! Nous pouvons maintenant monter un CephFS provisionné dans Kubernetes avec Rook à l’extérieur du cluster.