Amazon Web Services ブログ

EKS Windows コンテナで Amazon FSx for Windows ファイルサーバーを使用する

最近、Amazon FSx for Windows ファイルサーバーを Amazon Elastic Container Service (ECS) 上の Windows コンテナの永続ストレージとして使用することに関するブログ記事を公開しました。今日は、Amazon Elastic Kubernetes Service (EKS) で同じことを行う方法について、順を追って説明します。AWS System Manager ドキュメントを使用して、Windows インスタンス上のファイル共有マッピングを自動化し、Docker ボリュームをコンテナに提供するための EKS Windows ポッドを設定します。

では、これをどのように実現するかをご説明します。
Windows Server バージョン 1709 (Windows Server 2016「半期チャネル」) で「SMB グローバルマッピング」と呼ばれる SMB プロトコルの既存の機能を活用します。SMB グローバルマッピングを使用すると、SMB 共有をホストにマウントし、その共有上のディレクトリをコンテナに渡すことができます。コンテナを特定のサーバー、共有、ユーザー名、またはパスワードで設定する必要はありません。これらはすべてホストが代わりに処理します。コンテナは、ローカルストレージがある場合と同じように機能します。

前提条件および仮定

  • コンピュータに AWS CLIWindows PowerShell 用 AWS Tools を適切にインストールし、設定済みであること。
  • コンテナインスタンスとして Windows Server 2019 Amazon マシンイメージを使用し、EKS クラスターをセットアップ済みであること。EKS 公式ドキュメント。
  • コンテナインスタンスが Active Directory ドメインのメンバーであること。「手動で Windows インスタンスに参加する方法」を参照してください。
  • このブログ記事では、Managed Microsoft AD としての AWS Directory Service について説明していますが、コンテナインスタンスがドメインに参加できる限り、他の Active Directory シナリオでも有効です。
  • Amazon FSx for Windows ファイルサーバーがデプロイ済みであること
  • このブログ記事の内容は、Amazon EKS 上の Windows コンテナインスタンスにも通用します。

このブログでは、以下を行います。

  • System Manager パラメータストアで、ユーザー名とパスワード用の 2 つのパラメータを作成する。
  • System Manager ドキュメントを作成し、EKS Windows インスタンスで SMB グローバルマッピングをセットアップする。
  • KMS と SSM ポリシーを既存のインスタンス IAM ロールにアタッチする。
  • System Manager ドキュメントを作成し、ECS コンテナインスタンスで SMB グローバルマッピングをセットアップする。
  • Windows ポッドを起動して、結果を確認する。

1.System Manager パラメータストアで、ユーザー名とパスワード用の 2 つのパラメータを作成する。

PowerShell コンソールで、2 つの SSM パラメータを作成します。Active Directory ユーザーアカウント情報を保存する「domainUserName」と AWS KMS が暗号化したパスワードを保存する「domainUserPassword」という名前を選択します。- Value は、コンテナインスタンスと Amazon FSx for Windows ファイルサーバーが提供するファイル共有との間での共有認証/承認フェーズで使用するよう設計した、既存のユーザーアカウントとパスワードである必要があります。

Write-SSMParameter -Name 'domainUserName' -Value 'DOMAIN\USERNAME' -Type String
Write-SSMParameter -Name 'domainUserPassword' -Value 'PASSWORD' -Type SecureString -KeyId "KMSKeyId"

In the above command if you don't specify the KeyId parameter by default SSM uses the following key-id: *key/alias/aws/ssm*

2.System Manager ドキュメントを作成し、EKS Windows インスタンスで SMB グローバルマッピングをセットアップする。
以下のコンテンツを使用して JSON ファイル (filename.json) をローカルに作成し、以下に示す変更を行います。

  • New-SMBGlobalMapping コマンドで、「FSx DNS NAME」を Amazon FSx for Windows ファイルサーバーの DNS 名に、「Directory」を Docker コンテナボリュームで使用する共有内に作成した既存のディレクトリに置き換えます。また、必要に応じて、-LocalPath パラメータ値を G: ではなく、お好みのドライブ文字に置き換えます。
{
    "schemaVersion": "2.2",
    "description": "Map SMB Share using SMBGlobalMappings for Windows Containers",
    "mainSteps": [
        {
            "action": "aws:runPowerShellScript",
            "name": "runPowerShellWithSecureString",
            "precondition": {
                "StringEquals": [
                    "platformType",
                    "Windows"
                ]
            },
            "inputs": {
                "runCommand": [
                    "$username = (Get-SSMParameterValue -Name domainUserName).Parameters[0].Value",
                    "$password = (Get-SSMParameterValue -Name domainUserPassword -WithDecryption $True).Parameters[0].Value | ConvertTo-SecureString -asPlainText -Force",
                    "$credential = New-Object System.Management.Automation.PSCredential($username,$password)",
                    "New-SmbGlobalMapping -RemotePath '\\\\FSxDNSNAME\\share\\Directory' -Credential $credential -LocalPath G: -RequirePrivacy $true -ErrorAction Stop"
                ]
            }
        }
    ]
}

