Amazon Web Services ブログ

オープンソースの PACS ソリューション Dicoogle を AWS で実行する (第 2 部)

この記事は、“Running Dicoogle, an open source PACS solution, on AWS (part 2)” を翻訳したものです。

このブログは、Dicoogle オープンソースソフトウェアを使用して AWS で安全なDigital Imaging and Communications in Medicine (DICOM) サーバーをホストする方法を説明する 2 部構成のシリーズの第 2 部です。

このブログ連載の第 1 部 では、DICOM を紹介し、本ソリューションが提供するDICOM機能を説明し、以下のアーキテクチャ図のように、使用する AWS サービスを明確にした上で、安全な DICOM サーバーをホストする方法を説明しました。

このブログでは、AWS にソリューションをデプロイし、テストを実行する方法を 4 つのセクションで説明します。

  1. 前提条件を設定します。
  2. デプロイに必要な成果物を準備します。
  3. AWS CloudFormation テンプレートをデプロイしてソリューションを立ち上げます。
  4. テストを実行します。

このコードは GitHub リポジトリで入手できます。

前提条件

このソリューションには、次の前提条件が必要です。

  • AWS アカウント
  • AWS のリソースを配置するパーティションが「aws」 の AWS リージョン。このソリューションはパーティションが「aws-cn」の中国リージョンまたは 「aws-us-gov」のAWS GovCloud (米国) リージョンをサポートしていないことに注意してください。
  • 既存の Amazon Route53 public hosted zone (または、こちらの手順に従って新規に作成します)。
  • 3 つの Amazon Virtual Private Clouds (Amazon VPC)、3 つのInternet Gateway、4 つの NAT Gateway、および 4 つの Elastic IP を作成するのに十分な AWS サービスクォータがあること。
  • SSL 証明書と秘密鍵の 5 つのセット: AWS Fargate で実行される nginx リバースプロキシ、Fargate で実行される ghostunnel リバースプロキシとフォワードプロキシ、クライアント用Amazon Elastic Computer Cloud (Amazon EC2) で実行される ghostunnel フォワードプロキシ、および ストレージ用Amazon EC2で実行される storescp 、それぞれで認証用に 1 つずつ必要です。

