Snowpark Container Services: Zusätzliche Hinweise zu Diensten

SQL-Ausführung

Ihr Anwendungscontainer kann sich mit Snowflake verbinden und SQL ausführen. Unter diesem Thema wird beschrieben, wie der Containercode die erforderlichen Informationen für die Verbindung zu Snowflake erhält, einschließlich Authentifizierungsdaten, Datenbank- und Schemakontext des Service und das für die Ausführung von SQL-Anweisungen verwendete Warehouse.

Optionen für die Konfiguration der Anmeldeinformationen

Snowflake empfiehlt, dass Anwendungscontainer bei der Ausführung von SQL die von Snowflake bereitgestellten Anmeldeinformationen verwenden, um sich bei Snowflake zu authentifizieren. Obwohl es möglich ist, andere Anmeldeinformationen zu verwenden, indem Sie eine Verbindung über eine Integration für den externen Zugriff (EAI) herstellen, behandelt die Verbindung über eine EAI den Service so, als würde er außerhalb von Snowflake ausgeführt und stellte eine Verbindung zu Snowflake über das Internet her.

You have three options to connect to Snowflake from a service container:

  • Verwenden Sie die von Snowflake bereitgestellten Anmeldeinformationen für den Service: Snowflake liefert jedem Service Anmeldeinformationen, die als Serviceanmeldeinformationen bezeichnet werden. Ein Service verwendet diese Anmeldeinformationen, um sich als Servicebenutzer mit Snowflake zu verbinden.

  • Verwenden Sie von Snowflake bereitgestellte Aufrufer-Anmeldeinformationen (Aufruferrechte): Wenn Sie Ihren Service mit Aufruferrechten konfigurieren, stellt Snowflake auch Anmeldeinformationen bereit, damit der Service sich als aufrufender Benutzer mit Snowflake verbinden kann.

  • Use other credentials: In this case, you use an external access integration (EAI) that allows your service to connect to Snowflake’s internet endpoint by using valid authentication credentials. This option requires an administrator to create the EAI, and then grant the USAGE privilege on the integration to the service owner role.

    Bemerkung

    Die Verwendung von Integrationen für den externen Zugriff auf Snowflake kann bedeuten, dass potenziell sensible Informationen über das Internet gesendet werden.

Beispiele für Code, der verschiedene Snowflake-Treiber verwendet, um eine Verbindung zu Snowflake herzustellen, finden Sie unter `Beispiele für Snowflake-Verbindungen<https://github.com/Snowflake-Labs/sf-samples/tree/main/samples/spcs/sf-connection>`_.

Unter Verwendung der von Snowflake bereitgestellten Anmeldeinformationen für Servicebenutzer

Wenn Sie von Snowflake bereitgestellte Anmeldeinformationen für den Service verwenden, müssen Sie folgende Auswirkungen beachten:

  • Every object in Snowflake has an owner role, which is the role that is used to create the object. A service’s owner role determines the capabilities that the service is allowed when it interacts with Snowflake. These capabilities include executing SQL, accessing stages, and performing service-to-service networking.

  • When you create a service, Snowflake also creates a service user that is specific to that service. That service user has access to only two roles: the service owner role and the ‚PUBLIC‘ role. The default role for the service user is the service owner role.

When you start a service, including job services, Snowflake performs several actions. In each of your application containers, Snowflake enables the container code to use drivers for connecting to Snowflake and executing SQL, which is similar to any other code on your computer connecting to Snowflake. The following list shows the actions that Snowflake performs when you start a service:

  • Provides credentials (an OAuth token) in the container in a file that is named /snowflake/session/token. The container code uses these credentials to authenticate as the service user. This OAuth token can’t be used outside Snowpark Container Services

  • Sets the following environment variables for you to configure a Snowflake client in your service code:

    • SNOWFLAKE_ACCOUNT: This variable is set to the account locator for the Snowflake account that the service is currently running under.

    • SNOWFLAKE_HOST: This variable provides the hostname that is used to connect to Snowflake.

Wenn Sie als Servicebenutzer eine Verbindung zu Snowflake herstellen, muss der Containercode SNOWFLAKE_HOST, SNOWFLAKE_ACCOUNTund das OAuth-Token verwenden. Das OAuth-Token kann nicht ohne SNOWFLAKE_HOST verwendet werden.

Beispiel

In Tutorial 2 (siehe main.py) liest der Code die Umgebungsvariablen wie im folgenden Beispiel gezeigt:

SNOWFLAKE_ACCOUNT = os.getenv('SNOWFLAKE_ACCOUNT')
SNOWFLAKE_HOST = os.getenv('SNOWFLAKE_HOST')
Copy

The code passes these variables to a connection creation code for the Snowflake client of choice. The container uses these credentials to create a new session, with the service’s owner role as the session’s primary role, to run queries. The following example shows the minimum code that you need to create a Snowflake connection in Python:

def get_login_token():
  with open('/snowflake/session/token', 'r') as f:
    return f.read()

conn = snowflake.connector.connect(
  host = os.getenv('SNOWFLAKE_HOST'),
  account = os.getenv('SNOWFLAKE_ACCOUNT'),
  token = get_login_token(),
  authenticator = 'oauth'
)
Copy

Be aware of the following details about this OAuth token:

  • Snowflake refreshes the content of the /snowflake/session/token file every few minutes. Every token is valid for up to one hour. After a container connects to Snowflake successfully, the expiration time doesn’t apply to the connection, as is the case with any sessions that users create directly.

  • This OAuth token is valid only within the specific Snowflake service. You can’t copy the OAuth token and use it outside the service.

  • If you use the OAuth token to connect, it creates a new session. The OAuth token is not associated with any existing SQL session.

    Bemerkung

    A significant difference between executing stored procedures and executing a service is that stored procedures run in the same session as the SQL that runs the procedures. But every time a container establishes a new connection, you create a new session.

Um die von einem bestimmten Dienstbenutzer erstellten Abfragen einzusehen, können Sie die Rolle ACCOUNTADMIN verwenden und den Abfrageverlauf anzeigen. Der Benutzername des Dienstbenutzers wird in den folgenden Formen angezeigt:

  • Bei einem Service, der vor dem Release 8.35 des Servers erstellt wurde, hat der Dienstbenutzer das Format SF$SERVICE$unique-id.

  • Bei einem Service, der nach dem Release 8.35 des Servers erstellt wurde, ist der Dienstbenutzer derselbe wie der Name des Services.

Bemerkung

A service’s owner role is the role that created the service. You can define one or more service roles to manage access to the endpoints that the service exposes. For more information, see Verwaltung dienstbezogener Berechtigungen.

Allgemeine Informationen zur Verwendung der von Snowflake bereitgestellten Aufruferanmeldeinformationen (Aufruferrechte)

In certain application scenarios, you might need to execute queries by using the context of the end user rather than the service user as explained in the preceding section. The caller’s rights feature is used in this context.

For example, suppose that you create a service that exposes a public endpoint for a web application that displays a dashboard that uses data stored in Snowflake. You grant other users in your Snowflake account access to the dashboard by granting them the service role. When a user signs in, the dashboard displays only the data that user is authorized to access.

However, because containers by default execute queries by using the service user and the service’s owner role, the dashboard shows the data that the service’s owner role has access to, regardless of which end user connected to the endpoint. As a result, the dashboard isn’t limited to the data the end user is authorized to access, allowing the signed-in user to see data they shouldn’t have access to.

To limit the dashboard to show only data that is accessible to the signed in user, the application containers must execute SQL by using privileges granted to the end user. You can enable this by using caller’s rights in the application.

Bemerkung

  • The caller’s rights feature is supported only when accessing a service using network ingress. The feature isn’t available when using a service function to access the service.

  • Das Aufruferrechte-Feature wird derzeit in Snowflake Native App (Apps mit Containern nicht) unterstützt.

Configure caller’s rights for your service

Configuring caller’s rights for your application is a two-step procedure.

  1. In the service specification, set the executeAsCaller to true, in as shown in the following specification fragment:

    spec:
      containers:
      ...
    capabilities:
      securityContext:
        executeAsCaller: true
    
    Copy

    This setting tells Snowflake that the application intends to use caller’s rights and causes Snowflake to insert the Sf-Context-Current-User-Token header in every incoming request before sending the request to the application container. This user token facilitates query execution as the calling user. If not specified, executeAsCaller defaults to false.

    Specifying the executeAsCaller option doesn’t affect the service’s ability to execute queries as the service user and service’s owner role. With executeAsCaller enabled, the service has the option to connect to Snowflake both as a calling user and as a service user.

  2. To establish a Snowflake connection on behalf of the calling user, update your application code to create a login token that includes both the OAuth token that Snowflake provided to the service and the user token from the Sf-Context-Current-User-Token header.

    Das Anmeldetoken muss diesem Format entsprechen: <service-oauth-token>.<Sf-Context-Current-User-Token>.

    This update is demonstrated in the following Python code fragment:

    # Environment variables below will be automatically populated by Snowflake.
    SNOWFLAKE_ACCOUNT = os.getenv("SNOWFLAKE_ACCOUNT")
    SNOWFLAKE_HOST = os.getenv("SNOWFLAKE_HOST")
    
    def get_login_token():
        with open("/snowflake/session/token", "r") as f:
            return f.read()
    
    def get_connection_params(ingress_user_token = None):
        # start a Snowflake session as ingress user
        # (if user token header provided)
        if ingress_user_token:
            logger.info("Creating a session on behalf of the current user.")
            token = get_login_token() + "." + ingress_user_token
        else:
            logger.info("Creating a session as the service user.")
            token = get_login_token()
    
        return {
            "account": SNOWFLAKE_ACCOUNT,
            "host": SNOWFLAKE_HOST,
            "authenticator": "oauth",
            "token": token
        }
    
    def run_query(request, query):
        ingress_user_token = request.headers.get('Sf-Context-Current-User-Token')
        # ingress_user_token is None if header not present
        connection_params = get_connection_params(ingress_user_token)
        with Session.builder.configs(connection_params).create() as session:
          # use the session to execute a query.
    
    Copy

