Exposer Apache Superset à Internet
Cet article décrit comment exposer Apache Superset à Internet.
Sélection du nom d’hôte
Choisissez un nom d’hôte pour Superset.
Sauf si vous utilisez un nom DNS personnalisé, ce nom d’hôte doit correspondre au modèle :
<superset-instance-name>.<azure-region>.cloudapp.azure.com
. Le nom-instance-superset doit être unique dans la région Azure.Exemple :
myuniquesuperset.westus3.cloudapp.azure.com
Obtenez un certificat TLS pour le nom d’hôte, placez-le dans votre coffre de clés et appelez-le
aks-ingress-tls
. Découvrez comment placer un certificat dans un Azure Key Vault.
Configurer une entrée
Les instructions suivantes ajoutent une deuxième couche d’authentification sous la forme d’un proxy d’autorisation OAuth utilisant Oauth2Proxy. Cette couche signifie qu’aucun client non autorisé n’atteint l’application Superset.
Ajoutez les secrets suivants à votre Key Vault.
Nom du secret Description client-id Votre ID client principal du service Azure. Le proxy OAuth exige que cet identifiant soit un secret. oauth2proxy-redis-password Mot de passe du cache proxy. Le mot de passe utilisé par le proxy OAuth pour accéder à l’instance de déploiement Redis back-end sur Kubernetes. Générez un mot de passe fort. oauth2proxy-cookie-secret Secret de cookie sur 32 caractères, utilisé pour chiffrer les données du cookie. Ce secret doit comporter 32 caractères. Ajoutez ces rappels dans la configuration de votre application Azure AD Superset.
https://{{superset_hostname}}/oauth2/callback
- pour le proxy OAuth2
https://{{superset_hostname}}/oauth-authorized/azure
- pour Superset
Déployer le contrôleur nginx d’entrée dans l’espace de noms
default
helm install ingress-nginx-superset ingress-nginx/ingress-nginx \ --namespace default \ --set controller.service.annotations."service\.beta\.kubernetes\.io/azure-load-balancer-health-probe-request-path"=/healthz \ --set controller.config.proxy-connect-timeout="60" \ --set controller.config.proxy-read-timeout="1000" \ --set controller.config.proxy-send-timeout="1000" \ --set controller.config.proxy-buffer-size="'64k'" \ --set controller.config.proxy-buffers-number="8"
Pour obtenir des instructions détaillées, consultez les instructions Azure ici.
Remarque
Les étapes du contrôleur nginx d'entrée utilisent l'espace de noms Kubernetes
ingress-basic
. Ceci doit être modifié pour utiliser l’espace de nomsdefault
. Exemple :NAMESPACE=default
Créez une classe de fournisseur de secrets TLS.
Cette étape décrit comment le certificat TLS est lu à partir du Key Vault et transformé en un secret Kubernetes à utiliser par Entrée :
Mettez à jour dans le yaml suivant :
{{MSI_CLIENT_ID}}
– L'ID client de l'identité managée attribuée au cluster Superset ($MANAGED_IDENTITY_RESOURCE
).{{KEY_VAULT_NAME}}
- Le nom de Azure Key Vault contenant les secrets.{{KEY_VAULT_TENANT_ID}}
– Le guid d’identifiant du locataire Azure où se trouve le Key Vault.
tls-secretprovider.yaml
apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-tls spec: provider: azure # secretObjects defines the desired state of synced K8s secret objects secretObjects: - secretName: ingress-tls-csi type: kubernetes.io/tls data: - objectName: aks-ingress-tls key: tls.key - objectName: aks-ingress-tls key: tls.crt parameters: usePodIdentity: "false" useVMManagedIdentity: "true" userAssignedIdentityID: "{{MSI_CLIENT_ID}}" # the name of the AKV instance keyvaultName: "{{KEY_VAULT_NAME}}" objects: | array: - | objectName: aks-ingress-tls objectType: secret # the tenant ID of the AKV instance tenantId: "{{KEY_VAULT_TENANT_ID}}"
Créez une classe de fournisseur secret OauthProxy.
Mettez à jour dans le yaml suivant :
{{MSI_CLIENT_ID}}
– L'ID client de l'identité managée attribuée au cluster Superset ($MANAGED_IDENTITY_RESOURCE
).{{KEY_VAULT_NAME}}
- Le nom de Azure Key Vault contenant les secrets.{{KEY_VAULT_TENANT_ID}}
- Le Guid d’identificateur du locataire Azure où se trouve le coffre de clés.
oauth2-secretprovider.yaml
# This is a SecretProviderClass example using aad-pod-identity to access the key vault apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: oauth2-secret-provider spec: provider: azure parameters: useVMManagedIdentity: "true" userAssignedIdentityID: "{{MSI_CLIENT_ID}}" usePodIdentity: "false" # Set to true for using aad-pod-identity to access your key vault keyvaultName: "{{KEY_VAULT_NAME}}" # Set to the name of your key vault cloudName: "" # [OPTIONAL for Azure] if not provided, the Azure environment defaults to AzurePublicCloud objects: | array: - | objectName: oauth2proxy-cookie-secret objectType: secret - | objectName: oauth2proxy-redis-password objectType: secret - | objectName: client-id objectType: secret - | objectName: client-secret objectType: secret tenantId: "{{KEY_VAULT_TENANT_ID}}" # The tenant ID of the key vault secretObjects: - secretName: oauth2-secret type: Opaque data: # OauthProxy2 Secrets - key: cookie-secret objectName: oauth2proxy-cookie-secret - key: client-id objectName: client-id - key: client-secret objectName: client-secret - key: redis-password objectName: oauth2proxy-redis-password - secretName: oauth2-redis type: Opaque data: - key: redis-password objectName: oauth2proxy-redis-password
Créez une configuration pour le proxy OAuth.
Mettez à jour dans le yaml suivant :
{{superset_hostname}}
– le nom d’hôte accessible sur Internet choisi dans la sélection du nom d’hôte{{tenant-id}}
– GUID d’identifiant du locataire Azure où votre principal de service a été créé.
Facultatif : mettre à jour la liste des domaines de messagerie. Exemple :
email_domains = [ "microsoft.com" ]
oauth2-values.yaml
# Force the target Kubernetes version (it uses Helm `.Capabilities` if not set). # This is especially useful for `helm template` as capabilities are always empty # due to the fact that it doesn't query an actual cluster kubeVersion: # OAuth client configuration specifics config: # OAuth client secret existingSecret: oauth2-secret configFile: |- email_domains = [ ] upstreams = [ "file:///dev/null" ] image: repository: "quay.io/oauth2-proxy/oauth2-proxy" tag: "v7.4.0" pullPolicy: "IfNotPresent" extraArgs: provider: oidc oidc-issuer-url: https://login.microsoftonline.com/<tenant-id>/v2.0 login-url: https://login.microsoftonline.com/<tenant-id>/v2.0/oauth2/authorize redeem-url: https://login.microsoftonline.com/<tenant-id>/v2.0/oauth2/token oidc-jwks-url: https://login.microsoftonline.com/common/discovery/keys profile-url: https://graph.microsoft.com/v1.0/me skip-provider-button: true ingress: enabled: true path: /oauth2 pathType: ImplementationSpecific hosts: - "{{superset_hostname}}" annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/proxy_buffer_size: 64k nginx.ingress.kubernetes.io/proxy_buffers_number: "8" tls: - secretName: ingress-tls-csi hosts: - "{{superset_hostname}}" extraVolumes: - name: oauth2-secrets-store csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: oauth2-secret-provider - name: tls-secrets-store csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: azure-tls extraVolumeMounts: - mountPath: "/mnt/oauth2_secrets" name: oauth2-secrets-store readOnly: true - mountPath: "/mnt/tls-secrets-store" name: tls-secrets-store readOnly: true # Configure the session storage type, between cookie and redis sessionStorage: # Can be one of the supported session storage cookie/redis type: redis redis: # Secret name that holds the redis-password and redis-sentinel-password values existingSecret: oauth2-secret # Can be one of sentinel/cluster/standalone clientType: "standalone" # Enables and configure the automatic deployment of the redis subchart redis: enabled: true auth: existingSecret: oauth2-secret # Enables apiVersion deprecation checks checkDeprecation: true
Déployez des ressources proxy OAuth.
kubectl apply -f oauth2-secretprovider.yaml kubectl apply -f tls-secretprovider.yaml helm repo add oauth2-proxy https://oauth2-proxy.github.io/manifests helm repo update helm upgrade --install --values oauth2-values.yaml oauth2 oauth2-proxy/oauth2-proxy
Mettez à jour l’étiquette DNS dans l’adresse IP publique associée.
Ouvrez votre cluster Kubernetes AKS Superset dans le portail Azure.
Sélectionnez « Propriétés » dans la navigation de gauche.
Ouvrez le lien « Groupe de ressources d'infrastructure ».
Recherchez l'adresse IP publique avec ces balises :
{ "k8s-azure-cluster-name": "kubernetes", "k8s-azure-service": "default/ingress-nginx-controller" }
Sélectionnez « Configuration » dans la navigation de gauche de l'adresse IP publique.
Entrez l’étiquette du nom DNS avec le
<superset-instance-name>
défini dans la sélection du nom d’hôte.
Vérifiez que votre entrée pour OAuth est configurée.
Exécutez
kubectl get ingress
pour voir les deux entrées créées,azure-trino-superset
etoauth2-oauth2-proxy
. L’adresse IP correspond à l’adresse IP publique de l’étape précédente.De même, lorsque vous exécutez
kubectl get services
vous devez voir queingress-nginx-controller
a été affecté à unEXTERNAL-IP
.Conseil
Vous pouvez ouvrir
http://{{superset_hostname}}/oauth2
pour tester si le chemin OAuth fonctionne.Définissez une entrée pour fournir l’accès à Superset, mais redirigez tous les appels non autorisés vers
/oauth
.Mettez à jour dans le yaml suivant :
{{superset_hostname}}
– le nom d’hôte accessible sur Internet choisi dans la sélection du nom d’hôte
ingress.yaml
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: nginx nginx.ingress.kubernetes.io/auth-signin: https://$host/oauth2/start?rd=$escaped_request_uri nginx.ingress.kubernetes.io/auth-url: http://oauth2-oauth2-proxy.default.svc.cluster.local:80/oauth2/auth nginx.ingress.kubernetes.io/proxy-buffer-size: 64k nginx.ingress.kubernetes.io/proxy-buffers-number: "8" nginx.ingress.kubernetes.io/rewrite-target: /$1 generation: 1 labels: app.kubernetes.io/name: azure-trino-superset name: azure-trino-superset namespace: default spec: rules: - host: "{{superset_hostname}}" http: paths: - backend: service: name: superset port: number: 8088 path: /(.*) pathType: Prefix tls: - hosts: - "{{superset_hostname}}" secretName: ingress-tls-csi
Déployez votre entrée.
kubectl apply -f ingress.yaml
Effectuer des tests.
Ouvrez
https://{{superset_hostname}}/
dans votre navigateur.
Dépannage de l'entrée
Conseil
Pour réinitialiser le déploiement d’entrée, exécutez les commandes suivantes :
kubectl delete secret ingress-tls-csi
kubectl delete secret oauth2-secret
helm uninstall oauth2-proxy
helm uninstall ingress-nginx-superset
kubectl delete ingress azure-trino-superset
Après avoir supprimé ces ressources, vous devez suivre à nouveau ces instructions depuis le début.
Certificat de sécurité non valide : faux certificat du contrôleur d’entrée Kubernetes
Ceci provoque une erreur de vérification du certificat TLS dans votre navigateur/client. Pour voir cette erreur, inspectez le certificat dans un navigateur.
La cause habituelle de ce problème est que votre certificat est mal configuré :
Vérifiez que vous pouvez voir votre certificat dans Kubernetes :
kubectl get secret ingress-tls-csi --output yaml
Vérifiez que votre CN correspond au CN fourni dans votre certificat.
La non-concordance du CN est enregistrée dans le pod d’entrée. Ces journaux peuvent être consultés en exécutant
kubectl logs <ingress pod>
.Exemple :
kubectl logs ingress-nginx-superset-controller-f5dd9ccfd-qz8wc
L’erreur de non-concordance du CN est décrite avec cette ligne de journal :
Le certificat SSL « default/ingress-tls-csi » ne contient pas de nom commun ou d’autre nom d’objet pour le serveur « {nom du serveur} » : x509 : le certificat est valide pour {nom d’hôte non valide}, et non pas pour {nom d’hôte réel}
Impossible de résoudre l’hôte
Si le nom d’hôte ne peut pas être résolu pour l’instance Superset, l’adresse IP publique n’a pas de nom d’hôte affecté. Sans cette affectation, le DNS ne peut pas résoudre le nom d’hôte.
Vérifiez les étapes de la section Mettre à jour l’étiquette DNS dans l’adresse IP publique associée.
404 / nginx
Le contrôleur d’entrée Nginx ne trouve pas le Superset. Vérifiez que Superset est déployé en exécutant kubectl get services
et en vérifiant la présence d’un service superset
. Vérifiez que le service back-end dans ingress.yaml correspond au nom du service utilisé pour Superset.
503 Service temporairement indisponible / nginx
Le service est en cours d'exécution mais inaccessible. Check the service port numbers and service name.