ソリューションをデプロイするための準備

  1. AWS Cloud9 サービスのコンソールにログインします。「Create environment」をクリックして、AWS Cloud9 環境を作成します。Step 1 でご希望の名前を入力し、「Next step」 をクリックします。 Step 2 の「Configure settings」 の設定はデフォルトのままで、「Next step」 をクリックします。 最後に、「Create environment」をクリックします。
  2. AWS Cloud9 環境が作成されるまで待ってから、画面下部のターミナルウィンドウに移動します。
  1. 次のコマンドを実行してキーペアを作成します。このキーペアは、AWS Cloud9 ターミナルからAmazon EC2 インスタンスに SSH 接続するために使用されます。出力 (秘密鍵) をファイルに保存します。
    sudo yum install -y jq
    aws ec2 create-key-pair --key-name "dicoogle" | jq -r ".KeyMaterial" > ~/dicoogle.pem
    chmod 400 ~/dicoogle.pem
    	
  1. 次のコマンドを実行して、Amazon Simple Storage Service (Amazon S3) バケットを作成します。出力されるバケット名をメモします。
    SUFFIX=$( echo $RANDOM | md5sum | head -c 20 )
    BUCKET=dicoogle-$SUFFIX
    aws s3 mb s3://$BUCKET
    echo “Bucket name: $BUCKET”
  1. 次のコマンドを実行して、最初に AWS キーマネジメントサービス (AWS KMS) キーを作成し、続けて 3 つの Amazon Elastic Container Registory (Amazon ECR) リポジトリを作成します。Dicoogle 用、Nginx 用、Ghostunnel 用です。
    KMS_KEY=$( aws kms create-key | jq -r .KeyMetadata.KeyId )
    aws ecr create-repository --repository-name dicoogle --encryption-configuration encryptionType=KMS,kmsKey=$KMS_KEY
    aws ecr create-repository --repository-name nginx --encryption-configuration encryptionType=KMS,kmsKey=$KMS_KEY
    aws ecr create-repository --repository-name ghostunnel --encryption-configuration encryptionType=KMS,kmsKey=$KMS_KEY
  1. 次のコマンドを実行して、GitHub コードリポジトリをクローンします。
    cd ~/environment
    git clone https://github.com/aws-samples/dicoogle-on-aws
  1. 次のコマンドを実行して Docker イメージをビルドし、Amazon ECR にプッシュします。出力の各イメージ名をメモします。これらをステップ 12 で使用します。
    cd ~/environment/dicoogle-on-aws/docker/dicoogle
    ./build.sh
    cd ~/environment/dicoogle-on-aws/docker/nginx
    ./build.sh
    cd ~/environment/dicoogle-on-aws/docker/ghostunnel
    ./build.sh
  1. 次のコマンドを実行して AWS Lambda 関数をパッケージ化し、デプロイするすべての成果物をAmazon S3 バケットにアップロードします。アップロードされた成果物には、すべての AWS CloudFormation テンプレートと、zip 形式でパッケージ化された Lambda 関数が含まれます。これらは、ソリューションのデプロイに使用されます。出力された Amazon S3 テンプレートの URL をメモします。ステップ 11 で使用します。
    cd ~/environment/dicoogle-on-aws
    chmod 755 ./artifacts.sh
    ./artifacts.sh $BUCKET
  1. 次のステップでは、環境を設定する際、独自の SSL 証明書と秘密鍵を生成して使用する必要があります。そして、AWS Secrets Manager でエントリを作成し、SSL 証明書と秘密鍵を設定します。デモンストレーションの目的で、自己署名 SSL 証明書を生成する手順を説明します。自己署名SSL証明書は本番稼働用ではないことに注意してください。
    cd ~/environment/dicoogle-on-aws/cert

    以下の手順では、プロンプトが表示されたら、デフォルト値を全てそのまま使用します。証明書への署名またはコミットのプロンプトが表示されたら、「y」を選択します。

    ルート CA 証明書を生成する:

    openssl req -x509 -config openssl-ca.cnf -newkey rsa:4096 -sha256 -nodes -out cacert.pem -outform PEM

    nginx 用の証明書署名リクエスト (CSR: Certificate Signing Request) を生成する:

    openssl req -config openssl-nginx.cnf -newkey rsa:2048 -sha256 -nodes -out nginxcert.csr -outform PEM

    nginx 用の証明書の CSR に署名する:

    openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out nginxcert.pem -infiles nginxcert.csr

    Ghostunnel 用の証明書署名リクエスト (CSR) を生成する:

    openssl req -config openssl-ghostunnel.cnf -newkey rsa:2048 -sha256 -nodes -out ghostunnelcert.csr -outform PEM

    Ghostunnel 用の証明書の CSR に署名する:

    openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out ghostunnelcert.pem -infiles ghostunnelcert.csr

    クライアントとして利用する EC2 用の証明書署名リクエスト (CSR) を生成する:

    openssl req -config openssl-client.cnf -newkey rsa:2048 -sha256 -nodes -out clientcert.csr -outform PEM

    クライアントとして利用する EC2 用の証明書の CSR に署名する:

    openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out clientcert.pem -infiles clientcert.csr

    ストレージ として利用する EC2 用の証明書署名リクエスト (CSR) を生成する:

    openssl req -config openssl-storage.cnf -newkey rsa:2048 -sha256 -nodes -out storagecert.csr -outform PEM

    ストレージとして利用する EC2 用の証明書の CSR に署名する:

    openssl ca -config openssl-ca.cnf -policy signing_policy -extensions signing_req -out storagecert.pem -infiles storagecert.csr

    Secrets Manager にエントリーを作成する:

    chmod 755 ./secrets.sh
    ./secrets.sh

    出力される各シークレット ARN (Amazon Resource Name) をメモします。これらをステップ 12 で使用します。

  1. AWS Route 53 サービスコンソールに移動します。ソリューションに使用する既存のパブリックホストゾーンを見つけます。「Domain name」と「Hosted zone ID」をメモしておきます。 これらをステップ12 で使用します。