Im obigen Beispiel:

  • Die Funktion get_login_token liest die Datei, in die Snowflake das OAuth-Token für den zu verwendenden Container kopiert hat.

  • The get_connection_params function constructs a token by concatenating the OAuth token and the user token from the Sf-Context-Current-User-Token header. The function includes this token in a dictionary of parameters that the application uses to connect to Snowflake.

Bemerkung

When a service uses caller’s rights, it can connect to Snowflake as multiple users. You are responsible for managing access to resources that arn’t managed by Snowflake.

For example, in Streamlit apps, the st.connection object automatically caches the connection by using st.cache_resource in the global state, making it accessible across Streamlit sessions that are started by different users. When you use caller’s rights, consider using st.session_state to store connections on a per-session basis to avoid sharing connections between users.

For an example with step-by-step instructions, see Create a service with caller’s rights enabled.

Zugriff auf einen Dienst mit konfigurierten Aufruferrechten

Configuring caller’s rights means that your service is establishing a Snowflake connection on behalf of the caller. How you log in to the service’s ingress endpoints, either programmatically or by using a browser, remains the same. After log in, the following behaviors and optionsapply:

  • Accessing a public endpoint using a browser: After you log into an endpoint, the service establishes a connection to** Snowflake on behalf of the calling user using the default role of the user. If there is no default role configured for the user, the PUBLIC role is used.

  • Accessing a public endpoint programmatically: When logging into an endpoint programmatically using JWT token, you can optionally set the scope parameter to specify the role to activate

Currently, after a service establishes a caller’s right connection to Snowflake on behalf of the caller, switching roles is not supported. If your application needs to use different roles to access different objects, you must change the user’s default secondary roles property.

  • To set up the user to have all secondary roles active by default, use the ALTER USER command to set the DEFAULT_SECONDARY_ROLES property of the user to (‚ALL‘), as shown in the following example:

ALTER USER my_user SET DEFAULT_SECONDARY_ROLES = ( 'ALL' );
Copy
Verwalten von Aufruferberechtigungen für einen Dienst

When a service creates a caller’s rights session, the session operates as the calling user, not as the service user. When an operation is performed by using this session, Snowflake applies a sequence oftwo permissions checks:

  1. The first permissions check is performed as if the user created the session directly. This check is part of thenormal permission checks that Snowflake performs for the user.

  2. The second permissions check verifies that the service is allowed to perform the operation on behalf of a user. Snowflake verifies this by ensuring that the service’s owner role was granted the necessary caller grants.

In einer Sitzung mit Aufruferrechten müssen sowohl die normale Berechtigungsprüfung als auch die Prüfung der Aufruferrechte der Rolle des Diensteigentümers die Operation erlauben. Dies wird als eingeschränkte Aufruferrechte bezeichnet. Standardmäßig hat der Dienst keine Berechtigung, etwas im Namen eines Benutzers zu tun. Sie müssen dem Dienst explizit Aufruferrechte gewähren, damit er mit den Berechtigungen des Aufrufers ausgeführt werden kann.

For example, suppose a user U1 uses a role R1 that has the SELECT privilege on the table T1. When U1 logs into the public endpoint of your service (example_service), which is configured to use the caller’s rights, the service then establishes a connection with Snowflake on behalf of U1.

Damit der Dienst die Tabelle T1 im Namen von U1 abfragen kann, müssen Sie der Rolle des Diensteigentümers die folgenden Berechtigungen erteilen:

  • Berechtigungen zur Auflösung des Tabellennamens, indem einem Aufrufer eine Berechtigung gewährt wird, die es dem Dienst ermöglicht, mit der USAGE-Berechtigung auf der Datenbank und dem Schema für diese Tabelle zu arbeiten.

  • Berechtigung zur Verwendung eines Warehouse, um Abfragen auszuführen, indem einem Aufrufer eine Berechtigung gewährt wird, die es dem Dienst ermöglicht, mit der entsprechende USAGE-Berechtigung auf dem Warehouse zu arbeiten.

  • Berechtigungen zur Abfrage der Tabelle, indem einem Aufrufer eine Berechtigung gewährt wird, die es dem Dienst ermöglicht, mit der SELECT-Berechtigung auf der Tabelle T1 ausgeführt zu werden.

Das folgende Beispiel zeigt, wie Sie der Eigentümerrolle des Services diese Berechtigungen zuweisen:

-- Permissions to resolve the table's name.
GRANT CALLER USAGE ON DATABASE <db_name> TO ROLE <service_owner_role>;
GRANT CALLER USAGE ON SCHEMA <schema_name> TO ROLE <service_owner_role>;
-- Permissions to use a warehouse
GRANT CALLER USAGE ON WAREHOUSE <warehouse_name> TO ROLE <service_owner_role>;
-- Permissions to query the table.
GRANT CALLER SELECT ON TABLE T1 TO ROLE <service_owner_role>;
Copy

Jede Rolle in Ihrem Konto, die über die globale Berechtigung MANAGE CALLER GRANT verfügt, kann Aufruferberechtigungen gewähren. Weitere Informationen über Aufruferrechte finden Sie unter GRANT CALLER und Eingeschränkte Aufruferrechte.

Beispiel

For an example of a service that uses the caller’s rights feature when executing SQL queries on behalf of the users is provided. For more information, see Create a service with caller’s rights enabled.

Connect to Snowflake by using other credentials

Sie können auch andere Formen der Authentifizierung verwenden, um eine Verbindung zu Snowflake herzustellen, nicht nur das von Snowflake bereitgestellte OAuth-Token. Dazu erstellen Sie eine Integration für den externen Zugriff (EAI, External Access Integration), die es Ihrem Container ermöglicht, eine Verbindung zu Snowflake herzustellen, als ob der Container außerhalb von Snowflake ausgeführt wird und sich über das Internet verbindet. Wenn Sie sich auf diese Weise verbinden, müssen Sie nicht den Host konfigurieren, der vom Client verwendet wird.

Bemerkung

Da diese Verbindungen einen EAI durchlaufen, setzt die Snowflake-Authentifizierung auch Netzwerkrichtlinien durch. Wenn Ihr Unternehmen Netzwerkrichtlinien erfordert, wird das Verbinden mit anderen Anmeldeinformationen nicht unterstützt.

Bei der folgenden Verbindung werden zur Authentifizierung beispielsweise Benutzername und Kennwort angegeben:

conn = snowflake.connector.connect(
  account = '<acct-name>',
  user = '<user-name>',
  password = '<password>'
)
Copy

To use a default hostname, you need external access integration with a network rule that allows access from your service to the Snowflake internet hostname for your account. For example, if your account name is MYACCOUNT in the organization MYORG, the hostname is myorg-myaccount.snowflakecomputing.com. For more information, see Konfigurieren des Netzwerkausgangs. Privatelink hostnames are not supported

  • Erstellen Sie eine Netzwerkregel, die einen Abgleich mit Snowflake-API-Hostnamen Ihres Kontos vornimmt:

    CREATE OR REPLACE NETWORK RULE snowflake_egress_access
      MODE = EGRESS
      TYPE = HOST_PORT
      VALUE_LIST = ('myorg-myaccount.snowflakecomputing.com');
    
    Copy
  • Erstellen Sie eine Integration unter Verwendung der obigen Netzwerkregel:

    CREATE EXTERNAL ACCESS INTEGRATION snowflake_egress_access_integration
      ALLOWED_NETWORK_RULES = (snowflake_egress_access)
      ENABLED = TRUE;
    
    Copy

Configuration of the database and schema context for executing SQL

Neben der Bereitstellung von Anmeldeinformationen stellt Snowflake auch den Datenbank- und Schemakontext bereit, in dem der Service erstellt wird. Der Containercode kann diese Informationen zur Ausführung von SQL im gleichen Datenbank- und Schemakontext wie der Service verwenden.

In diesem Abschnitt werden zwei Konzepte erläutert:

  • Die Logik, mit der Snowflake Datenbank und Schema bestimmt, in dem Ihr Dienst erstellt werden soll.

  • Die Methode, mit der Snowflake diese Informationen an Ihre Container weitergibt, sodass der Containercode SQL im gleichen Datenbank- und Schemakontext ausführen kann.

Snowflake verwendet den Dienstnamen, um die Datenbank und das Schema zu bestimmen, in denen ein Dienst erstellt werden soll:

  • Beispiel 1: In den folgenden Befehlen CREATE SERVICE und EXECUTE JOB SERVICE gibt der Dienstname nicht explizit einen Datenbank- und Schemanamen an. Snowflake erstellt den Dienst und den Jobdienst in der aktuellen Datenbank und dem aktuellen Schema.

    -- Create a service.
    CREATE SERVICE test_service IN COMPUTE POOL ...
    
    -- Execute a job service.
    EXECUTE JOB SERVICE
      IN COMPUTE POOL tutorial_compute_pool
      NAME = example_job_service ...
    
    Copy
  • Beispiel 2: In den folgenden Befehlen CREATE SERVICE und EXECUTE JOB SERVICE enthält der Dienstname einen Datenbank- und einen Schemanamen. Snowflake erstellt den Dienst und den Jobdienst in der angegebenen Datenbank (test_db) und dem angegebenen Schema (test_schema), unabhängig vom aktuellen Schema.

    -- Create a service.
    CREATE SERVICE test_db.test_schema.test_service IN COMPUTE POOL ...
    
    -- Execute a job service.
    EXECUTE JOB SERVICE
      IN COMPUTE POOL tutorial_compute_pool
      NAME = test_db.test_schema.example_job_service ...
    
    Copy