上記の JSON スクリプトは、新しい SMB グローバルマッピングを作成し、 ‘domainUserName' and 'domainUserPassword' SSM parameters created during step-1 を使用して、FSX Windows 共有からコンテナインスタンスのローカルドライブ「G:」にパス「\\ Share \\ Directory」をマッピングします。

2.1 ローカルマシンで作成したファイルを使って、SSM ドキュメントを作成しましょう。PowerShell コンソールで、

$json = Get-Content C:\filename.json | Out-String
New-SSMDocument -DocumentType Command -Name document name -Content $json

[オプション]
2.2 ディレクトリにはボリュームとして Docker コンテナに示されたすべてのデータ (アプリのソース、データベース、機密ファイルなど) が含まれるため、セキュリティのために、メインの Docker ボリュームストレージとして使用する指定ディレクトリの継承を無効にし、認証済みユーザーを削除することが推奨されます。その後、SMB ファイル共有を認証するためのユーザーアカウントとして選択した既存のユーザーアカウントを追加します。[権限の変更] を選択します。

3.KMS と SSM ポリシーを既存のインスタンス IAM ロールにアタッチする。

コンテナインスタンスから KMS および System Manager の使用を有効にするには、Windows クラスターの構築時に作成したインスタンスロールに正しい IAM ポリシーが添付されていることを確認する必要があります。通常、EKS によって作成されたコンテナインスタンスの IAM ロールには、<cluster-name>-<worker-node>-NodeInstanceRole-<id> のような一意の名前が付けられます。インスタンスの詳細ページで確認できます。

まず、新しいポリシーを作成して、既存の IAM ロールにアタッチします。このポリシーは、セキュアな文字列値を持つ SSM パラメータが使用する kms:Decrypt API を呼び出すアクセス許可をインスタンスに付与します。これは、ステップ 1 で作成したパスワードパラメータを意味します。JSON ファイルを作成し、以下の例を使用してコンピューターに保存します。

region:account を、クラスターを起動したリージョンとアカウント ID に置き換えます。
key-id を、「domainUserPassword」SSM パラメータの作成中に使用したキーの ID に置き換えます。デフォルトでは、SSM は次のキー ID を使用します。key/alias/aws/ssm

{"Version":"2012-10-17",
   "Statement":[
      {"Effect":"Allow",
         "Action":[
            "kms:Decrypt"
         ],
         "Resource":[
            "arn:aws:kms:region:account-id:key/key-id"
         ]
      }
   ]
}

3.1 次に、既存の IAM ロールにポリシーを作成し、添付します。PowerShell コンソールで、以下を実行します。
*Replace ACCOUNT-ID with the account ID number and <existing-IAM-role> with the instance IAM role*

New-IAMPolicy -PolicyName "SSMSecureString" -policyDocument (Get-Content -Raw MySamplePolicy.json)
Register-IAMRolePolicy -RoleName <existing-IAM-role> -PolicyArn arn:aws:iam::ACCOUNT-ID:policy/SSMSecureString

3.2 IAM 管理ポリシー AmazonEC2RoleforSSM をインスタンスのロールにアタッチします。
*Replace <existing-IAM-role> with the instance IAM role*

Register-IAMRolePolicy -RoleName <existing-IAM-role> -PolicyArn arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM

4.System Manager ドキュメントを作成し、ECS コンテナインスタンスで SMB グローバルマッピングをセットアップする。

最後に、結果を見てみましょう。 PowerShell コンソールから以下のコマンドを実行し、SSMCommand を呼び出して、ステップ 2 で作成したドキュメントを実行します。

Send-SSMCommand -InstanceId instance-id -DocumentName SMBGlobalMappings

注: クラスターに複数の Windows インスタンスがある場合は、それらすべてに対して上記のコマンドを実行する必要があります。これをワンステップで行うには、-InstanceId パラメータを使用して、最大 50 個までのインスタンス ID を指定します。