ソリューションのデプロイ

  1. CloudFormation サービスコンソールに移動します。「Create stack」 をクリックし、「With new resources (standard)」を選択します。 「Prerequisite – Prepare template」 で、「Template is ready」 を選択します。 「Specify template」で「Amazon S3 URL」を選択し、ステップ 8 でメモした S3 テンプレート URL を入力します。「Next」をクリックします。
  1. 「Stack name」に「dicoogle」と入力します。 「Require input」セクションのパラメーターについては、「KeyName」で「dicoogle」を選択します。 「S3BucketName」に、ステップ 4 のバケット名を入力します。 「DicoogleImage」、「NginxImage」、および「GhostTunnelImage」に、手順 7 の各イメージ名を入力します。 手順 9 の各シークレット ARN を「NginxCert」、「NginxKey」、「GhostTunnelCert」、「GhostTunnelKey」、および「CACert」に入力します。「DomainName」にステップ 10 のドメイン名を入力し、「HostedZone」には、手順 10 のHosted zone ID を選択します。 「AvailabilityZones」では 2 つのアベイラビリティゾーンを選択します

  1. 「Contain default value. Input is optional」セクションのパラメータは、デフォルト値のままにします。「Next」をクリックして 「Configure stack options」に進みます。 次に、「Next」をクリックして「Review」に進みます。 2 つのチェックボックスを選択して、CloudFormation がカスタム名で IAM リソースを作成し、CAPABILITY_AUTO_EXPAND 機能を要求する可能性があることを確認します。次に「Create stack」をクリックします。 デプロイには約 20 分かかります。

Dicoogle への画像の一括アップロードのテスト

  1. 続けて、AWS Cloud9 で 3 つの ターミナルウィンドウを開きます。最初のターミナルウィンドウを使用してクライアント用の Amazon EC2 インスタンスにアクセスし、2 つ目のターミナルウィンドウを使用して DataSync タスクを起動して DNS ルックアップを実行し、3 つ目のターミナルウィンドウを使用してストレージ用の Amazon EC2 インスタンスにアクセスします。クライアントとストレージ用の Amazon EC2 インスタンスは、オンプレミス環境をシミュレートする Amazon Virtual Private Cloud (Amazon VPC) に配置されます。これらはインターネット経由で AWS Cloud9 からのアクセスが許可されており、デモンストレーション目的でのみ必要なパッケージをダウンロードするためにインターネットにアクセスできます。インターネットからのアクセスとインターネットへのアクセスは可能な限り制限することがベストプラクティスです。各ターミナルウィンドウで、次のコマンドを実行して、必要なすべての CloudFormation スタックの出力を取得し、後で使用するために環境変数を設定します。
    source ~/environment/dicoogle-on-aws/output.sh

    出力値をメモします。

  1. 最初のターミナルで、次のコマンドを実行してサンプル画像ファイルをクライアント用の Amazon EC2 インスタンスにコピーします。
    scp -i ~/dicoogle.pem ~/environment/dicoogle-on-aws/data/1*.dcm ec2-user@$ClientEC2Stack_PublicDNS:/home/ec2-user/

    「Are you sure you want to continue connecting (yes/no)?」という質問に「yes」と入力します。
    次のコマンドを実行して、クライアント証明書、秘密鍵、および CA 証明書をクライアント用 のAmazon EC2 インスタンスにコピーします。

    scp -i ~/dicoogle.pem ~/environment/dicoogle-on-aws/cert/client*.pem ec2-user@$ClientEC2Stack_PublicDNS:/home/ec2-user/
    scp -i ~/dicoogle.pem ~/environment/dicoogle-on-aws/cert/cacert.pem ec2-user@$ClientEC2Stack_PublicDNS:/home/ec2-user/

    次に、次のコマンドを実行して、クライアント用 のAmazon EC2 インスタンスに ssh 接続します。

    ssh -i ~/dicoogle.pem ec2-user@$ClientEC2Stack_PublicDNS

    これで、クライアント用 のAmazon EC2 インスタンスに接続しました。

  1. クライアント用 の Amazon EC2 インスタンスに接続している最初のターミナルで、次のコマンドを実行して、サンプル画像を (画像一括アップロードのシミュレーションとして) 画像バケットにアップロードします。AWS Cloud9 ではなくクライアント 用の Amazon EC2 からサンプル画像をアップロードする必要があるのは、オンプレミス環境をシミュレートする Amazon VPC からのアップロードでない限り、バケットへのアップロードを拒否するバケットポリシーを定義したためです。
    aws s3 cp ~/1-01.dcm s3://<ImageBcket from step 14 output>/
  1. 2 番目のターミナルで、次のコマンドを実行してタスクの実行を開始し、Amazon S3 から Amazon Elastic File System (Amazon EFS) に画像ファイルをコピーします。
    TASK_EXECUTION_ARN=$( aws datasync start-task-execution --task-arn $DataSyncStack_TaskArn | jq -r .TaskExecutionArn )

    ステータスとして「SUCCESS」が表示されるまで、次のコマンドを実行して実行ステータスを確認します。

    aws datasync describe-task-execution --task-execution-arn $TASK_EXECUTION_ARN | jq -r .Status