Wenn Snowflake einen Dienst startet, werden den ausgeführten Containern die Datenbank- und Schemainformationen über die folgenden Umgebungsvariablen zur Verfügung gestellt:

  • SNOWFLAKE_DATABASE

  • SNOWFLAKE_SCHEMA

Ihr Containercode kann Umgebungsvariablen im Verbindungscode verwenden, um die zu verwendende Datenbank und das Schema zu bestimmen, wie im folgenden Beispiel gezeigt:

conn = snowflake.connector.connect(
  host = os.getenv('SNOWFLAKE_HOST'),
  account = os.getenv('SNOWFLAKE_ACCOUNT'),
  token = get_login_token(),
  authenticator = 'oauth',
  database = os.getenv('SNOWFLAKE_DATABASE'),
  schema = os.getenv('SNOWFLAKE_SCHEMA')
)
Copy

Beispiel

In Tutorial 2 erstellen Sie einen Snowflake-Jobdienst, der sich mit Snowflake verbindet und SQL-Anweisungen ausführt. Die folgenden Schritte fassen zusammen, wie der Tutorial-Code die Umgebungsvariablen verwendet:

  1. Bei der grundlegenden Einrichtung (siehe Abschnitt Grundlegende Einrichtung) erstellen Sie Ressourcen, einschließlich einer Datenbank und eines Schemas. Sie legen auch die aktuelle Datenbank und das aktuelle Schema für die Sitzung fest:

    USE DATABASE tutorial_db;
    ...
    USE SCHEMA data_schema;
    
    Copy
  2. Nachdem Sie einen Jobdienst erstellt haben (durch Ausführen von EXECUTE JOB SERVICE), startet Snowflake den Container und setzt die folgenden Umgebungsvariablen im Container auf die aktuelle Datenbank und das aktuelle Schema der Sitzung:

    • SNOWFLAKE_DATABASE ist auf „TUTORIAL_DB“ gesetzt.

    • SNOWFLAKE_SCHEMA ist auf „DATA_SCHEMA“ gesetzt.

  3. Der Jobcode (siehe main.py in Tutorial 2) liest diese Umgebungsvariablen aus:

    SNOWFLAKE_DATABASE = os.getenv('SNOWFLAKE_DATABASE')
    SNOWFLAKE_SCHEMA = os.getenv('SNOWFLAKE_SCHEMA')
    
    Copy
  4. Der Jobcode legt die Datenbank und das Schema als Kontext fest, in dem die SQL-Anweisungen ausgeführt werden (Funktion run_job() in main.py):

    {
       "account": SNOWFLAKE_ACCOUNT,
       "host": SNOWFLAKE_HOST,
       "authenticator": "oauth",
       "token": get_login_token(),
       "warehouse": SNOWFLAKE_WAREHOUSE,
       "database": SNOWFLAKE_DATABASE,
       "schema": SNOWFLAKE_SCHEMA
    }
    ...
    
    Copy

    Bemerkung

    SNOWFLAKE_ACCOUNT SNOWFLAKE_HOST, SNOWFLAKE_DATABASE, SNOWFLAKE_SCHEMA sind Umgebungsvariablen, die Snowflake für den Anwendungscontainer generiert, allerdings nicht SNOWFLAKE_WAREHOUSE (der Anwendungscode von Tutorial 2 erstellt diese Variable, da Snowflake keinen Warehouse-Namen an einen Container übergibt).

Angeben des Warehouses für Ihren Container

Wenn Ihr Dienst eine Verbindung zu Snowflake herstellt, um eine Abfrage in einem Snowflake-Warehouse auszuführen, haben Sie die folgenden Optionen für die Angabe des Warehouses:

  • Warehouse in Ihrem Anwendungscode angeben. Geben Sie ein Warehouse als Teil der Verbindungskonfiguration an, wenn Sie eine Snowflake-Sitzung zum Ausführen von Abfragen in Ihrem Code starten. Ein Beispiel dazu finden Sie unter Tutorial 2.

  • Specify a default warehouse when creating a service. Specify the optional QUERY_WAREHOUSE parameter in the CREATE SERVICE or EXECUTE JOB SERVICE command to provide a default warehouse. If your application code doesn’t provide a warehouse as part of connection configuration, Snowflake uses the default warehouse. Use the ALTER SERVICE command to change the default warehouse.

    Bemerkung

    Das Warehouse, das mit dem QUERY_WAREHOUSE-Parameter angegeben wurde, ist der Standard nur für Servicebenutzer. Wenn der Service im Namen eines anderen Benutzers eine Verbindung zu Snowflake herstellt – im Kontext des Szenarios der Aufruferrechte –, verwendet Snowflake das Standard-Warehouse des Benutzers.

If you specify a warehouse by using both methods, the warehouse that is specified in the application code is used.

Access service user query history

You can find queries executed by your service as the service user by filtering the Ansicht QUERY_HISTORY or QUERY_HISTORY function where user_type is SNOWFLAKE_SERVICE.

Beispiel 1: Abrufen von Abfragen, die von einem Dienst ausgeführt werden.

SELECT *
FROM snowflake.account_usage.query_history
WHERE user_type = 'SNOWFLAKE_SERVICE'
AND user_name = '<service_name>'
AND user_database_name = '<service_db_name>'
AND user_schema_name = '<service_schema_name>'
order by start_time;
Copy

Für die WHERE-Klausel gilt:

  • user_name = '<service_name>': Sie geben den Dienstnamen als Benutzernamen an, da ein Dienst Abfragen als Dienstbenutzer ausführt und der Name des Dienstbenutzers mit dem Dienstnamen identisch ist.

  • user_type = 'SNOWFLAKE_SERVICE' und user_name = '<service_name>': Dies schränkt das Abfrageergebnis so ein, dass nur von einem Dienst ausgeführte Abfragen abgerufen werden.

  • user_database_name und user_schema_name: Für einen Benutzer eines Dienstes sind dies die Datenbank und das Schema des Dienstes.

Sie können die gleichen Ergebnisse erzielen, indem Sie die Funktion QUERY_HISTORY aufrufen.

SELECT *
FROM TABLE(<service_db_name>.information_schema.query_history())
WHERE user_database_name = '<service_db_name>'
AND user_schema_name = '<service_schema_name>'
AND user_type = 'SNOWFLAKE_SERVICE'
AND user_name = '<service_name>'
order by start_time;
Copy

Für die WHERE-Klausel gilt:

  • user_type = 'SNOWFLAKE_SERVICE' und user_name = '<service_name>' schränken das Abfrageergebnis so ein, dass nur von einem Dienst ausgeführte Abfragen abgerufen werden.

  • user_database_name- und user_schema_name-Namen (für einen Dienstbenutzer) sind die Datenbank und das Schema des Dienstes.

Beispiel 2: Von Diensten ausgeführte Abfragen und die entsprechenden Dienstinformationen abrufen.

SELECT query_history.*, services.*
FROM snowflake.account_usage.query_history
JOIN snowflake.account_usage.services
ON query_history.user_name = services.service_name
AND query_history.user_schema_id = services.service_schema_id
AND query_history.user_type = 'SNOWFLAKE_SERVICE'
Copy

Die Abfrage verknüpft die Ansichten QUERY_HISTORY und SERVICES, um Informationen über die Abfragen und die Dienste, die die Abfragen ausführten, abzurufen. Beachten Sie Folgendes:

  • Bei Abfragen, die von Diensten ausgeführt werden, ist query_history.user_name der Name des Dienstbenutzers, der mit dem Dienstnamen übereinstimmt.

  • Die Abfrage verbindet die Ansichten anhand des Schemas IDs (nicht des Schemanamens), um sicherzustellen, dass Sie sich auf dasselbe Schema beziehen. Denn wenn Sie ein Schema löschen und neu erstellen, ändert sich das Schema ID, aber der Name bleibt derselbe.

Sie können der Abfrage optionale Filter hinzufügen. Beispiel:

  • query_history-Filter, um nur Dienste abzurufen, die bestimmte Abfragen ausgeführt haben.

  • services-Filter, um nur Abfragen abzurufen, die von bestimmten Diensten ausgeführt wurden.

Beispiel 3: Abrufen von Dienstbenutzerinformationen für jeden Dienst.

SELECT services.*, users.*
FROM snowflake.account_usage.users
JOIN snowflake.account_usage.services
ON users.name = services.service_name
AND users.schema_id = services.service_schema_id
AND users.type = 'SNOWFLAKE_SERVICE'
Copy

Die Abfrage verbindet die Ansichten SERVICES und USERS im Schema ACCOUNT_USAGE, um Dienste und Benutzerinformationen abzurufen. Beachten Sie Folgendes:

  • Wenn ein Dienst Abfragen ausführt, führt er die Abfragen als Dienstbenutzer aus, und der Name des Dienstbenutzers ist derselbe wie der Dienstname. Daher geben Sie die Join-Bedingung an: users.name = services.service_name.

  • Dienstnamen sind nur innerhalb eines Schemas eindeutig. Daher gibt die Abfrage die Join-Bedingung (users.schema_id = services.service_schema_id) an, um sicherzustellen, dass jeder Dienstbenutzer mit dem spezifischen Dienst abgeglichen wird, zu dem er gehört (und nicht mit einem anderen gleichnamigen Dienst, der in verschiedenen Schemas läuft).

Konfigurieren des Netzwerkeingangs

Um eine Interaktion mit Ihrem Dienst vom Internet aus zu ermöglichen, deklarieren Sie die Netzwerkports, die von Ihrem Dienst überwacht werden, als Endpunkte in der Dienstspezifikationsdatei. Diese Endpunkte kontrollieren den eingehenden Datenverkehr.

