Apache Superset をインターネットに公開する
この記事では、Apache Superset をインターネットに公開する方法について説明します。
ホスト名の選択
スーパーセットのホスト名を決定します。
カスタム DNS 名を使用している場合を除き、このホスト名は次のパターンと一致する必要があります:
<superset-instance-name>.<azure-region>.cloudapp.azure.com
。 superset-instance-name は、Azure リージョン内で一意である必要があります。例:
myuniquesuperset.westus3.cloudapp.azure.com
ホスト名の TLS 証明書を取得して Key Vault に配置し、
aks-ingress-tls
呼び出します。 Azure Key Vaultに証明書を配置する方法について説明します。
イングレスを設定する
次の手順では、Oauth2Proxy を使用して、OAuth 承認プロキシの形式で認証の 2 番目のレイヤーを追加します。 このレイヤーは、承認されていないクライアントがスーパーセット アプリケーションに到達しなかったことを意味します。
次のシークレットを Key Vault に追加します。
シークレット名 説明 クライアントID Azure サービス プリンシパル クライアント ID。 OAuth プロキシでは、この ID がシークレットである必要があります。 oauth2proxy-redis-password プロキシ キャッシュのパスワード。 Kubernetes 上のバックエンド Redis デプロイ インスタンスにアクセスするために OAuth プロキシによって使用されるパスワード。 強力なパスワードを生成します。 oauth2proxy-cookie-secret 32 文字の Cookie シークレット。Cookie データの暗号化に使用されます。 このシークレットの長さは 32 文字にする必要があります。 これらのコールバックを Superset Azure AD アプリケーション構成に追加します。
https://{{superset_hostname}}/oauth2/callback
- OAuth2 プロキシの場合
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 シークレット プロバイダー クラスを作成します。
この手順では、TLS 証明書が Key Vault から読み取られ、イングレスで使用される Kubernetes シークレットに変換される方法について説明します。
次の yaml で更新します。
-
{{MSI_CLIENT_ID}}
- スーパーセット クラスターに割り当てられたマネージド ID のクライアント ID ($MANAGED_IDENTITY_RESOURCE
)。 -
{{KEY_VAULT_NAME}}
- シークレットを含む Azure Key Vault の名前。 -
{{KEY_VAULT_TENANT_ID}}
- Key Vault が配置されている Azure テナントの識別子 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}}
- スーパーセット クラスターに割り当てられたマネージド ID のクライアント ID ($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 プロキシの構成を作成します。
次の yaml で更新します。
-
{{superset_hostname}}
- インターネット向けのホスト名としてで選択されたホスト名 -
{{tenant-id}}
- サービス プリンシパルが作成された Azure テナントの GUID 形式の識別子。
省略可能: email_domainsリストを 更新します。 例:
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 プロキシ リソースをデプロイします。
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 portal で Superset AKS Kubernetes クラスターを開きます。
左側のナビゲーションから [プロパティ] を選択します。
[インフラストラクチャ リソース グループ] リンクを開きます。
次のタグを持つパブリック IP アドレスを見つけます。
{ "k8s-azure-cluster-name": "kubernetes", "k8s-azure-service": "default/ingress-nginx-controller" }
パブリック IP の左側のナビゲーションから [構成] を選択します。
のホスト名選択でに定義されている
<superset-instance-name>
の DNS 名ラベルを入力します。
OAuth のイングレスが構成されていることを確認します。
kubectl get ingress
を実行して、azure-trino-superset
とoauth2-oauth2-proxy
に作成された 2 つのイングレスを確認します。 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}}/
を開きます。
イングレスのトラブルシューティング
ヒント
イングレスデプロイをリセットするには、次のコマンドを実行します。
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 の不一致がイングレス ポッドに記録されます。 これらのログは、
kubectl logs <ingress pod>
を実行することで確認できます。例:
kubectl logs ingress-nginx-superset-controller-f5dd9ccfd-qz8wc
CN 不一致エラーは、次のログ行で説明されています。
SSL 証明書 "default/ingress-tls-csi" にサーバー "{server name}" の共通名またはサブジェクトの別名が含まれていません: x509: 証明書は {invalid hostname} に対して有効であり、{実際のホスト名} には含まれません
ホストを解決できませんでした
スーパーセット インスタンスのホスト名を解決できない場合、パブリック IP にはホスト名が割り当てられません。 この割り当てがないと、DNS はホスト名を解決できません。
関連するパブリック IP の DNS ラベルを更新セクションの手順を確認します。
404 / nginx
Nginx イングレス コントローラーがスーパーセットを見つけることができません。
kubectl get services
を実行し、superset
サービスの存在を確認して、Superset がデプロイされていることを確認します。
ingress.yaml のバックエンド サービスが、Superset に使用されるサービス名と一致するかどうかを確認します。
503 サービス一時的に利用できない/nginx
サービスは実行中ですが、アクセスできません。 サービス ポート番号とサービス名を確認します。