將 Apache Superset 公開至因特網
本文說明如何將 Apache Superset 公開至因特網。
主機名選取
決定 Superset 的主機名。
除非您使用自訂 DNS 名稱,否則此主機名應該符合模式:
<superset-instance-name>.<azure-region>.cloudapp.azure.com
。 超集實例名稱 在 Azure 區域內必須是唯一的。範例:
myuniquesuperset.westus3.cloudapp.azure.com
取得主機名的 TLS 憑證,並將它放入您的 Key Vault,並將其呼叫
aks-ingress-tls
。 瞭解如何將憑證放入 Azure Key Vault。
設定入口
下列指示會使用 Oauth2Proxy,以 OAuth 授權驗證代理的形式新增第二層驗證。 此層表示沒有任何未經授權的用戶端觸達超集應用程式。
將下列秘密新增至您的 Key Vault。
秘密名稱 描述 客戶身份識別碼 您的 Azure 服務主體用戶端標識碼。 OAuth Proxy 需要此標識符為秘密。 oauth2proxy-redis-password 代理快取密碼。 OAuth proxy 用來存取 Kubernetes 平台後端 Redis 部署實例的密碼。 產生強密碼。 oauth2proxy-cookie-secret 32 個字元的 Cookie 秘密,用來加密 Cookie 數據。 此秘密長度必須為32個字元。 在 Superset Azure AD 應用程式設定中新增這些回呼。
https://{{superset_hostname}}/oauth2/callback
- for OAuth2 Proxy
https://{{superset_hostname}}/oauth-authorized/azure
- 針對超集
將輸入 ngninx 控制器部署到
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"
如需詳細指示,請參閱此處 Azure 指示。
注意
入口 nginx 控制器的設定步驟使用了 Kubernetes 命名空間
ingress-basic
。 這需要修改以便使用default
命名空間。 例如NAMESPACE=default
建立 TLS 秘密提供者類別。
此步驟說明如何從 Key Vault 讀取 TLS 憑證,並將其轉換為供 Ingress 使用的 Kubernetes 密碼:
更新下列 YAML 檔案:
-
{{MSI_CLIENT_ID}}
- 指派給 Superset 叢集的受控識別之用戶端 ID($MANAGED_IDENTITY_RESOURCE
)。 -
{{KEY_VAULT_NAME}}
- 包含秘密的 Azure Key Vault 名稱。 -
{{KEY_VAULT_TENANT_ID}}
- Azure 租戶中 Key Vault 所在的識別碼 GUID。
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}}"
-
建立 OauthProxy 秘密提供者類別。
更新下列 YAML:
-
{{MSI_CLIENT_ID}}
- 指派給 Superset 叢集的受管理的身份識別的用戶端標識碼($MANAGED_IDENTITY_RESOURCE
)。 -
{{KEY_VAULT_NAME}}
- 儲存機密資訊的 Azure Key Vault 名稱。 -
{{KEY_VAULT_TENANT_ID}}
- 金鑰保存庫所在 Azure 租戶的識別符號 GUID。
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
-
建立 OAuth Proxy 的組態。
請更新下列「yaml」檔案:
-
{{superset_hostname}}
- 在 主機名稱選擇 中選擇的面向互聯網的主機名稱 -
{{tenant-id}}
- 建立您的服務主體的 Azure 租用戶之識別碼 guid。
選擇性: 更新電子郵件域名清單。 範例:
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
-
部署 OAuth Proxy 資源。
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
更新相關聯公用IP中的 DNS 標籤。
在 Azure 入口網站中開啟您的 Superset AKS Kubernetes 叢集。
從左側導覽中選取 [屬性]。
開啟 [基礎結構資源群組] 連結。
尋找具有下列標籤的公用 IP 位址:
{ "k8s-azure-cluster-name": "kubernetes", "k8s-azure-service": "default/ingress-nginx-controller" }
從 [公用 IP] 左側導覽中選取 [組態]。
輸入 DNS 名稱標籤
<superset-instance-name>
,該標籤是在 主機名選擇中定義的。
確認您已設定 OAuth 的入口。
執行
kubectl get ingress
以檢視建立的兩個入口azure-trino-superset
和oauth2-oauth2-proxy
。 IP 位址符合上一個步驟中的公用IP。同樣地,在執行
kubectl get services
時,您應該會看到ingress-nginx-controller
已指派EXTERNAL-IP
。提示
您可以開啟
http://{{superset_hostname}}/oauth2
,以測試 OAuth 路徑是否正常運作。定義輸入以提供對 Superset 的存取權,但將所有未經授權的呼叫重新導向至
/oauth
。更新下列 YAML 文件:
-
{{superset_hostname}}
- 在 主機名選取 中選擇的對外網路主機名稱
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
-
部署您的入口。
kubectl apply -f ingress.yaml
測試。
在瀏覽器中開啟
https://{{superset_hostname}}/
。
針對網路入口進行疑難解答
提示
若要重設 Ingress 部署,請執行下列命令:
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
刪除這些資源之後,您必須從頭重新啟動這些指示。
無效的安全性憑證:Kubernetes 輸入控制器假憑證
這會導致瀏覽器/客戶端發生 TLS 憑證驗證錯誤。 若要查看此錯誤,請在瀏覽器中檢查憑證。
此問題的一般原因是您的憑證設定錯誤:
確認您可以在 Kubernetes 中看到您的憑證:
kubectl get secret ingress-tls-csi --output yaml
請確認您的 CN 與憑證中提供的 CN 相符。
CN 不匹配會記錄在入口 Pod 中。 執行
kubectl logs <ingress pod>
即可看到這些記錄。範例:
kubectl logs ingress-nginx-superset-controller-f5dd9ccfd-qz8wc
CN 不符錯誤會使用此記錄列來描述:
SSL 憑證 “default/ingress-tls-csi” 不包含伺服器 “{server name}” 的一般名稱或主體別名“: x509: 憑證適用於 {無效的主機名},而不是 {實際主機名}
無法解析主機
如果無法解析超集實例的主機名,公用IP就不會指派主機名。 如果沒有此指派,DNS 就無法解析主機名。
驗證在章節 內,將相關聯的公用 IP中的 DNS 標籤進行更新的步驟。
404 / nginx
Nginx Ingress 控制器找不到 Superset。 請執行 kubectl get services
並檢查是否有 superset
服務,以確定超集已部署。 確認 ingress.yaml 中的後端服務 符合超集所使用的服務名稱。
503 服務暫時無法使用 / nginx
服務正在執行,但無法存取。 檢查服務埠號碼和服務名稱。