Standardmäßig sind die Dienstendpunkte privat. Nur Dienstfunktionen und die Dienst-zu-Dienst-Kommunikation können Anforderungen an die privaten Endpunkte senden. Sie können einen Endpunkt als öffentlich deklarieren, um Anfragen an einen Endpunkt aus dem Internet zuzulassen. Die Erstellung eines öffentlichen Endpunkts ist eine privilegierte Operation und die Eigentümerrolle des Dienstes muss die Berechtigung BIND SERVICE ENDPOINT für das Konto haben.

endpoints:
- name: <endpoint name>
  port: <port number>
  protocol : < TCP / HTTP >
  public: true
  corsSettings:                  # optional CORS configuration
    Access-Control-Allow-Origin: # required list of allowed origins
      - <origin>                 # for example, "http://example.com"
      - <origin>
        ...
    Access-Control-Allow-Methods: # optional list of HTTP methods
      - <method>
      - <method>
        ...
    Access-Control-Allow-Headers: # optional list of HTTP headers
      - <header-name>
      - <header-name>
        ...
    Access-Control-Expose-Headers: # optional list of HTTP headers
      - <header-name>
      - <header-name>
        ...
Copy

Ein Beispiel dazu finden Sie unter Tutorial 1.

Timeout der eingehenden Verbindung

Eingangsendpunkte haben ein Timeout von 90 Sekunden. Wenn 90 Sekunden lang keine Aktivität bei einer Verbindung zu einem Endpunkt stattfindet, bricht Snowflake die Verbindung ab. Wenn Ihre Anwendung eine längere Konnektivität benötigt, verwenden Sie Polling oder WebSockets.

Eingangs-Webbrowser Authentifizierung Abmeldung

Wenn Sie eine Webanwendung erstellen, die als Dienst ausgeführt wird, haben Sie die Möglichkeit, Benutzern die Abmeldung von Ihrer Anwendung zu ermöglichen, indem Sie sie an /sfc-endpoint/logout weiterleiten.

Nach der Abmeldung muss sich der Benutzer erneut bei Snowflake authentifizieren, um auf den öffentlichen Endpunkt des Dienstes zuzugreifen.

Sicherheit von Eingangsdatenverkehr und Webanwendungen

Sie können einen Snowpark Container Services-Dienst für das Webhosting erstellen, indem Sie die Unterstützung für öffentliche Endpunkte (Netzwerkeingang) nutzen. Für zusätzliche Sicherheit setzt Snowflake einen Proxydienst ein, um eingehende Anforderungen von Clients an Ihren Dienst und ausgehende Antworten von Ihrem Dienst an die Clients zu überwachen. In diesem Abschnitt wird erklärt, was der Proxy tut und wie er sich auf einen Dienst auswirkt, der in Snowpark Container Services bereitgestellt wird.

Bemerkung

Wenn Sie einen Dienst lokal testen, verwenden Sie nicht den Snowflake-Proxy. Daher wird es Unterschiede zwischen der lokalen Ausführung eines Dienstes und der Bereitstellung in Snowpark Container Services geben. Lesen Sie diesen Abschnitt, und aktualisieren Sie Ihre lokalen Einstellungen, um das Testen zu optimieren.

Beispiel:

  • Der Proxy leitet eine eingehende HTTP-Anforderung nicht weiter, wenn die Anforderung eine nicht zulässige HTTP-Methode verwendet.

  • Der Proxy sendet eine 403-Antwort an den Client, wenn der Content-Type-Header in der Antwort angibt, dass die Antwort eine ausführbare Datei enthält.

Darüber hinaus kann der Proxy auch neue Kopfzeilen einfügen und bestehende Kopfzeilen in der Anforderung und der Antwort ändern, wobei Ihr Container und Ihre Datensicherheit berücksichtigt werden.

Beispielsweise könnte Ihr Dienst nach Erhalt einer Anforderung in der Antwort HTML-, JavaScript-, CSS- und andere Inhalte für eine Webseite an den Client-Browser senden. Die Webseite im Browser ist Teil Ihres Dienstes und dient als Benutzerschnittstelle. Wenn Ihr Dienst aus Sicherheitsgründen Einschränkungen unterliegt (z. B. bezüglich des Herstellens von Netzwerkverbindungen zu anderen Standorten), möchten Sie vielleicht auch, dass die Webseite Ihres Dienstes denselben Einschränkungen unterliegt.

Standardmäßig haben Dienste nur begeschränkte Berechtigungen für den Zugriff auf das Internet. Der Browser sollte auch verhindern, dass die Clientanwendung auf das Internet zugreift und möglicherweise in den meisten Fällen Daten freigibt. Wenn Sie eine Integration des externen Zugriffs (EAI) eingerichtet haben, um Ihrem Dienst den Zugriff auf example.com zu ermöglichen (siehe Konfigurieren des Netzwerkausgangs), sollte die Webseite für Ihren Dienst auch über Ihren Browser auf example.com zugreifen können.

Der Snowflake-Proxy wendet dieselben Netzwerkbeschränkungen auf den Dienst und die Webseite an, indem er einen CSP-Header (Content-Security-Policy) in die Antwort einfügt. Standardmäßig fügt der Proxy eine Baseline-CSP in die Antwort ein, um Schutz vor allgemeinen Sicherheitsbedrohungen zu bieten. Bei der Browser-Sicherheit geht es darum, ein Gleichgewicht zwischen Funktionalität und Sicherheit zu finden. Es liegt in der gemeinsamen Verantwortung sicherzustellen, dass diese Basis für Ihren Anwendungsfall geeignet ist. Wenn Ihr Dienst so konfiguriert ist, dass eine EAI verwendet wird, wendet der Proxy außerdem dieselben Netzwerkregeln von der EAI auf die CSP der Webseite an. Diese CSP ermöglicht der Webseite im Browser auf dieselben Standorte zuzugreifen, auf die auch der Dienst zugreifen kann.

Snowflake bietet CORS-Unterstützung, die Sie in der Dienstspezifikation konfigurieren.

Der Snowflake-Proxy gibt die in der Dienstspezifikation definierten CORS-Einstellungen zurück. Beachten Sie, dass der Proxy alle vom Dienst zurückgegebenen CORS-Header entfernt.

Die folgenden CORS-Header sind standardmäßig eingestellt:

  • Access-Control-Expose-Headers-Header meldet immer die folgenden Header-Namen, zusätzlich zu den in der Dienstspezifikation für den Endpunkt konfigurierten Headern.

    • X-Frame-Options

    • Cross-Origin-Opener-Policy

    • Cross-Origin-Resource-Policy

    • X-Content-Type-Options

    • Cross-Origin-Embedder-Policy

    • Content-Security-Policy-Report-Only

    • Content-Security-Policy

  • Access-Control-Max-Age ist auf zwei Stunden eingestellt.

  • Access-Control-Allow-Credentials auf „true“ gesetzt ist.

Außerdem setzt Snowflake den Header Vary mit dem Wert Origin, um dem Browser anzuzeigen, dass der Wert für Access-Control-Allow-Origin je nach dem Wert von Origin unterschiedlich sein kann.

Der Header Authorization ist erforderlich, um die CORS-Anforderung zu erstellen. Sie können ein programmgesteuertes Zugriffstoken angeben (PAT) – in diesem Header (Authorization: "Snowflake Token=\"${patToken}\""). Informationen zum Generieren eines programmgesteuerten Zugriffstokens finden Sie unter Verwenden von programmatische Zugriffstoken für die Authentifizierung.

In den folgenden Abschnitten wird erläutert, wie der Snowflake-Proxy eingehende Anforderungen für Ihren Dienst verarbeitet und die ausgehenden Antworten Ihres Dienstes an die Clients modifiziert.

Beim Dienst eingehende Anforderungen

Wenn eine Anforderung eintrifft, führt der Proxy folgende Schritte aus, bevor er die Anforderung an den Dienst weiterleitet:

  • Eingehende Anforderungen mit nicht zulässigen HTTP-Methoden: Wenn eine eingehende HTTP-Anforderung eine der folgenden nicht zulässigen HTTP-Methoden verwendet, leitet der Proxy die Anforderung nicht an Ihren Dienst weiter:

    • TRACE

    • CONNECT

  • Header-Scrubbing für eingehende Anfragen: Der Snowflake-Proxy entfernt die folgenden Anfrage-Header, falls vorhanden:

    • X-SF-SPCS-Authorization

    • Authorization: Wird nur entfernt, wenn er ein Snowflake-Token enthält; andernfalls wird er an Ihren Dienst weitergeleitet.

An die Clients ausgehende Antworten

