ALM

Créer une image Docker pour une connexion ODBC à Databricks

Sep 29, 2021

Nicolas Bailly

Si vous voulez créer des dashboards en dehors d’un Notebook, dans une Web Application par exemple, vous devrez d’abord permettre la connexion à Databricks en utilisant le driver fournit par l’éditeur.
Dans cet article nous allons voir comment créer une image contenant tout ce qu’il faut pour permettre une connexion à Databricks par ODBC

Databricks ODBC Driver

Databricks met à disposition un driver ODBC en fonction de l’OS désiré : https://databricks.com/fr/spark/odbc-drivers-download
Et vous trouverez ici quelques explications sur l’utilisation de ce driver : https://docs.databricks.com/integrations/bi/jdbc-odbc-bi.html
Mais la copie de ce driver ne suffit pas, il nous faut installer les bibliothèques de base pour permettre à l’ODBC de fonctionner. Vous pouvez voir, qu’il existe 2 drivers Databricks pour Linux. Nous créerons 2 images différentes pour utiliser l’un ou l’autre de ces drivers en fonction du besoin :

  • une image où nous installerons le driver ODBC de Databricks au format RPM
  • une image où nous installerons le driver ODBC de Databricks pour debian, au format .deb

Création d’une image Ubuntu

Nous allons commencer avec une image Ubuntu sur laquelle nous installons les libraires requises pour l’ODBC : libpq-dev, unixodbc, unixodbc-dev
Nous y ajoutons également quelques librairies pour quand le container docker sera instancié : libxml2-dev, libssl-dev, libcurl4-openssl-dev, nano, curl

FROM ubuntu:focal

RUN apt-get update

RUN apt-get install -y --no-install-recommends 
  libpq-dev 
  libxml2-dev 
  libssl-dev 
  libcurl4-openssl-dev 
  nano 
  curl 
  unixodbc 
  unixodbc-dev

Nous pouvons maintenant copier le driver Databricks et l’installer. Nous prenons ici le driver pour debian

RUN curl https://databricks-bi-artifacts.s3.us-east-2.amazonaws.com/simbaspark-drivers/odbc/2.6.17/SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip -o SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip && 
    unzip SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip -d tmp