アップロードされた画像のインデックス作成のテスト

  1. ここで、AWS Cloud9 ターミナル環境を一時的に終了し、デスクトップまたはラップトップに切り替えます。CloudFormation を利用したデプロイにより、Amazon Cognito ユーザープールが作成されました。ここでは、Dicoogle 管理者として Amazon Cognito ユーザープールにユーザーを作成します。ブラウザを起動し、Amazon Cognito サービスのコンソールに移動し、「Manage User Pools」 をクリックして、ステップ 14 で記録した UserPool 値と一致する「Pool Id」を持つユーザープールを選択します。「General settings」に移動し、「Users and groups」に移動し、「Create user」をクリックします。フォームに記入してユーザーを作成します。
  1. デスクトップまたはラップトップから、ブラウザで新しいタブを開き、https://<ALBDnsRecord> に移動します (訳注: SSLサーバ証明書の検証エラーが発生します。デモンストレーション以外では、信頼された認証局に署名されたSSLサーバ証明書を使用してください。) 。AlbDNSRecordはステップ14の出力に含まれています。「Sign in」ウィンドウで、ステップ 18 のユーザー名とパスワードを入力して、Amazon Cognito で認証します。

    初めてサインインすると、パスワードを変更するように求められます。新しいパスワードを入力し、「Send」をクリックします。
    これにより、Dicoogle ウェブ UI のサインインウィンドウへのアクセスが許可されます。ユーザー名としてデフォルトの「dicoogle」、パスワードとして「dicoogle」を使用してログインします。
  1. 左側の「Indexer」をクリックします。index directory に「file: /opt/dicoogle/Dicoogle_v3.0.2/Images」と入力します。index providers から「lucene」を選択します。画像ファイルのインデックスを作成するには、「Start」をクリックします。