Der Snowflake-Proxy wendet diese Änderungen auf die von Ihrem Dienst gesendete Antwort an, bevor er die Antwort an den Client weiterleitet.

  • Header Scrubbing: Der Snowflake-Proxy entfernt diese Antwort-Header, falls vorhanden:

    • X-XSS-Protection

    • Server

    • X-Powered-By

    • Public-Key-Pins

  • CORS Header-Manipulation: Siehe Überlegungen zum Zugriff und CORS.

  • Antwort-Header „Content-Type“: Wenn die Antwort Ihres Dienstes den „Content-Type“-Header mit einem der folgenden Werte des MIME-Typs (der auf eine ausführbare Datei hinweist) enthält, leitet der Snowflake-Proxy diese Antwort nicht an den Client weiter. Stattdessen sendet der Proxy eine 403 Forbidden-Antwort.

    • application/x-msdownload: ausführbare Microsoft-Datei.

    • application/exe: allgemeine ausführbare Datei.

    • application/x-exe: eine weitere allgemeine ausführbare Datei.

    • application/dos-exe: ausführbare DOS-Datei.

    • application/x-winexe: ausführbare Windows-Datei.

    • application/msdos-windows: ausführbare MS-DOS-Windows-Datei.

    • application/x-msdos-program: ausführbare MS-DOS-Datei.

    • application/x-sh: Unix-Shell-Skript.

    • application/x-bsh: Bourne-Shell-Skript.

    • application/x-csh: C-Shell-Skript.

    • application/x-tcsh: Tcsh-Shell-Skript.

    • application/batch: Windows-Batch-Datei.

  • Antwort-Header „X-Frame-Options“: Um Clickjacking-Angriffe zu verhindern, setzt der Snowflake-Proxy diesen Antwort-Header auf DENY und verhindert so, dass andere Webseiten einen iFrame zur Webseite für Ihren Dienst verwenden.

  • Antwort-Header „Cross-Origin-Opener-Policy“ (COOP): Snowflake setzt den COOP-Antwort-Header auf same-origin, um zu verhindern, dass verweisende Cross-Origin-Fenster auf Ihre Dienst-Registerkarte zugreifen.

  • Antwort-Header „Cross-Origin-Resource-Policy“ (CORP): Snowflake setzt den CORP-Header auf same-origin, um zu verhindern, dass externe Websites Ressourcen laden, die vom Eingangsendpunkt bereitgestellt werden (z. B. in einem iFrame).

  • Antwort-Header „X-Content-Type-Options“: Snowflake-Proxy setzt diesen Header auf nosniff, um sicherzustellen, dass die Clients den von Ihrem Dienst in der Antwort angegebenen MIME-Typ nicht ändern.

  • Antwort-Header „Cross-Origin-Embedder-Policy“ (COEP): Snowflake-Proxy setzt den COEP-Antwort-Header auf credentialless, was bedeutet, dass Snowflake beim Laden eines Cross-Origin-Objekts, z. B. eines Images oder eines Skripts, die Anmeldeinformationen nicht sendet, wenn das Remoteobjekt das „Cross-Origin Resource Sharing“ (CORS)-Protokoll nicht unterstützt.

  • Antwort-Header „Content-Security-Policy-Report-Only“: Snowflake-Proxy ersetzt diesen Antwort-Header durch einen neuen Wert, der den Client anweist, die CSP-Berichte an Snowflake zu senden.

  • Antwort-Header „Content-Security-Policy“ (CSP): Standardmäßig fügt der Snowflake-Proxy die folgende Baseline-CSP hinzu, um sich gegen gängige Webangriffe zu schützen.

    default-src 'self' 'unsafe-inline' 'unsafe-eval' blob: data:; object-src 'none'; connect-src 'self'; frame-ancestors 'self';
    
    Copy

    Es gibt zwei Überlegungen zur Inhaltssicherheitsrichtlinie:

    • Zusätzlich zur Baseline-Sicherheitsrichtlinie für Inhalte, die der Proxy hinzufügt, kann der Dienst selbst explizit eine CSP in der Antwort hinzufügen. Ein Dienst könnte sich dafür entscheiden, die Sicherheit durch Hinzufügen einer strengeren CSP zu erhöhen. Ein Dienst könnte zum Beispiel folgendes CSP hinzufügen, um nur Skripte von self zuzulassen.

      script-src 'self'
      
      Copy

      In der Antwort, die an den Client gesendet wird, sind zwei CSP-Header enthalten. Nach Erhalt der Antwort wenden die Client-Browser dann die strengste Inhaltssicherheitsrichtlinie an, die die in den einzelnen Richtlinien angegebenen zusätzlichen Einschränkungen enthält.

    • Wenn Sie eine Integration für den externen Zugriff (EAI) konfigurieren, um Ihrem Dienst den Zugriff auf eine externe Website (Konfigurieren des Netzwerkausgangs) zu ermöglichen, erstellt der Snowflake-Proxy eine CSP, die Ihrer Webseite den Zugriff auf diese Site ermöglicht. Angenommen, eine mit einer EAI verknüpfte Netzwerkregel erlaubt Ihrem Dienst den Ausgangsdatenzugriff auf example.com. Dann fügt der Snowflake-Proxy diesen CSP-Antwort-Header hinzu:

      default-src 'self' 'unsafe-inline' 'unsafe-eval' http://example.com https://example.com blob: data:; object-src 'none'; connect-src 'self' http://example.com https://example.com wss://example.com; frame-ancestors 'self';
      
      Copy

      Die Browser halten sich an die in der Antwort enthaltene Inhaltszugriffsrichtlinie. In diesem Beispiel erlauben die Browser der App den Zugriff auf example.com, aber nicht auf andere Websites.

Überlegungen zum Zugriff und CORS

Standardmäßig verhindern Browser, dass Webanwendungen, die auf einem Server gehostet werden, Anfragen an einen anderen Server mit einem anderen Hostnamen senden. Wenn Sie beispielsweise eine Webanwendung außerhalb von Snowpark Container Services hosten, die mit einem in Snowpark Container Services bereitgestellten Backend-Dienst interagieren muss, gilt diese Einschränkung.

CORS (Cross-Origin Resource Sharing) ermöglicht es einem Snowpark Container Services-Dienst, den Browsern mitzuteilen, dass er Anfragen von Webanwendungen zulässt, die außerhalb seiner Umgebung gehostet werden. Sie können jeden öffentlichen Endpunkt konfigurieren, um festzulegen, wie er sowohl auf CORS Preflight-Anfragen als auch auf Standard-Anfragen reagiert.

Snowflake-Proxy setzt die folgenden Antwort-Header immer außer Kraft:

  • Access-Control-Allow-Origin

  • Access-Control-Allow-Methods

  • Access-Control-Allow-Headers

  • Access-Control-Expose-Headers

  • Access-Control-Max-Age

  • Access-Control-Allow-Credentials

Der Snowflake-Proxy nimmt keinen dieser CORS-Header in die Antwort auf, wenn einer der folgenden Punkte zutrifft:

  • CORS ist nicht für den Dienstendpunkt konfiguriert. Das heißt, es gibt kein corsSettings in der Dienstspezifikation

  • CORS ist für den Dienstendpunkt konfiguriert, aber der Origin-Header in der Anfrage stimmt nicht mit dem angegebenen Feld Access-Control-Allow-Origin in der Dienstspezifikation überein

In der Dienstspezifikation können Sie CORS-Einstellungen für jeden öffentlichen Endpunkt konfigurieren. Wenn der origin-Header in der Anfrage mit dem Feld Access-Control-Allow-Origin übereinstimmt, das in der Spezifikation für den Endpunkt angegeben ist, fügt der Proxy in die Antwort die in der Spezifikation definierten CORS-Header mit den folgenden Anpassungen ein:

  • Access-Control-Allow-Origin: Gibt den Origin-Header der Anfrage zurück.

  • Access-Control-Expose-Headers: Fügt die Liste der erlaubten Header, die Sie konfiguriert haben, mit diesen immer sichtbaren Headern zusammen: X-Frame-Options, Cross-Origin-Opener-Policy, Cross-Origin-Resource-Policy, X-Content-Type-Options, Cross-Origin-Embedder-Policy, Content-Security-Policy-Report-Only, Content-Security-Policy.

  • Access-Control-Max-Age: Ist auf zwei Stunden eingestellt.

  • Access-Control-Allow-Credentials: Ist auf „true“ gesetzt.

Überlegungen zum Zugriff und SSO

Wenn Sie vom Internet aus auf den öffentlichen Endpunkt zugreifen, kann es sein, dass die Authentifizierung mit Benutzername und Kennwort funktioniert, aber SSO zu einer leeren Seite oder dem Fehler führt: „OAuth Clientintegration mit der angegebenen Client-ID wurde nicht gefunden.“

Dies passiert, wenn Sie die alte Methode der föderierten Authentifizierung (SSO) mit Snowflake anstelle der neueren Version der Sicherheitsintegration verwenden, wie unter Konfigurieren von Snowflake für die Verwendung der Verbundauthentifizierung beschrieben. Gehen Sie wie folgt vor, um dies zu überprüfen:

  1. Führen Sie die folgende Abfrage aus:

    SHOW PARAMETERS LIKE 'SAML_IDENTITY_PROVIDER' IN ACCOUNT;
    
    Copy

    Wenn Sie diesen Parameter gesetzt haben, haben Sie zu irgendeinem Zeitpunkt die alte föderierte Authentifizierung verwendet.

  2. Wenn der obige Parameter gesetzt wurde, führen Sie die folgende Abfrage aus, um festzustellen, ob Sie über eine SAML-Sicherheitsintegration verfügen:

    SHOW INTEGRATIONS
      ->> SELECT * FROM $1 WHERE "type" = 'SAML2';
    
    Copy

    Wenn Sie keine Integrationen des Typs SAML2 haben, dann verwenden Sie die alte Methode der föderierten Authentifizierung.

In diesem Fall besteht die Lösung darin, von der alten Methode der föderierten Authentifizierung auf die neue, integrative Methode der föderierten Authentifizierung umzusteigen. Weitere Informationen dazu finden Sie unter Migration zu einer SAML2-Sicherheitsintegration.

Konfigurieren des Netzwerkausgangs

Der Code Ihrer Anwendung erfordert möglicherweise einen Zugang zum Internet. Standardmäßig haben Anwendungscontainer keine Berechtigung für den Zugriff auf das Internet. Sie müssen daher den Internetzugang über Integrationen für den externen Zugriff (External Access Integrations, EAIs) aktivieren.

In der Regel werden EAIs von einem Kontoadministrator erstellt, um den von Diensten (einschließlich Jobdiensten) erlaubten externen Zugriff zu verwalten. Kontoadministratoren können dann die Berechtigung zur EAI-Nutzung bestimmten Rollen zuweisen, die Entwickler zum Ausführen von Diensten verwenden.

Im folgenden Beispiel werden die Schritte zum Erstellen einer EAI beschrieben, die ausgehenden Datenverkehr zu bestimmten Zielen zulässt, die mithilfe von Netzwerkregeln spezifiziert werden. Sie können sich dann auf diese EAI beziehen, wenn Sie einen Dienst erstellen, um Anforderungen an bestimmte Internetziele zuzulassen.