RUN gdebi -n  tmp/SimbaSparkODBC-2.6.17.0024-Debian-64bit/simbaspark_2.6.17.0024-2_amd64.deb
RUN rm -r tmp/*
RUN rm SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip

Il faut ensuite créer les fichiers odbc.ini et odbcinst.ini

RUN echo "[ODBC Data Sources]" >> /etc/odbc.ini && 
    echo "Databricks_Cluster = Simba Spark ODBC Driver" >> /etc/odbc.ini && 
    echo "" >> /etc/odbc.ini && 
    echo "[Databricks_Cluster]" >> /etc/odbc.ini && 
    echo "Driver          = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbc.ini && 
    echo "Description     = Simba Spark ODBC Driver DSN" >> /etc/odbc.ini && 
    echo "HOST            = " >> /etc/odbc.ini && 
    echo "PORT            = 443" >> /etc/odbc.ini && 
    echo "Schema          = default" >> /etc/odbc.ini && 
    echo "SparkServerType = 3" >> /etc/odbc.ini && 
    echo "AuthMech        = 11" >> /etc/odbc.ini && 
    echo "Auth_Flow       = 0" >> /etc/odbc.ini && 
    echo "UID             = token" >> /etc/odbc.ini && 
    echo "ThriftTransport = 2" >> /etc/odbc.ini && 
    echo "SSL             = 1" >> /etc/odbc.ini && 
    echo "HTTPPath        = " >> /etc/odbc.ini && 
    echo "UseProxy        = 1" >> /etc/odbc.ini &&  
    echo "ProxyHost       = $PROXY_HOST" >> /etc/odbc.ini &&  
    echo "ProxyPort       = $PROXY_PORT" >> /etc/odbc.ini &&  
    echo "" >> /etc/odbc.ini && 
    echo "[ODBC Drivers]" >> /etc/odbcinst.ini && 
    echo "Simba = Installed" >> /etc/odbcinst.ini && 
    echo "[Simba Spark ODBC Driver 64-bit]" >> /etc/odbcinst.ini && 
    echo "Driver = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbcinst.ini && 
    echo "" >> /etc/odbcinst.ini

Nous laissons volontairement vide les paramètres d’environnement qui seront fournit par l’application au moment de la connexion : HOST et HTTPPATH. Si vous n’avez qu’un environnement et que ces paramètres ne bougent pas, vous pouvez les préciser ici.
Vous remarquerez les paramètres ProxyHost et ProxyPort. Ce sont les paramètres de Proxy qu’il faut fournir dans les variables d’environnement. Si vous n’avez pas de proxy, il faut retirer ces 2 lignes du fichier INI.

Voici le Dockerfile complet :

FROM ubuntu:focal

RUN apt-get update

RUN apt-get install -y --no-install-recommends 
  libpq-dev 
  libxml2-dev 
  libssl-dev 
  libcurl4-openssl-dev 
  nano 
  curl 
  unixodbc 
  unixodbc-dev

### INSTALL databricks ODBC package
RUN curl https://databricks-bi-artifacts.s3.us-east-2.amazonaws.com/simbaspark-drivers/odbc/2.6.17/SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip -o SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip && 
    unzip SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip -d tmp
RUN gdebi -n  tmp/SimbaSparkODBC-2.6.17.0024-Debian-64bit/simbaspark_2.6.17.0024-2_amd64.deb
RUN rm -r tmp/*
RUN rm SimbaSparkODBC-2.6.17.0024-Debian-64bit.zip

### CREATE ODBC.INI file
RUN echo "[ODBC Data Sources]" >> /etc/odbc.ini && 
    echo "Databricks_Cluster = Simba Spark ODBC Driver" >> /etc/odbc.ini && 
    echo "" >> /etc/odbc.ini && 
    echo "[Databricks_Cluster]" >> /etc/odbc.ini && 
    echo "Driver          = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbc.ini && 
    echo "Description     = Simba Spark ODBC Driver DSN" >> /etc/odbc.ini && 
    echo "HOST            = " >> /etc/odbc.ini && 
    echo "PORT            = 443" >> /etc/odbc.ini && 
    echo "Schema          = default" >> /etc/odbc.ini && 
    echo "SparkServerType = 3" >> /etc/odbc.ini && 
    echo "AuthMech        = 11" >> /etc/odbc.ini && 
    echo "Auth_Flow       = 0" >> /etc/odbc.ini && 
    echo "UID             = token" >> /etc/odbc.ini && 
    echo "ThriftTransport = 2" >> /etc/odbc.ini && 
    echo "SSL             = 1" >> /etc/odbc.ini && 
    echo "HTTPPath        = " >> /etc/odbc.ini && 
    echo "UseProxy        = 1" >> /etc/odbc.ini &&  
    echo "ProxyHost       = $PROXY_HOST" >> /etc/odbc.ini &&  
    echo "ProxyPort       = $PROXY_PORT" >> /etc/odbc.ini &&  
    echo "" >> /etc/odbc.ini && 
    echo "[ODBC Drivers]" >> /etc/odbcinst.ini && 
    echo "Simba = Installed" >> /etc/odbcinst.ini && 
    echo "[Simba Spark ODBC Driver 64-bit]" >> /etc/odbcinst.ini && 
    echo "Driver = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbcinst.ini && 
    echo "" >> /etc/odbcinst.ini

Création d’une image RedHat

Nous allons faire de même mais sur une image RedHat qui nécessite le driver Databricks RPM et d’autres librairies linux.
Dans cet exemple, nous nous basons sur une image python dont la base est RedHat et nous installons les packages unixODBC et unixODBC-devel :

FROM python:3.8-ubi7

RUN yum --setopt=tsflags=nodocs install -y unixODBC
          RUN yum --setopt=tsflags=nodocs install -y unixODBC-devel

Nous pouvons ensuite installer le driver Databricks

RUN curl https://databricks-bi-artifacts.s3.us-east-2.amazonaws.com/simbaspark-drivers/odbc/2.6.17/SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip -o SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip && 
              unzip SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip -d tmp

USER ROOT
RUN rpm -i tmp/SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit/simbaspark-2.6.17.0024-1.x86_64.rpm
RUN rm -r tmp
RUN rm SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip

Le reste est identique à l’image Ubuntu, il faut créer les fichiers odbc.ini et odbcinst.ini. Voici le Dockerfile complet :

FROM python:3.8-ubi7

### INSTALL ODBC
RUN yum --setopt=tsflags=nodocs install -y unixODBC
RUN yum --setopt=tsflags=nodocs install -y unixODBC-devel

### INSTALL databricks ODBC package
RUN curl https://databricks-bi-artifacts.s3.us-east-2.amazonaws.com/simbaspark-drivers/odbc/2.6.17/SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip -o SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip && 
              unzip SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip -d tmp
USER root
RUN rpm -i tmp/SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit/simbaspark-2.6.17.0024-1.x86_64.rpm
RUN rm -r tmp
RUN rm SimbaSparkODBC-2.6.17.0024-LinuxRPM-64bit.zip

### CREATE ODBC.INI file
RUN echo "[ODBC Data Sources]" >> /etc/odbc.ini && 
    echo "Databricks_Cluster = Simba Spark ODBC Driver" >> /etc/odbc.ini && 
    echo "" >> /etc/odbc.ini && 
    echo "[Databricks_Cluster]" >> /etc/odbc.ini && 
    echo "Driver          = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbc.ini && 
    echo "Description     = Simba Spark ODBC Driver DSN" >> /etc/odbc.ini && 
    echo "HOST            = " >> /etc/odbc.ini && 
    echo "PORT            = 443" >> /etc/odbc.ini && 
    echo "Schema          = default" >> /etc/odbc.ini && 
    echo "SparkServerType = 3" >> /etc/odbc.ini && 
    echo "AuthMech        = 11" >> /etc/odbc.ini && 
    echo "Auth_Flow       = 0" >> /etc/odbc.ini && 
    echo "UID             = token" >> /etc/odbc.ini && 
    echo "ThriftTransport = 2" >> /etc/odbc.ini && 
    echo "SSL             = 1" >> /etc/odbc.ini && 
    echo "HTTPPath        = " >> /etc/odbc.ini && 
    echo "UseProxy        = 1" >> /etc/odbc.ini &&  
    echo "ProxyHost       = $PROXY_HOST" >> /etc/odbc.ini &&  
    echo "ProxyPort       = $PROXY_PORT" >> /etc/odbc.ini &&  
    echo "" >> /etc/odbc.ini && 
    echo "[ODBC Drivers]" >> /etc/odbcinst.ini && 
    echo "Simba = Installed" >> /etc/odbcinst.ini && 
    echo "[Simba Spark ODBC Driver 64-bit]" >> /etc/odbcinst.ini && 
    echo "Driver = /opt/simba/spark/lib/64/libsparkodbc_sb64.so" >> /etc/odbcinst.ini && 
    echo "" >> /etc/odbcinst.ini

Authentification par token

Dans ce que nous venons de faire, le type d’authentification paramétré dans le fichier INI se fait par token Azure qu’il faut générer avant de lancer la connexion dans l’application. La documentation Microsoft l’explique : https://docs.microsoft.com/en-us/azure/databricks/integrations/bi/jdbc-odbc-bi#azure-active-directory-token-authentication
Par contre, la documentation Databricks qui se veut agnostique de l’endroit où est installé votre cluster(AWS ou Azure) ne parle que de l’utilisation d’un Personal Access Token (PAT). Si vous voulez utiliser ce mode d’authentification, il faut modifier quelque peu le fichier ini. A savoir que l’utilisation d’un PAT Databricks est lié à votre compte utilisateur. Ce n’est donc pas envisageable sur une application de production où il est préférable d’utiliser un token Azure AD obtenu soit par une App Registered soit par l’authentification de l’utilisateur connecté à votre application. Si toutefois, vous voulez utiliser un PAT Databricks, voici comment paramétrer le fichier INI :

  • AuthMech : mettre la valeur 3 au lieu de 11 => AuthMech=3
  • Auth_Flow : supprimer ce paramètre
  • PWD : ajouter le paramètre PWD et y mettre votre PAT

Exemples d’applications

Nous irons plus loin dans un autre article avec l’implémentation d’une application R Shiny pour afficher des dashboards dans cet article

0 commentaires

Soumettre un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Découvrez nos autres articles

Aller au contenu principal