C-FINDC-MOVEのテスト

  1. ここで、AWS Cloud9 に戻ります。3 番目の AWS Cloud9 ターミナルから、次のコマンドを実行して、ストレージ用EC2のサーバ証明書、秘密鍵、および CA 証明書をストレージ用の Amazon EC2 インスタンスにコピーします。
    scp -i ~/dicoogle.pem ~/environment/dicoogle/cert/storage*.pem ec2-user@$StorageEC2Stack_PublicDNS:/home/ec2-user/
    scp -i ~/dicoogle.pem ~/environment/dicoogle/cert/cacert.pem ec2-user@$StorageEC2Stack_PublicDNS:/home/ec2-user/

    次のコマンドを実行して、ストレージ用 の Amazon EC2 インスタンスに SSH 接続します。

    ssh -i ~/dicoogle.pem ec2-user@$StorageEC2Stack_PublicDNS

    「Are you sure you want to continue connecting (yes/no)?」という質問に「yes」と入力します。
    これで、ストレージ用 の Amazon EC2 インスタンスに接続しました。

  1. AWS Cloud9 の、ストレージ用の Amazon EC2 インスタンスに接続している 3 番目の ターミナルから、次のコマンドを実行し、dcmtk パッケージの storescp ユーティリティを使用して Storage Service Class Provider (Storage SCP) を開始します。ストレージ用の Amazon EC2 インスタンスのデプロイ中に、ユーザーデータdcmtk パッケージをインストールしていることに注意してください。このパッケージは、テストのために Dicoogle と相互にやりとりするためのユーティリティを提供します。
    storescp -d -aet CONSUMER -od "/home/ec2-user" 7777 -su study -fe .dcm --fork +tls storagekey.pem storagecert.pem +cf cacert.pem
  1. AWS Cloud9 の 2 番目のターミナルで、ステップ 14 の出力に含まれる ProviderEndPoint を使用して、次のコマンドを実行して、プロバイダーエンドポイントに関連付けられた IP アドレスを取得します。エンドポイントには 2 つの IP アドレスが関連付けられています。2 つの IP アドレスのうち 1 つを選択し、後のステップ 25、26、および 28 で使用できるようにメモしておきます。
    nslookup $PrivatelinkStack_ProviderEndpoint

  1. デスクトップまたはラップトップに切り替えて、Dicoogle 管理コンソールに戻り、左側の「Management」をクリックします。「Storage Servers」タブに移動し、「Add New」をクリックして Storage Server を追加します。
    「AE Title」に「CONSUMER」、「IP Address」に「127.0.0.1」、「Port」に「17777」と入力したら、「Add」をクリックします。 127.0.0.1/localhost のポート17777 は、Ghostunnel フォワードプロキシが listen します。CloudFormation スタックのデプロイでは、Ghostunnel フォワードプロキシが、ストレージ用の Amazon EC2 インスタンスを宛先としてポイントするように自動的に設定されます。
  1. AWS Cloud9 の最初のターミナル(現在はクライアント用 Amazon EC2 インスタンスに接続しています)から、dcmtk パッケージの findscu ユーティリティを使用して、次のコマンドを実行し、サンプル画像のある Dicoogle にクエリを実行します。ストレージ用の Amazon EC2 インスタンスと同様に、デプロイ時にクライアント用の Amazon EC2 インスタンスに dcmtk パッケージもインストールしました。
    findscu -S -k 0008,0052=STUDY -aec DICOOGLE-STORAGE <ip address of provider endpoint from step 23> 1045 -k 0010,0020=* -k 0020,000d -k 0008,1030 -k 0008,0020 -k 0008,0050

    この応答はDicoogleから返ってきます。出力される大括弧内の StudyInstanceUID に注目してください。ステップ 26 で使用します。

  1. AWS Cloud9の最初のターミナルから次のコマンドを実行し、dcmtk パッケージの movescu ユーティリティを使用して Dicoogle からサンプル画像を取得し、ストレージ用の Amazon EC2 インスタンス(DICOM 宛先ノード)に送信します。
    movescu -v -S -P -aec "DICOOGLE-STORAGE" -aet CONSUMER -aem CONSUMER -k StudyInstanceUID=<StudyInstanceUID from step 24> <ip address of provider endpoint from step 23> 1045 +xa

  1. ストレージ用 Amazon EC2 インスタンス上にある 3 つ目の AWS Cloud9 ターミナルで、<ctrl>C を押して storescp プロセスを中断します。次のコマンドを実行して、取得した画像が使用可能になったことを確認します。
    ls -lt ~/study*