Beispiel

Angenommen, Sie möchten, dass Ihr Anwendungscode Anforderungen an die folgenden Ziele sendet:

  • HTTPS-Anforderung an translation.googleapis.com

  • HTTP- und HTTPS-Anforderung an google.com

Führen Sie die folgenden Schritte aus, damit Ihr Dienst auf diese Domänen im Internet zugreifen kann:

  1. Erstellen Sie eine Integration für den externen Zugriff (EAI). Dafür sind die entsprechenden Berechtigungen erforderlich. Sie können zum Beispiel die Rolle ACCOUNTADMIN verwenden, um eine EAI zu erstellen. Dies ist ein zweistufiger Prozess:

    1. Verwenden Sie den Befehl CREATE NETWORK RULE, um eine oder mehrere Netzwerkregeln für den ausgehenden Datenverkehr zu erstellen, wobei in den Regeln die externen Ziele aufgeführt sind, für die Sie den Zugriff erlauben möchten. Sie können benötigen für dieses Beispiel normalerweise nur eine Netzwerkregel, aber zur Veranschaulichung erstellen wir hier zwei Netzwerkregeln:

      1. Erstellen Sie eine Netzwerkregel namens translate_network_rule.

        CREATE OR REPLACE NETWORK RULE translate_network_rule
          MODE = EGRESS
          TYPE = HOST_PORT
          VALUE_LIST = ('translation.googleapis.com');
        
        Copy

        Diese Regel erlaubt TCP-Verbindungen zum Ziel translation.googleapis.com. Die Domäne in der Eigenschaft VALUE_LIST gibt keine optionale Portnummer an, sodass der Standardport 443 (HTTPS) angenommen wird. Dadurch kann Ihre Anwendung eine Verbindung zu jeder URL herstellen, die mit https://translation.googleapis.com/ beginnt.

      2. Erstellen Sie eine Netzwerkregel namens google_network_rule.

        CREATE OR REPLACE NETWORK RULE google_network_rule
          MODE = EGRESS
          TYPE = HOST_PORT
          VALUE_LIST = ('google.com:80', 'google.com:443');
        
        Copy

        Dadurch kann Ihre Anwendung eine Verbindung zu jeder URL herstellen, die mit http://google.com/ oder https://google.com/ beginnt.

      Bemerkung

      Für den Parameter VALUE_LIST müssen Sie einen vollständigen Hostnamen angeben. Platzhalter (z. B. *.googleapis.com) werden nicht unterstützt.

      Snowpark Container Services unterstützt nur die Netzwerkregeln, die die Ports 22, 80, 443 und 1024+ erlauben. Wenn eine referenzierte Netzwerkregel den Zugriff auf andere Ports zulässt, schlägt das Erstellen des Dienstes fehl. Wenden Sie sich an Ihren Kundenbetreuer, wenn Sie zusätzliche Ports benötigen.

      Bemerkung

      Damit Ihr Dienst HTTP- oder HTTPS-Anforderungen an ein beliebiges Ziel im Internet senden kann, geben Sie in der VALUE_LIST-Eigenschaft „0.0.0.0“ als Domäne an. Die folgende Netzwerkregel erlaubt es, sowohl „HTTP“- als auch „HTTPS“-Anforderungen an beliebige Ziele im Internet zu senden. Mit „0.0.0.0“ werden nur die Ports 80 oder 443 unterstützt.

      CREATE NETWORK RULE allow_all_rule
        TYPE = 'HOST_PORT'
        MODE= 'EGRESS'
        VALUE_LIST = ('0.0.0.0:443','0.0.0.0:80');
      
      Copy
    2. Erstellen Sie eine Integration für den externe Zugriff (EAI), die festlegt, dass die beiden obigen Netzwerkregeln für ausgehenden Datenverkehr zulässig sind:

      CREATE EXTERNAL ACCESS INTEGRATION google_apis_access_integration
        ALLOWED_NETWORK_RULES = (translate_network_rule, google_network_rule)
        ENABLED = true;
      
      Copy

      Nun kann der Kontoadministrator Entwicklern die Nutzung (USAGE) der Integration gestatten, damit diese einen Dienst ausführen können, der auf bestimmte Ziele im Internet zugreifen kann.

      GRANT USAGE ON INTEGRATION google_apis_access_integration TO ROLE test_role;
      
      Copy
  2. Erstellen Sie den Dienst durch Angabe der EAI wie in den folgenden Beispielen gezeigt. Die Eigentümerrolle, die den Dienst erstellt, benötigt die Berechtigung USAGE für die EAI und die Berechtigung READ für die referenzierten Geheimnisse. Beachten Sie, dass Sie mit der Rolle ACCOUNTADMIN keine Dienste erstellen können.

    • Erstellen Sie einen Dienst:

      USE ROLE test_role;
      
      CREATE SERVICE eai_service
        IN COMPUTE POOL MYPOOL
        EXTERNAL_ACCESS_INTEGRATIONS = (GOOGLE_APIS_ACCESS_INTEGRATION)
        FROM SPECIFICATION
        $$
        spec:
          containers:
            - name: main
              image: /db/data_schema/tutorial_repository/my_echo_service_image:tutorial
              env:
                TEST_FILE_STAGE: source_stage/test_file
              args:
                - read_secret.py
          endpoints:
            - name: read
              port: 8080
        $$;
      
      Copy

      Diese CREATE SERVICE-Beispielanforderung verwendet eine Inline-Dienstspezifikation und gibt die optionale Eigenschaft EXTERNAL_ACCESS_INTEGRATIONS an, um die EAI einzuschließen. Die EAI gibt die Netzwerkregeln an, die den ausgehenden Datenverkehr vom Dienst zu den spezifischen Zielen erlauben.

    • Führen Sie einen Jobdienst aus:

      EXECUTE JOB SERVICE
        IN COMPUTE POOL tt_cp
        NAME = example_job_service
        EXTERNAL_ACCESS_INTEGRATIONS = (GOOGLE_APIS_ACCESS_INTEGRATION)
        FROM SPECIFICATION $$
        spec:
          container:
          - name: curl
            image: /tutorial_db/data_schema/tutorial_repo/alpine-curl:latest
            command:
            - "curl"
            - "http://google.com/"
        $$;
      
      Copy

      Dieser EXECUTE JOB SERVICE-Beispielbefehl gibt die Inline-Spezifikation und die optionale Eigenschaft EXTERNAL_ACCESS_INTEGRATIONS an, um die EAI einzuschließen. Dadurch wird der ausgehende Datenverkehr vom Job zu den in den Netzwerkregeln angegebenen Zielen zugelassen, die die EAI zulässt.

Netzwerkausgang über private Konnektivität

Anstatt den Netzwerkausgag über das öffentliche Internet zu routen, können Sie sich dafür entscheiden, den Ausgangverkehr Ihres Dienstes über einen privaten Konnektivitätsendpunkt zu leiten.

Zunächst müssen Sie den privaten Konnektivitätsendpunkt in Ihrem Snowflake-Konto erstellen. Konfigurieren Sie dann eine Netzwerkregel, um den ausgehenden Datenverkehr über die private Konnektivität zuzulassen. Der Prozess zur Einrichtung einer External Access Integration (EAI) bleibt derselbe wie im vorangegangenen Abschnitt beschrieben.

Bemerkung

Private Kommunikation erfordert, dass sowohl Snowflake als auch das Cloud-Konto des Kunden denselben Cloudanbieter und dieselbe Region verwenden.

Wenn Sie zum Beispiel den ausgehenden Internetzugang Ihres Dienstes zu einem Amazon S3-Bucket über private Konnektivität aktivieren möchten, gehen Sie wie folgt vor:

  1. Aktivieren Sie die private Link-Konnektivität für den selbstverwalteten Endpunktdienst (Amazon S3). Eine Schritt-für-Schritt-Anleitung finden Sie unter AWS Private Link for Amazon S3.

  2. Rufen Sie die Systemfunktion SYSTEM$PROVISION_PRIVATELINK_ENDPOINT auf, um einen privaten Konnektivitätsendpunkt in Ihrem Snowflake-VNet bereitzustellen. Dadurch kann Snowflake über private Konnektivität eine Verbindung zum externen Dienst (in diesem Beispiel Amazon S3) herstellen.

    USE ROLE ACCOUNTADMIN;
    
    SELECT SYSTEM$PROVISION_PRIVATELINK_ENDPOINT(
      'com.amazonaws.us-west-2.s3',
      '*.s3.us-west-2.amazonaws.com'
    );
    
    Copy
  3. Genehmigen Sie den Endpunkt im Konto des Cloudanbieters. In diesem Beispiel für Amazon AWS, siehe Verbindungsanfragen annehmen oder ablehnen in der AWS-Dokumentation. Um den Endpunkt in Azure zu genehmigen, lesen Sie auch die Azure-Dokumentation.

  4. Verwenden Sie den Befehl CREATE NETWORK RULE, um eine Netzwerkegel für den ausgehenden Datenverkehr zu erstellen, in der Sie die externen Ziele angeben, für die Sie den Zugriff erlauben möchten.

    CREATE OR REPLACE NETWORK RULE private_link_network_rule
      MODE = EGRESS
      TYPE = PRIVATE_HOST_PORT
      VALUE_LIST = ('<bucket-name>.s3.us-west-2.amazonaws.com');
    
    Copy

    Der Parameters TYPE ist auf PRIVATE_HOST_PORT eingestellt. Er zeigt an, dass die Netzwerkregel den ausgehenden Datenverkehr über die private Konnektivität zulässt.

  5. Die übrigen Schritte zur Erstellung eines EAI und dessen Verwendung zur Erstellung eines Dienstes sind die gleichen wie im vorangegangenen Abschnitt (siehe Konfigurieren des Netzwerkausgangs) erklärt.