この記事で紹介した例のような出力を受け取ることになるでしょう。 ステータスを見ると、SSM が Amazon EC2 インスタンスに対してコマンドを実行しているため、「Pending」と表示されます。

CloudWatchOutputConfig : Amazon.SimpleSystemsManagement.Model.CloudWatchOutputConfig
CommandId : 71d161be-e200-48c3-bd2d-a9ffe1dcc94b
Comment :
CompletedCount : 0
DeliveryTimedOutCount : 0
DocumentName : SMBGlobalMappings
DocumentVersion :
ErrorCount : 0
ExpiresAfter : 1/29/2020 12:27:00 AM
InstanceIds : {i-0e176f3c47e4fcb59}
MaxConcurrency : 50
MaxErrors : 0
NotificationConfig : Amazon.SimpleSystemsManagement.Model.NotificationConfig
OutputS3BucketName :
OutputS3KeyPrefix :
OutputS3Region :
Parameters : {}
RequestedDateTime : 1/28/2020 10:27:00 PM
ServiceRole :
Status : Pending
StatusDetails : Pending
TargetCount : 1
Targets : {}

4.1 以下に示すコマンド ID を使用して、上記のコマンドを実行し、SSM ドキュメントが正常に実行されたことを確認します。

Get-SSMCommandInvocation -CommandId "commandId"

上記のコマンドは、ステータスが「Success」の次のような出力を返すと予想されます。

CommandId : dc383f39-8f8b-4cd1-987a-84c82ab1dd9c
CommandPlugins : {}
Comment :
DocumentName : CreateSMBGlobalMappingsFsxBlog
InstanceId : i-034ffa7bf391dcc80
InstanceName :
NotificationConfig : Amazon.SimpleSystemsManagement.Model.NotificationConfig
RequestedDateTime : 2/18/2020 8:45:56 PM
ServiceRole :
StandardErrorUrl :
StandardOutputUrl :
Status : Success
StatusDetails : Success
TraceOutput :

4.2 これで完了です。 コンテナインスタンスに SMB 共有がマウントされました。RDP セッションまたは System Manager Session Manager を介してインスタンスにアクセスし、PowerShell コンソールで次のコマンドを実行します。

Get-SMBGlobalMappings

New-SmbGlobalMapping コマンドのステップ 2 で使用した「ディレクトリ」の結果が表示されます。

5.Windows ポッドを起動して、結果を確認する。

ディレクトリを G:\ドライブからコンテナへのボリュームとして提示するには、以下のようなポッド設定が必要です。

apiVersion: v1
kind: Pod
metadata:
  name: test-fsx
spec:
  containers:
  - name: test-fsx
    image: mcr.microsoft.com/windows/servercore:1809
    command:
      - powershell.exe
      - -command
      - "Add-WindowsFeature Web-Server; Invoke-WebRequest -UseBasicParsing -Uri 'https://dotnetbinaries.blob.core.windows.net/servicemonitor/2.0.1.6/ServiceMonitor.exe' -OutFile 'C:\\ServiceMonitor.exe'; echo '<html><body><br/><br/><marquee><H1>Hello EKS!!!<H1><marquee></body><html>' > C:\\inetpub\\wwwroot\\default.html; C:\\ServiceMonitor.exe 'w3svc'; "
    volumeMounts:
      - mountPath: C:\dotnetapp\app-state
        name: test-mount
  volumes:
    - name: test-mount
      hostPath: 
        path: G:\Directory\app-state
        type: Directory
  nodeSelector:
      beta.kubernetes.io/os: windows
      beta.kubernetes.io/arch: amd64

上記のポッドを EKS Windows インスタンス上で起動します

kubectl apply -f <pod-filename>.yaml

まとめ

これで完了です。 Amazon FSx for Windows ファイルサーバーでホストされている SMB 共有を介して、EKS Windows コンテナインスタンスを設定するだけで、コンテナボリュームをマウントできるようにました。コンテナへのデータ永続化のアプローチは、新しいクラウドネイティブのアプリには理想的ではありませんが、レガシアプリケーションには最適で、必須と言えます。このアプローチが極めてよく適合する例としては、レガシーの ASP.NET アプリケーションがあります。コードを変更せずにアプリケーションディレクトリをリダイレクトし、マルチ AZ 配置で Amazon FSx for Windows ファイルサーバーを使用して高い可用性と災害対策を実現できるようになります。