C-STOREのテスト

  1. 現在クライアント用の Amazon EC2 インスタンスに接続しているAWS Cloud9の最初のターミナルから、次のコマンドを実行して最初に ghostunnel フォワードプロキシを起動し、dcmtk パッケージの dcmsend ユーティリティを使用してサンプル画像を Dicoogle に送信します。これは、画像をPACSシステムとしてDicoogleに直接送信するモダリティをシミュレートするために行われます。
    sudo su –
    echo <ip address of provider endpoint from step 23> ghostunnel.example.com >> /etc/hosts
    exit
    ghostunnel client --listen localhost:16666 --target ghostunnel.example.com:16666 --cert=clientcert.pem --key=clientkey.pem --cacert=cacert.pem > /dev/null 2>&1 &
    dcmsend -v 127.0.0.1 16666 1-02.dcm

  1. デスクトップまたはラップトップに切り替え、Dicoogle 管理コンソールに戻り、メニュー左側の 「Search」をクリックします。「All providers」のドロップダウンリストから「lucene」を選択し、「Search」をクリックします。 1 人の患者が返るはずです。返された患者レコードをクリックし、次に検査レコードをクリックし、最後にシリーズレコードをクリックします。2 つの画像が返されます。1つは、datasyncタスクを介してDicoogleにアップロードされ、手順 20 で Dicoogle によってインデックスが作成された最初のサンプル画像からのものです。もう 1 つは、ステップ 28 でクライアント用のAmazon EC2 インスタンスから Dicoogle にアップロードされた 2 つ目のサンプル画像です。

デプロイしたソリューションの削除

今後の課金が発生しないように、ソリューションの準備とデプロイを行うセクションで作成したリソースを削除します。

  • CloudFormation スタック
  • Amazon ECR リポジトリ
  • AWS KMS キー
  • AWS Secret Manager のシークレット
  • Amazon S3 バケット
  • キーペア
  • AWS Cloud9 インスタンス

元の AWS Cloud9 ターミナルウィンドウ (ステップ 3 ~ 9 を実行した場所) に移動し、次のコマンドを実行します。

source ~/environment/dicoogle/output.sh
aws cloudformation delete-stack --stack-name dicoogle

DICOOGLE-LogBucketStack と DICOOGLE-ImagesBucketStack にログファイルと画像ファイルが含まれていると、削除に失敗することがあります。その場合は、次のコマンドを実行して、バケット内のすべてのオブジェクトごと、強制的にバケットを削除します。

aws s3 rb s3://$LogBucketStack_LogBucket --force
aws s3 rb s3://$ImagesBucketStack_ImagesBucket --force

次に、前のコマンドの実行に戻って、dicoogle スタックを削除します。(訳注: 続けて、以下のコマンドを実行して残りのリソースを削除します。)

aws ecr delete-repository --repository-name dicoogle –force
aws ecr delete-repository --repository-name nginx --force
aws ecr delete-repository --repository-name ghostunnel --force
aws kms schedule-key-deletion --key-id $KMS_KEY --pending-window-in-days 7
aws secretsmanager delete-secret --secret-id CACERT
aws secretsmanager delete-secret --secret-id NGINXCERT
aws secretsmanager delete-secret --secret-id NGINXKEY
aws secretsmanager delete-secret --secret-id GHOSTUNNELCERT
aws secretsmanager delete-secret --secret-id GHOSTUNNELKEY
aws s3 rb s3://$BUCKET --force
aws ec2 delete-key-pair --key-name dicoogle

最後に、AWS Cloud9 サービスコンソールに移動し、「Delete」をクリックして AWS Cloud9 環境を削除します。

まとめ

この記事では、CloudFormation テンプレートを使用して AWS に Dicoogle をデプロイする手順と、1) Dicoogle に画像を一括アップロードする 2) Dicoogle でアップロードされた画像のインデックスを作成する 3) DICOM の C-FIND、C-MOVE、および C-STORE 機能をテストする手順について説明しました。機能と最新の開発状況について、詳しくは Dicoogle のドキュメントをご覧ください。Dicoogle コミュニティに貢献するには、GitHub リポジトリにアクセスしてください。

翻訳は Solutions Architect 今井と窪田が担当しました。原文はこちらです。