Esporre Apache Superset su Internet
Questo articolo descrive come esporre Apache Superset a Internet.
Selezione del nome host
Scegliere un nome host per Superset.
A meno che non si usi un nome DNS personalizzato, questo nome host deve corrispondere al modello
<superset-instance-name>.<azure-region>.cloudapp.azure.com
. Il superset-instance-name deve essere univoco all'interno dell'area di Azure.Esempio:
myuniquesuperset.westus3.cloudapp.azure.com
Ottenere un certificato TLS per il nome host e inserirlo nel Key Vault, dandogli il nome
aks-ingress-tls
. Informazioni su come inserire un certificato in un Azure Key Vault.
Configurare l'ingresso
Le istruzioni seguenti aggiungono un secondo livello di autenticazione sotto forma di proxy di autorizzazione OAuth usando Oauth2Proxy. Questo livello significa che nessun client non autorizzato raggiunge l'applicazione Superset.
Aggiungi i seguenti segreti al tuo Key Vault.
Nome segreto Descrizione ID cliente ID cliente principale del servizio di Azure. Il proxy OAuth richiede che questo ID sia un segreto. oauth2proxy-redis-password Password della cache proxy. Password usata dal proxy OAuth per accedere all'istanza di distribuzione Redis back-end in Kubernetes. Generare una password sicura. oauth2proxy-cookie-secret Segreto cookie di 32 caratteri, usato per crittografare i dati del cookie. Questo segreto deve avere una lunghezza di 32 caratteri. Aggiungere i callback nella configurazione dell'applicazione Superset Azure AD.
https://{{superset_hostname}}/oauth2/callback
- per OAuth2 Proxy
https://{{superset_hostname}}/oauth-authorized/azure
- per Superset
Distribuire il controller ingress nginx nello spazio dei nomi
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"
Per istruzioni dettagliate, vedere le istruzioni di Azure qui .
Nota
I passaggi del controller Ingress NGINX utilizzano lo spazio dei nomi Kubernetes
ingress-basic
. Questa operazione deve essere modificata usando lo spazio dei nomidefault
. ad esempioNAMESPACE=default
Creare la classe del provider di segreto TLS.
Questo passaggio descrive come il certificato TLS viene letto dal Key Vault e trasformato in un segreto Kubernetes da utilizzare da ingress:
Eseguire l'aggiornamento nel file yaml seguente:
-
{{MSI_CLIENT_ID}}
: ID client dell'identità gestita assegnata al cluster Superset ($MANAGED_IDENTITY_RESOURCE
). -
{{KEY_VAULT_NAME}}
: nome di Azure Key Vault contenente i segreti. -
{{KEY_VAULT_TENANT_ID}}
: GUID del tenant di Azure dove si trova il 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}}"
-
Creare la OauthProxy Secret Provider Classe.
Eseguire l'aggiornamento nel file yaml seguente:
-
{{MSI_CLIENT_ID}}
: ID client dell'identità gestita assegnata al cluster Superset ($MANAGED_IDENTITY_RESOURCE
). -
{{KEY_VAULT_NAME}}
: Il nome dell'Azure Key Vault contenente i segreti. -
{{KEY_VAULT_TENANT_ID}}
- Il GUID del tenant di Azure in cui si trova la cassaforte delle chiavi.
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
-
Creare la configurazione per il proxy OAuth.
Eseguire l'aggiornamento nel file yaml seguente:
-
{{superset_hostname}}
: nome host con connessione Internet scelto nella selezione del nome host -
{{tenant-id}}
: GUID dell'identificatore del tenant di Azure in cui è stata creata l'entità servizio.
Facoltativo: aggiornare l'elenco dei domini email. Esempio:
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
-
Distribuire le risorse 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
Aggiornare l'etichetta DNS nell'indirizzo IP pubblico associato.
Apri il tuo cluster Kubernetes Superset AKS nel portale di Azure.
Selezionare "Proprietà" dalla barra di navigazione a sinistra.
Aprire il collegamento "Gruppo di risorse infrastrutturali".
Trovare l'indirizzo IP pubblico con questi tag:
{ "k8s-azure-cluster-name": "kubernetes", "k8s-azure-service": "default/ingress-nginx-controller" }
Selezionare "Configurazione" dalla sezione di navigazione a sinistra sotto "IP pubblico."
Immettere l'etichetta del nome DNS definita con il
<superset-instance-name>
nella selezione del nome host .
Verificare che l'ingresso per OAuth sia configurato.
Eseguire
kubectl get ingress
per visualizzare i due ingressi creatiazure-trino-superset
eoauth2-oauth2-proxy
. L'indirizzo IP corrisponde all'indirizzo IP pubblico del passaggio precedente.Analogamente, quando si esegue
kubectl get services
si noterà cheingress-nginx-controller
è stato assegnato unEXTERNAL-IP
.Consiglio
È possibile aprire
http://{{superset_hostname}}/oauth2
per verificare che il percorso OAuth funzioni.Definire un ingresso per fornire l'accesso a Superset, ma reindirizzare tutte le chiamate non autorizzate a
/oauth
.Eseguire l'aggiornamento nel file yaml seguente:
in ingresso.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
Implementare il vostro ingresso.
kubectl apply -f ingress.yaml
Test.
Aprire
https://{{superset_hostname}}/
nel browser.
Risoluzione dei problemi di ingresso
Suggerimento
Per reimpostare la distribuzione in ingresso, eseguire questi comandi:
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
Dopo aver eliminato queste risorse, sarà necessario riavviare queste istruzioni dall'inizio.
Certificato di sicurezza non valido: Certificato falso del controller di ingresso Kubernetes
Ciò causa un errore di verifica del certificato TLS nel browser o nel client. Per visualizzare questo errore, controllare il certificato in un browser.
La causa consueta di questo problema è che il certificato non è configurato correttamente:
Verificare che sia possibile visualizzare il certificato in Kubernetes:
kubectl get secret ingress-tls-csi --output yaml
Verificare che il CN corrisponda al CN fornito nel certificato.
La mancata corrispondenza CN viene registrata nel pod di ingresso. Questi log possono essere visualizzati eseguendo
kubectl logs <ingress pod>
.Esempio:
kubectl logs ingress-nginx-superset-controller-f5dd9ccfd-qz8wc
L'errore di mancata corrispondenza CN viene descritto con questa riga di Log:
Il certificato SSL "default/ingress-tls-csi" non contiene un nome comune o un nome alternativo soggetto per il server "{nome server}": x509: certificato valido per {nome host non valido}, non {nome host effettivo}
Impossibile risolvere l'host
Se il nome host non può essere risolto per l'istanza superset, all'indirizzo IP pubblico non è assegnato un nome host. Senza questa assegnazione, DNS non è in grado di risolvere il nome host.
Verificare i passaggi nella sezione Aggiornare l'etichetta DNS nell'indirizzo IP pubblico associato.
404/ nginx
Il controller di ingresso Nginx non riesce a trovare Superset. Assicuratevi che Superset sia implementato eseguendo kubectl get services
e verificando la presenza di un servizio superset
. Verificare che il servizio backend in ingress.yaml corrisponda al nome del servizio usato per Superset.
503 Servizio temporaneamente non disponibile/nginx
Il servizio è in esecuzione ma inaccessibile. Controllare i numeri di porta del servizio e il nome del servizio.