

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 附录
<a name="appendix"></a>

## 多租户比较
<a name="multi-tenancy-comparison"></a>

*表 2 — 多租户比较*


|  多域  |  多账号  |  单个域内基于属性的访问控制 (ABAC)  | 
| --- | --- | --- | 
|  资源隔离是使用标签实现的。 SageMaker AI Studio 会自动使用域ARN和用户配置文件/空间标记所有资源。ARN  |  每个租户都有自己的账户，因此资源绝对隔离。  |  资源隔离是使用标签实现的。用户必须管理为创建的资源的标ABAC记。  | 
|  列表APIs不能受标签限制。用户界面筛选资源是在共享空间上完成的，但是，通过 AWS CLI 或 Boto3 发出的列表API调用SDK将列出整个区域的资源。  |  列表APIs隔离也是可能的，因为租户位于他们的专用账户中。  |  列表APIs不能受标签限制。列出通过 AWS CLI 或 Boto3 API 拨打的电话SDK将列出整个地区的资源。  | 
|  SageMaker 使用 Domain ARN 作为成本分配标签，可以轻松监控每个租户的 AI Studio 计算和存储成本。  |  SageMaker 使用专用帐户，可以轻松监控每个租户的 AI Studio 计算和存储成本。  |  SageMaker AI Studio 需要使用自定义标签计算每个租户的计算成本。  SageMaker 无法按域监控 AI Studio 的存储成本，因为所有租户共享相同的存储EFS容量。  | 
|  服务配额是在账户级别设置的，因此单个租户仍然可以用完所有资源。  |  可以在账户级别为每个租户设置服务配额。  |  服务配额是在账户级别设置的，因此单个租户仍然可以用完所有资源。  | 
|  可以通过基础设施即代码 (IaC) 或 Service Catalog 来扩展到多个租户。  |  扩展到多个租户涉及Organizations和出售多个帐户。  |  Scaling 需要为每个新租户指定租户特定的角色，并且需要用租户名称手动标记用户配置文件。  | 
|  租户内部的用户可以通过共享空间进行协作。  |  租户内部的用户可以通过共享空间进行协作。  |  所有租户都可以访问同一个共享空间进行协作。  | 

## SageMaker AI Studio 域名备份和恢复
<a name="sagemaker-studio-domain-backup-and-recovery"></a>

如果意外EFS删除，或者由于网络或身份验证更改而需要重新创建域，请按照以下说明进行操作。

### 选项 1：EFS使用现有备份 EC2
<a name="option-1"></a>

#### SageMaker 工作室域名备份
<a name="sagemaker-studio-domain-backup"></a>

1. 列出 SageMaker Studio 中的用户个人资料和空间 ([CLI](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/list-user-profiles.html), [SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.list_user_profiles))。

1. 将用户个人资料/空间映射到 on。UIDs EFS

   1. 对于 users/spaces, describe the user profile/space ([CLI](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/describe-user-profile.html), [SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.describe_user_profile)) 列表中的每个用户。

   1. 映射用户配置文件/空间到 `HomeEfsFileSystemUid`。

   1. 为具有不同执行角色的用户映射配置文件到 `UserSettings['ExecutionRole']`。

   1. 识别默认空间执行角色。

1. 创建新域并指定默认空间执行角色。

1. 创建用户配置文件和空间。
   + 对于用户列表中的每个用户，使用执行角色映射创建用户配置文件 ([CLI](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/create-user-profile.html), [SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_user_profile))。

1. 为新的EFS和创建映射UIDs。

   1. 对于用户列表中的每个用户，请描述用户个人资料 ([CLI](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/describe-user-profile.html), [SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.describe_user_profile))。

   1. 映射用户配置文件到 `HomeEfsFileSystemUid`。

1. 可以先删除所有应用程序、用户配置文件和空间，再删除域。

#### EFS 备份
<a name="efs-backup"></a>

要进行备份EFS，请按照以下说明进行操作：