Weitere Informationen zur Arbeit mit privaten Konnektivitätsendpunkten finden Sie unter:

Konfigurieren der Netzwerkkommunikation zwischen Containern

Es gibt zwei Konzepte:

  • Kommunikation zwischen Containern einer Dienstinstanz: Wenn eine Dienstinstanz mehrere Container ausführt, können diese Container über „localhost“ miteinander kommunizieren (es ist nicht erforderlich, in der Dienstspezifikation Endpunkte zu definieren).

  • Kommunikation zwischen Containern verschiedener Dienste oder mehrerer Dienstinstanzen: Container, die zu verschiedenen Diensten (oder verschiedenen Instanzen desselben Dienstes) gehören, können über Endpunkte kommunizieren, die in Spezifikationsdateien definiert sind. Weitere Informationen dazu finden Sie unter Dienst-zu-Dienst-Kommunikation.

Übergabe von Anmeldeinformationen an einen Container mit Snowflake-Geheimnissen

Es gibt viele Gründe, warum Sie von Snowflake verwaltete Anmeldeinformationen an Ihren Container weitergeben möchten. Ihr Dienst könnte zum Beispiel mit externen Endpunkten (außerhalb von Snowflake) kommunizieren. In diesem Fall müssen Sie in Ihrem Container Anmeldeinformationen bereitstellen, die Ihr Anwendungscode verwenden kann.

Um Anmeldeinformationen bereitzustellen, speichern Sie diese zunächst in Snowflake-Geheimnis-Objekten. In der Service-Spezifikation geben Sie dann unter containers.secrets an, welche Geheimnisobjekte verwendet werden sollen und wo sie im Container platziert werden sollen. Sie können diese Anmeldeinformationen entweder an Umgebungsvariablen in den Containern übergeben oder sie in lokalen Dateien in den Containern verfügbar machen.

Snowflake-Geheimnisse angeben

Geben Sie ein Snowflake-Geheimnis durch Name oder Referenz an (die Referenz ist nur im Native Application-Szenario anwendbar):

  • Snowflake-Geheimnis per Name übergeben: Sie können einen Geheimnamen als snowflakeSecret-Feldwert übergeben.

    ...
    secrets:
    - snowflakeSecret:
        objectName: '<secret-name>'
      <other info about where in the container to copy the secret>
      ...
    
    Copy

    Beachten Sie, dass Sie optional <secret-name> direkt als Wert snowflakeSecret angeben können.

  • Snowflake-Geheimnis per Referenz weitergeben: Wenn Sie Snowpark Container Services verwenden, um eine Native App (eine App mit Containern) zu erstellen, verwenden der App-Produzent und die Verbraucher unterschiedliche Snowflake-Konten. In bestimmten Kontexten muss eine installierte Snowflake Native App auf bestehende Geheimnisobjekte im Verbraucherkonto zugreifen, die außerhalb des APPLICATION-Objekts existieren. In diesem Fall können Entwickler die Syntax der Spezifikation „secrets by reference“ (Geheimnisse per Referenz) verwenden, um Anmeldeinformationen wie gezeigt zu behandeln:

    containers:
    - name: main
      image: <url>
      secrets:
      - snowflakeSecret:
          objectReference: '<reference-name>'
        <other info about where in the container to copy the secret>
    
    Copy

    Beachten Sie, dass die Spezifikation objectReference anstelle von objectName verwendet, um einen geheimen Referenznamen anzugeben.

Festlegen der Platzierung von Geheimnissen innerhalb des Containers

Sie können Snowflake anweisen, die Geheimnisse entweder als Umgebungsvariablen in den Containern zu platzieren oder sie in lokale Dateien der Container zu schreiben.

Übergeben Sie Geheimnisse als Variablen der Umgebung

Um Snowflake-Geheimnisse als Umgebungsvariablen an Container zu übergeben, fügen Sie envVarName in das containers.secrets-Feld ein.

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: <secret-name>
    secretKeyRef: username | password | secret_string |  'access_token'
    envVarName: '<env-variable-name>'
Copy

Der secretKeyRef-Wert hängt von der Art des Snowflake-Geheimnisses ab. Mögliche Werte sind die folgenden:

  • username oder password, wenn das Snowflake-Geheimnis vom Typ password ist.

  • secret_string, wenn das Snowflake-Geheimnis vom Typ generic_string ist.

Beachten Sie, dass Snowflake die als Umgebungsvariablen übergebenen Geheimnisse nicht aktualisiert, nachdem ein Dienst erstellt wurde.

Beispiel 1: Übergeben von Geheimnissen des Typs password als Umgebungsvariable

In diesem Beispiel erstellen Sie das folgende Snowflake-Geheimnisobjekt vom Typ password:

CREATE SECRET testdb.testschema.my_secret_object
  TYPE = password
  USERNAME = 'snowman'
  PASSWORD = '1234abc';
Copy

Um dieses Snowflake-Geheimnisobjekt den Umgebungsvariablen (z. B. LOGIN_USER und LOGIN_PASSWORD) in Ihrem Container zur Verfügung zu stellen, fügen Sie das folgende Feld containers.secrets in die Spezifikationsdatei ein:

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: testdb.testschema.my_secret_object
    secretKeyRef: username
    envVarName: LOGIN_USER
  - snowflakeSecret: testdb.testschema.my_secret_object
    secretKeyRef: password
    envVarName: LOGIN_PASSWORD
Copy

In diesem Beispiel ist der Wert snowflakeSecret ein vollständig qualifizierter Objektname, da Geheimnisse in einem anderen Schema als der zu erstellende Dienst gespeichert sein können.

Das Feld containers.secrets in diesem Beispiel ist eine Liste mit zwei snowflakeSecret-Objekten:

  • Mit dem ersten Objekt wird username im Snowflake-Geheimnisobjekt der Umgebungsvariablen LOGIN_USER in Ihrem Container zugeordnet.

  • Mit dem zweiten Objekt wird password im Snowflake-Geheimnisobjekt der Umgebungsvariablen LOGIN_PASSWORD in Ihrem Container zugeordnet.

Beispiel 2: Übergeben von Geheimnissen vom Typ generic_string als Umgebungsvariable

In diesem Beispiel erstellen Sie das folgende Snowflake-Geheimnisobjekt vom Typ generic_string:

CREATE SECRET testdb.testschema.my_secret
  TYPE=generic_string
  SECRET_STRING='
       some_magic: config
  ';
Copy

Um dieses Snowflake-Geheimnisobjekt den Umgebungsvariablen (z. B. GENERIC_SECRET) in Ihrem Container zur Verfügung zu stellen, fügen Sie das folgende Feld containers.secrets in die Spezifikationsdatei ein:

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: testdb.testschema.my_secret
    secretKeyRef: secret_string
    envVarName: GENERIC_SECRET
Copy

Geheimnisse in lokale Containerdateien schreiben

Um Snowflake-Geheimnisse für Ihren Anwendungscontainer in lokalen Containerdateien verfügbar zu machen, fügen Sie ein containers.secrets-Feld ein: Um Snowflake-Geheimnisse für Ihren Anwendungscontainer in lokalen Containerdateien verfügbar zu machen, fügen Sie directoryPath in die Datei containers.secrets ein:

containers:
- name: <name>
  image: <url>
  ...
  secrets:
  - snowflakeSecret: <snowflake-secret-name>
    directoryPath: '<local directory path in the container>'
Copy

Snowflake füllt die notwendigen Dateien für das Geheimnis in diesem angegebenen directoryPath auf; die Angabe von secretKeyRef ist nicht erforderlich. Je nach Geheimnistyp erstellt Snowflake die folgenden Dateien im Container unter dem von Ihnen angegebenen Verzeichnispfad:

  • username und password, wenn das Snowflake-Geheimnis vom Typ password ist.

  • secret_string, wenn das Snowflake-Geheimnis vom Typ generic_string ist.

  • access_token, wenn das Snowflake-Geheimnis vom Typ oauth2 ist.

Bemerkung

Wenn nach dem Erstellen eines Dienstes das Snowflake-Geheimnisobjekt aktualisiert wird, aktualisiert Snowflake die entsprechenden Geheimnisdateien in den aktiven Containern.

Beispiel 1: Übergeben von Geheimnissen des Typs password mithilfe von lokalen Containerdateien

In diesem Beispiel erstellen Sie das folgende Snowflake-Geheimnisobjekt vom Typ password:

CREATE SECRET testdb.testschema.my_secret_object
  TYPE = password
  USERNAME = 'snowman'
  PASSWORD = '1234abc';
Copy

Um diese Anmeldeinformationen in lokalen Containerdateien zur Verfügung zu stellen, fügen Sie das folgende containers.secrets-Feld in die Spezifikationsdatei ein:

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: testdb.testschema.my_secret_object
    directoryPath: '/usr/local/creds'
Copy

Wenn Sie Ihren Dienst starten, erstellt Snowflake zwei Dateien innerhalb des Containers: /usr/local/creds/username und /usr/local/creds/password. Ihr Anwendungscode kann dann diese Dateien lesen.

Beispiel 2: Übergabe von Geheimnissen vom Typ generic_string in lokalen Containerdateien

In diesem Beispiel erstellen Sie das folgende Snowflake-Geheimnisobjekt vom Typ generic_string:

CREATE SECRET testdb.testschema.my_secret
  TYPE=generic_string
  SECRET_STRING='
       some_magic: config
  ';
Copy

Um dieses geheime Snowflake-Objekt in lokalen Containerdateien bereitzustellen, fügen Sie das folgende containers.secrets-Feld in die Datei mit den Spezifikationen ein:

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: testdb.testschema.my_secret
    directoryPath: '/usr/local/creds'