1. 启动EC2实例，并将旧 SageMaker Studio 域的入站/出站安全组附加到新EC2实例（允许端口 2049 TCP 上的NFS流量）。请参阅 “[外部资源” 中的 Connect SageMaker Studio 笔记本电脑](https://docs.aws.amazon.com/sagemaker/latest/dg/studio-notebooks-and-internet-access.html#:~:text=NFS%20traffic%20over%20TCP%20on%20port%202049%20between%20the%20domain%20and%20the%20Amazon%20EFS%20volume.)。VPC

1. 将 SageMaker Studio EFS 卷挂载到新EC2实例。请参阅[挂载EFS文件系统](https://docs.aws.amazon.com/efs/latest/ug/mounting-fs.html)。

1. 将文件复制到EBS本地存储：`>sudo cp -rp /efs /studio-backup:`

   1. 将新的域安全组附加到实EC2例。

   1. 将新EFS卷挂载到EC2实例。

   1. 将文件复制到新EFS卷。

   1. 对于用户集合中的每位用户：

      1. 创建目录：`mkdir new_uid`。

      1. 将文件从旧UID目录复制到新UID目录。

      1. 更改所有文件的所有权：所有文件的 `chown <new_UID>`。

### 选项 2：EFS使用 S3 和生命周期配置从现有设备进行备份
<a name="option-2"></a>

1. 请参阅使用亚马逊 [Linux 将您的作品迁移到亚马逊 SageMaker 笔记本实例 2](https://aws.amazon.com/blogs/machine-learning/migrate-your-work-to-amazon-sagemaker-notebook-instance-with-amazon-linux-2/)。

1. 创建 S3 存储桶进行备份（例如 `>studio-backup`）。

1. 列出所有具有执行角色的用户配置文件。

1. 在当前 SageMaker Studio 域中，在域级别设置默认LCC脚本。
   + 在中LCC，将所有内容复制`/home/sagemaker-user`到 S3 中的用户配置文件前缀中（例如，`s3://studio-backup/studio-user1`）。

1. 重新启动所有默认 Jupyter Server 应用程序（LCC以便运行）。

1. 删除所有应用程序、用户配置文件和域。

1. 创建一个新的 SageMaker Studio 域名。

1. 从用户配置文件和执行角色列表新建用户配置文件。

1. LCC在域级别设置：
   + 在中LCC，将 S3 中用户配置文件前缀中的所有内容复制到 `/home/sagemaker-user`

1. 使用[LCC配置](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateApp.html#:~:text=%22ResourceSpec%22%3A%20%7B%20%0A%20%20%20%20%20%20%22InstanceType%22%3A%20%22string%22%2C%0A%20%20%20%20%20%20%22LifecycleConfigArn%22%3A%20%22string%22%2C) ([CLI](https://docs.aws.amazon.com/cli/latest/reference/sagemaker/create-app.html),) 为所有用户创建默认 Jupyter Server 应用程序。[SDK](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_app)

## SageMaker 使用SAML断言访问工作室
<a name="sagemaker-studio-access-using-saml"></a>

解决方案设置步骤：

1. 在外部 IdP 中创建SAML应用程序。

1. 在中将外部 IdP 设置为身份提供者。IAM

1. 创建一个 I `SAMLValidator` dP 可以访问的 Lambda 函数（通过函数URL或网关）。API

1. 创建一个 `GeneratePresignedUrl` Lambda 函数和一个API网关来访问该函数。

1. 创建一个用户可以代入的IAM角色来调用API网关。此角色应按以下格式作为属性在SAML断言中传递：
   + 属性名称： https://aws.amazon.com/SAML/属性/角色
   + 属性值：`<IdentityProviderARN>`，`<RoleARN>`

1. 将SAML断言使用者服务 (ACS) 端点更新为`SAMLValidator`调用URL。

SAML验证器示例代码：

```
import requests
import os
import boto3
from urllib.parse import urlparse, parse_qs
import base64
import requests
from aws_requests_auth.aws_auth import AWSRequestsAuth
import json


# Config for calling AssumeRoleWithSAML
idp_arn = "arn:aws:iam::0123456789:saml-provider/MyIdentityProvider"
api_gw_role_arn = 'arn:aws:iam:: 0123456789:role/APIGWAccessRole'
studio_api_url = "abcdef.execute-api.us-east-1.amazonaws.com"
studio_api_gw_path = "https://" + studio_api_url + "/Prod "

# Every customer will need to get SAML Response from the POST call
def get_saml_response(event):
    saml_response_uri = base64.b64decode(event['body']).decode('ascii')
    request_body = parse_qs(saml_response_uri)
    print(f"b64 saml response: {request_body['SAMLResponse'][0]}")
    return request_body['SAMLResponse'][0]


def lambda_handler(event, context):
    sts = boto3.client('sts')
    
    # get temporary credentials 
    response = sts.assume_role_with_saml(
                    RoleArn=api_gw_role_arn,
                    PrincipalArn=durga_idp_arn,
                    SAMLAssertion=get_saml_response(event)
                )    
    auth = AWSRequestsAuth(aws_access_key=response['Credentials']['AccessKeyId'],
                      aws_secret_access_key=response['Credentials']['SecretAccessKey'],
                      aws_host=studio_api_url,
                      aws_region='us-west-2',
                      aws_service='execute-api',
                      aws_token=response['Credentials']['SessionToken'])
                      
    presigned_response = requests.post(
        studio_api_gw_path,
        data=saml_response_data,
        auth=auth)
        
    return presigned_response
```