Copy

Wenn Sie Ihren Dienst starten, erstellt Snowflake diese Datei in den Containern: /usr/local/creds/secret_string.

Beispiel 3: Übergeben von Geheimnissen des Typs oauth2 mithilfe von lokalen Containerdateien

In diesem Beispiel erstellen Sie das folgende Snowflake-Geheimnisobjekt vom Typ oauth2:

CREATE SECRET testdb.testschema.oauth_secret
  TYPE = OAUTH2
  OAUTH_REFRESH_TOKEN = '34n;vods4nQsdg09wee4qnfvadH'
  OAUTH_REFRESH_TOKEN_EXPIRY_TIME = '2023-12-31 20:00:00'
  API_AUTHENTICATION = my_integration;
Copy

Um diese Anmeldeinformationen in lokalen Containerdateien zur Verfügung zu stellen, fügen Sie das folgende containers.secrets-Feld in die Spezifikationsdatei ein:

containers:
- name: main
  image: <url>
  secrets:
  - snowflakeSecret: testdb.testschema.oauth_secret
    directoryPath: '/usr/local/creds'
Copy

Snowflake ruft das Zugriffstoken aus dem OAuth-Geheimnisobjekt ab und erstellt /usr/local/creds/access_token in den Containern.

Wenn ein Dienst Geheimnisse des „oauth2“-Typs verwendet, wird erwartet, dass der Dienst dieses Geheimnis für den Zugriff auf ein Internetziel verwendet. Ein OAuth-Geheimnis muss von einer Integration für den externen Zugriff (EAI) erlaubt werden, da sonst CREATE SERVICE und EXECUTE JOB SERVICE fehlschlagen. Diese zusätzliche EAI-Anforderung gilt nur für Geheimnisse des „oauth2“-Typs und nicht für andere Typen von Geheimnissen.

Zusammenfassend sind folgende allgemeine Schritte zum Erstellen eines solchen Dienstes erforderlich:

  1. Erstellen Sie ein Geheimnis vom Typ „oauth2“ (siehe oben).

  2. Erstellen Sie eine EAI, um die Verwendung des Geheimnisses durch einen Dienst zu erlauben. Beispiel:

    CREATE OR REPLACE EXTERNAL ACCESS INTEGRATION example_eai
      ALLOWED_NETWORK_RULES = (<name>)
      ALLOWED_AUTHENTICATION_SECRETS = (testdb.testschema.oauth_secret)
      ENABLED = true;
    
    Copy
  3. Erstellen Sie einen Dienst, der ein containers.secrets-Feld in der Spezifikation enthält. Darin wird auch die optionale Eigenschaft EXTERNAL_ACCESS_INTEGRATIONS mit einer EAI angegeben, um die Verwendung des OAuth2-Geheimnisses zuzulassen.

    Beispiel für einen CREATE SERVICE-Befehl (mit Inline-Spezifikation):

    CREATE SERVICE eai_service
      IN COMPUTE POOL MYPOOL
      EXTERNAL_ACCESS_INTEGRATIONS = (example_eai)
      FROM SPECIFICATION
      $$
      spec:
        containers:
          - name: main
            image: <url>
            secrets:
            - snowflakeSecret: testdb.testschema.oauth_secret
              directoryPath: '/usr/local/creds'
        endpoints:
          - name: api
            port: 8080
      $$;
    
    Copy

Weitere Informationen zu ausgehendem Datenverkehr finden Sie unter Konfigurieren des Netzwerkausgangs.

Richtlinien und Einschränkungen

  • Allgemeine Beschränkungen: Sollten Sie Probleme mit diesen Beschränkungen haben, wenden Sie sich bitte an Ihren Kontobeauftragten.

    • Sie können bis zu 200 Dienste in Ihrem Snowflake-Konto erstellen.

    • Jeder Dienst kann bis zu 100 Endpunkte haben (siehe spec.endpoints).

    • Jeder Dienst kann bis zu 20 Container haben (siehe spec.containers).

    • Jeder Dienst kann bis zu 50 Geheimnisse haben (siehe containers.secrets).

    • Jeder Dienst kann bis zu 20 Volumes haben (siehe spec.volumes).

    • Die folgenden Beschränkungen gelten, wenn Sie den Internetzugang (siehe Konfigurieren des Netzwerkausgangs) unter Verwendung von Integrationen für den externen Zugang (EAIs) aktivieren.

    • Wenn Sie vom Internet aus auf den öffentlichen Endpunkt zugreifen, kann es sein, dass die Authentifizierung mit Benutzername und Kennwort funktioniert, aber SSO zu einer leeren Seite oder dem Fehler führt: „OAuth Clientintegration mit der angegebenen Client-ID wurde nicht gefunden.“ Informationen zum Umgang mit diesem Problem finden Sie unter Überlegungen zum Zugriff und SSO.

  • Anforderungen an die Image-Plattform: Snowpark Container Services erfordert derzeit linux/amd64 Plattform-Images.

  • Dienstcontainer haben keine Berechtigungen: Dienstcontainer werden derzeit ohne weitreichende Berechtigungen ausgeführt, d. h. sie können die Konfiguration der Hardware auf dem Host nicht ändern und können BS-Konfigurationen nur begrenzt ändern. Dienstcontainer können nur Betriebssystemkonfigurationen ausführen, die auch ein normaler Benutzer (d. h. ein Benutzer, der keine Root-Berechtigung benötigt) ausführen kann.

  • Umbenennen von Datenbank und Schema:

    • Benennen Sie keine Datenbanken und Schemas um, für die Sie bereits einen Dienst erstellt haben. Das Umbenennen bedeutet im Grunde, dass ein Dienst in eine andere Datenbank und ein anderes Schema verschoben wird, was nicht unterstützt wird. Beispiel:

      • Datenbank- und Schemainformationen, die Snowflake den aktiven Dienstcontainern zur Verfügung stellt, beziehen sich weiterhin auf die alten Namen.

      • Neue Protokolleinträge, die von Diensten in die Ereignistabelle aufgenommen werden, beziehen sich weiterhin auf die alten Datenbank- und Schemanamen.

      • Die Dienstfunktion wird weiterhin auf den Dienst in der alten Datenbank und dem alten Schema verweisen, und wenn Sie die Dienstfunktion aufrufen, wird sie fehlschlagen.

    • Eine Dienstspezifikation kann auf Objekte wie Snowflake-Stagingbereiche und Image-Repositorys verweisen. Wenn Sie den Namen von Datenbank oder Schema umbenennen, in denen sich diese Objekte befinden, müssen Sie die Datenbank- und Schemanamen der referenzierten Objekte in der Dienstspezifikation manuell aktualisieren.

  • Ownership transferof the parent schema or database:

    You can transfer the ownership of the parent schema or database to a different role. But the ownership of services inside the schema or database isn’t transferred to the new role because services run as service’s owner roles and that doesn’t change. As a result, the services could lose permissions on objects inside the schema, such as image repositories and Snowflake stages in the same schema.

    If you must transfer the ownership of the parent schema or database, consider re-creating the services.

  • Löschen und Wiederherstellen von Datenbank und Schema:

    • Wenn Sie die übergeordnete Datenbank oder das übergeordnete Schema löschen, werden die Dienste asynchron gelöscht. Das bedeutet, dass ein Dienst noch einige Zeit weiter ausgeführt wird, bevor er durch interne Prozesse entfernt wird.

    • Wenn Sie versuchen, eine zuvor gelöschte Datenbank oder ein Schema wiederherzustellen, gibt es keine Garantie, dass die Dienste wiederhergestellt werden.

  • Ownership transfer of services: Ownership transfer or future ownership transfer for services, including job services, isn’t supported.

  • Übertragung der Eigentümerschaft von Dienstfunktionen:

    Die Eigentümerschaft an einer Dienstfunktion kann verschiedene Rollen übertragen. Wenn die neue Eigentümerrolle nicht die Berechtigung USAGE für den Dienst hat, schlagen Funktionsaufrufe fehl. Sie müssen der neuen Eigentümerrolle der Funktion die Berechtigung USAGE erteilen.

  • Replikation: Bei der Replikation in Snowflake ist Folgendes zu beachten:

    • Snowpark Container Services-Objekte wie Dienste, Computepools und Repositorys können nicht repliziert werden.

    • Wenn Sie ein Repository innerhalb einer Datenbank erstellen, kann nicht die gesamte Datenbank repliziert werden. In Fällen, in denen die Datenbank andere Ressourcen enthält, wie z. B. Dienste oder Computepools, wird der Replikationsprozess der Datenbank erfolgreich sein, aber diese einzelnen Objekte innerhalb der Datenbank werden nicht repliziert.

  • Job services timeout: Snowpark Container Services job services runs synchronously by default. If a statement times out, the job service is canceled. The default statement timeout is two days. Customers can change the timeout by setting the parameter STATEMENT_TIMEOUT_IN_SECONDS using ALTER SESSION.

    ALTER SESSION SET statement_timeout_in_seconds=<time>
    
    Copy

    Stellen Sie ihn ein, bevor Sie den Befehl EXECUTE JOB SERVICE ausführen. Sie können Jobdienste asynchron ausführen, indem Sie ASYNC=true angeben, um zu verhindern, dass Jobdienste durch ein Timeout der Anweisung unterbrochen werden.

  • File staging commands support in Google Cloud: To use the PUT, GET, LIST, or REMOVE command with Snowflake client libraries on Google Cloud, update your clients to at least the following versions.

    Client

    Version

    Go-Snowflake-Treiber

    1.14.1

    Snowflake Connector für Python

    3.16.0

    .NET-Treiber

    4.6.0

    Node.js-Treiber

    2.1.3

    JDBC-Treiber

    3.25.1

    ODBC-Treiber

    3.10.0