PACS の Cloud Healthcare API への接続

このページでは、Google Kubernetes Engine(GKE)でオープンソースの Cloud Healthcare API DICOM アダプタを使用して次のタスクを行う方法について説明します。

  • 画像保存通信システム(PACS)を Cloud Healthcare API に接続します。
  • PACS から Cloud Healthcare API の DICOM ストアに DICOM データをインポートします。

このガイドでは、Google Kubernetes Engine と Compute Engine 仮想マシン(VM)を使用してプロトタイプを簡単に設定する方法について説明します。Compute Engine VM で、オンプレミス PAC がシミュレートされます。詳細については、DICOM adapter README をご覧ください。

DICOM アダプタの概要

このアダプタは、インポート アダプタとエクスポート アダプタの 2 つの主要コンポーネントで構成されます。このガイドでは、インポート アダプタを使用して DICOM 画像を DICOM ストアに保存する方法を説明します。

DICOM アダプタを使用して、従来のプロトコルと RESTful プロトコル間でデータを変換します。たとえば、C-STORE 形式から STOW-RS 形式に変換できます。

費用

このガイドでは、課金対象となる以下の Google Cloudのコンポーネントを使用します。

  • Cloud Healthcare API
  • Google Kubernetes Engine
  • Compute Engine

料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを出すことができます。新しい Cloud Platform ユーザーは無料トライアルをご利用いただけます。

始める前に

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Cloud Healthcare API, Google Kubernetes Engine, and Container Registry APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  5. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Cloud Healthcare API, Google Kubernetes Engine, and Container Registry APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  8. GKE API と関連サービスが有効になるのを待ちます。 これには数分かかることがあります。
  9. まだ DICOM ストアを作成していない場合は作成します。
  10. シェルを選択する

    このガイドを完了するには、Cloud Shell またはローカルシェルを使用します。

    Cloud Shell は、 Google Cloudでホストされているリソースを管理するためのシェル環境です。Cloud Shell には、このガイドで使用する以下のツールがプリインストールされています。

    • gcloud CLI: Google Cloudの主要なコマンドライン インターフェースを提供します
    • kubectl: GKE クラスタに対してコマンドを実行するためのコマンドライン インターフェースを提供します

    Cloud Shell を開くか、ローカルシェルの構成は、次の手順で行います。

    Cloud Shell

    1. Google Cloud コンソールに移動します。

      Google Cloud コンソール

    2. コンソールの右上隅にある [Google Cloud Shell の有効化] ボタン をクリックします。

    コンソールの下部にあるフレーム内で Cloud Shell セッションが開きます。このシェルで gcloud コマンドと kubectl コマンドを実行します。

    ローカルシェル

    ローカルシェルを使用する場合は、gcloud CLI をインストールする必要があります。手順については、Google Cloud CLI のインストールをご覧ください。

    Google Kubernetes Engine を使用したアダプタのデプロイ

    インポート アダプタとエクスポート アダプタは、Container Registry 内の事前に構築された Docker イメージでステージングされたコンテナ化アプリケーションです。このガイドでは、dicom-import-adapter イメージをデプロイして、GKE クラスタ上で実行します。

    Compute Engine サービス アカウントに権限を付与します

    インスタンスのサービス アカウントの作成と有効化の手順に沿って、Compute Engine のデフォルトのサービス アカウントroles/healthcare.dicomEditor ロールを付与します。詳細については、DICOM ストアのロールをご覧ください。

    クラスタを作成する

    gcloud

    GKE 内に dicom-adapter という名前のクラスタを作成するには、gcloud container clusters create コマンドを実行します。

    後述のコマンドデータを使用する前に、次のように置き換えます。

    • COMPUTE_ZONE: クラスタがデプロイされるゾーン。ゾーンとは、クラスタとそのリソースがデプロイされるおおよその地理的な位置のことです。たとえば、us-west1-aus-west リージョン内のゾーンです。gcloud config set compute/zone コマンドを使用してデフォルト ゾーンを設定した場合は、前のコマンドのフラグの値によってデフォルト値がオーバーライドされます。

    次のコマンドを実行します。

    Linux、macOS、Cloud Shell

    gcloud container clusters create dicom-adapter \
      --zone=COMPUTE_ZONE \
      --scopes=https://www.googleapis.com/auth/cloud-healthcare

    Windows(PowerShell)

    gcloud container clusters create dicom-adapter `
      --zone=COMPUTE_ZONE `
      --scopes=https://www.googleapis.com/auth/cloud-healthcare

    Windows(cmd.exe)

    gcloud container clusters create dicom-adapter ^
      --zone=COMPUTE_ZONE ^
      --scopes=https://www.googleapis.com/auth/cloud-healthcare

    次のようなレスポンスが返されます。

    Creating cluster dicom-adapter in COMPUTE_ZONE... Cluster is being health-checked (master is healthy)...done.
    Created [https://container.googleapis.com/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/clusters/dicom-adapter].
    To inspect the contents of your cluster, go to: https://console.cloud.google.com/kubernetes/workload_/gcloud/COMPUTE_ZONE/dicom-adapter?project=PROJECT_ID
    kubeconfig entry generated for dicom-adapter.
    NAME           LOCATION    MASTER_VERSION  MASTER_IP        MACHINE_TYPE   NODE_VERSION   NUM_NODES  STATUS
    dicom-adapter  COMPUTE_ZONE 1.18.16-gke.502   123.456.789.012  n1-standard-1  1.18.16-gke.502  3     RUNNING
    

    Deployment の構成

    アプリケーションを GKE にデプロイするときは、Deployment マニフェスト ファイル(通常は YAML ファイル)を使用して Deployment のプロパティを定義します。Deployment マニフェスト ファイルについては、Deployment を作成するをご覧ください。

    テキスト エディタを使用して、次の内容が含まれる、インポート アダプタの Deployment マニフェスト ファイルを dicom_adapter.yaml という名前で作成します。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dicom-adapter
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: dicom-adapter
      template:
        metadata:
          labels:
            app: dicom-adapter
        spec:
          containers:
            - name: dicom-import-adapter
              image: gcr.io/cloud-healthcare-containers/healthcare-api-dicom-dicomweb-adapter-import:0.2.43
              ports:
                - containerPort: 2575
                  protocol: TCP
                  name: "port"
              args:
                - "--dimse_aet=IMPORTADAPTER"
                - "--dimse_port=2575"
                - "--dicomweb_address=https://healthcare.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/datasets/DATASET_ID/dicomStores/DICOM_STORE_ID/dicomWeb"

    以下を置き換えます。

    • PROJECT_ID: プロジェクト ID
    • LOCATION: データセットのロケーション
    • DATASET_ID: DICOM ストアの親データセットの ID
    • DICOM_STORE_ID: DICOM データのインポート先である DICOM ストアの ID

    Service の構成

    DICOM アダプタを GKE クラスタ外のアプリケーション(PACS など)からアクセスできるようにするには、内部ロードバランサを構成する必要があります。ロードバランサを使用すると、DIMSE ポート(このガイドでは、ポート 2575)を内部で公開できます。

    サービス マニフェスト ファイルを作成して、内部負荷分散を構成します。Deployment マニフェスト ファイルを作成したディレクトリに、テキスト エディタを使用して、次の内容が含まれる dicom_adapter_load_balancer.yaml という名前のファイルを作成します。サービスの Deployment と内部ロードバランサの作成で、サービス マニフェスト ファイルを作成してデプロイします。

    apiVersion: v1
    kind: Service
    metadata:
      name: dicom-adapter-load-balancer
      # The "Internal" annotation will result in an load balancer that can only
      # be accessed from within the VPC the Kubernetes cluster is in.
      # You can remove this annotation to get an externally accessible load balancer.
      annotations:
        cloud.google.com/load-balancer-type: "Internal"
    spec:
      ports:
      - port: 2575
        targetPort: 2575
        protocol: TCP
        name: port
      selector:
        app: dicom-adapter
      type: LoadBalancer
    

    Deployment のデプロイ

    アダプタを GKE クラスタにデプロイするには、dicom_adapter.yaml Deployment マニフェスト ファイルを含むディレクトリで次のコマンドを実行します。

    kubectl apply -f dicom_adapter.yaml
    

    次のような出力が表示されます。

    deployment.apps/dicom-adapter created
    

    Deployment の検査

    Deployment を作成したら、kubectl ツールを使用して検査します。

    デプロイの詳細情報を取得するには、次のコマンドを実行します。

    kubectl describe deployment dicom-adapter
    

    Deployment によって作成された Pod を表示するには、次のコマンドを実行します。

    kubectl get pods -l app=dicom-adapter
    

    作成された Pod に関する情報を取得するには、前のコマンドで返された Pod の名前を使用して次のコマンドを実行します。

    kubectl describe pod POD_NAME

    Deployment が成功すると、上記のコマンドの最後の部分に次の情報が含まれます。アダプタは、dicom-import-adapter コンテナの Reason 列に Started 値がある場合にリクエストを処理する準備が完了しています。

    Events:
      Type    Reason     Age    From                                                   Message
      ----    ------     ----   ----                                                   -------
      Normal  Scheduled  3m33s  default-scheduler                                      Successfully assigned default/dicom-adapter-69d579778-qrm7n to gke-dicom-adapter-default-pool-6f6e0dcd-9cdd
      Normal  Pulling    3m31s  kubelet, gke-dicom-adapter-default-pool-6f6e0dcd-9cdd  Pulling image "gcr.io/cloud-healthcare-containers/healthcare-api-dicom-dicomweb-adapter-import:0.2.43"
      Normal  Pulled     3m10s  kubelet, gke-dicom-adapter-default-pool-6f6e0dcd-9cdd  Successfully pulled image "gcr.io/cloud-healthcare-containers/healthcare-api-dicom-dicomweb-adapter-import:0.2.43"
      Normal  Created    3m7s   kubelet, gke-dicom-adapter-default-pool-6f6e0dcd-9cdd  Created container dicom-import-adapter
      Normal  Started    3m7s   kubelet, gke-dicom-adapter-default-pool-6f6e0dcd-9cdd  Started container dicom-import-adapter
    

    Service と内部ロードバランサのデプロイ

    内部ロードバランサを作成するには、dicom_adapter_load_balancer.yaml Service マニフェスト ファイルを含むディレクトリで、次のコマンドを実行します。

    kubectl apply -f dicom_adapter_load_balancer.yaml
    

    次のような出力が表示されます。

    service/dicom-adapter-load-balancer created
    

    サービスの検査

    Service を作成したら、Service が正常に構成されていることを確認します。

    次のコマンドを実行して、内部ロードバランサを検査します。

    kubectl describe service dicom-adapter-load-balancer
    

    次のような出力が表示されます。

    Name:                     dicom-adapter-load-balancer
    Namespace:                default
    Labels:                   <none>
    Annotations:              cloud.google.com/load-balancer-type: Internal
    Selector:                 app=dicom-adapter
    Type:                     LoadBalancer
    IP:                       198.51.100.1
    LoadBalancer Ingress:     203.0.113.1
    Port:                     port  2575/TCP
    TargetPort:               2575/TCP
    NodePort:                 port  30440/TCP
    Endpoints:                192.0.2.1:2575
    Session Affinity:         None
    External Traffic Policy:  Cluster
    Events:
    
    Events:
      Type    Reason                Age   From                Message
      ----    ------                ----  ----                -------
      Normal  EnsuringLoadBalancer  1m    service-controller  Ensuring load balancer
      Normal  EnsuredLoadBalancer   1m    service-controller  Ensured load balancer
    

    LoadBalancer Ingress の IP アドレスの入力には 1 分ほどかかることがあります。LoadBalancer Ingress IP アドレスを保存します。次のセクションで、このクラスタを使用してクラスタの外部から Service にアクセスします。

    Compute Engine 仮想マシンの作成

    オンプレミスの PACS をシミュレートするには、DICOM アダプタにリクエストを送信する Compute Engine VM を作成します。内部ロードバランサをデプロイしたため、作成した VM と既存の GKE クラスタを同じリージョンに配置し、これらが同じ VPC ネットワークを使用する必要があります

    Compute Engine で Linux 仮想マシン インスタンスを作成する手順は次のとおりです。

    コンソール

    1. Google Cloud コンソールで [VM インスタンス] ページに移動します。

      [VM インスタンス] に移動

    2. [インスタンスを作成] をクリックします。

    3. インスタンスに対して、クラスタを作成したときに選択したゾーンと一致するリージョンゾーンを選択します。たとえば、クラスタを作成したときに、COMPUTE_ZONEus-central1-a を使用した場合、[リージョン] には us-central1 (Iowa) を、[ゾーン] には us-central1-a を選択します。

    4. [ブートディスク] セクションの [変更] をクリックして、ブートディスクを構成します。

    5. [公開イメージ] タブで、Debian オペレーティング システムのバージョン 9 を選択します。

    6. [選択] をクリックします。

    7. [ファイアウォール] で [HTTP トラフィックを許可する] を選択します。

    8. [作成] をクリックしてインスタンスを作成します。

    gcloud

    gcloud compute instances create コマンドを実行します。このコマンドでは、http-server タグを使用して HTTP トラフィックを許可します。

    後述のコマンドデータを使用する前に、次のように置き換えます。

    次のコマンドを実行します。

    Linux、macOS、Cloud Shell

    gcloud compute instances create INSTANCE_NAME \
      --project=PROJECT_ID \
      --zone=COMPUTE_ZONE \
      --image-family=debian-9 \
      --image-project=debian-cloud \
      --tags=http-server

    Windows(PowerShell)

    gcloud compute instances create INSTANCE_NAME `
      --project=PROJECT_ID `
      --zone=COMPUTE_ZONE `
      --image-family=debian-9 `
      --image-project=debian-cloud `
      --tags=http-server

    Windows(cmd.exe)

    gcloud compute instances create INSTANCE_NAME ^
      --project=PROJECT_ID ^
      --zone=COMPUTE_ZONE ^
      --image-family=debian-9 ^
      --image-project=debian-cloud ^
      --tags=http-server

    次のようなレスポンスが返されます。

    Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/instances/INSTANCE_NAME].
    NAME          ZONE           MACHINE_TYPE   PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP    STATUS
    INSTANCE_NAME  COMPUTE_ZONE           n1-standard-1               INTERNAL_IP  EXTERNAL_IP    RUNNING
    

    インスタンスが起動するまで、しばらくお待ちください。インスタンスが起動すると、[VM インスタンス] ページに緑色のステータス アイコン付きで表示されます。

    VM への接続

    VMへの接続は、次の手順で行います。

    コンソール

    1. Google Cloud コンソールで、[VM インスタンス] ページに移動します。

      [VM インスタンス] に移動

    2. 仮想マシン インスタンスのリストで、作成したインスタンスの行の SSH をクリックします。

    gcloud

    gcloud compute ssh コマンドを実行します。

    後述のコマンドデータを使用する前に、次のように置き換えます。

    • PROJECT_ID: Google Cloud プロジェクトの ID
    • COMPUTE_ZONE: VM のゾーン
    • INSTANCE_NAME: VM の名前

    次のコマンドを実行します。

    Linux、macOS、Cloud Shell

    gcloud compute ssh INSTANCE_NAME \
      --project PROJECT_ID \
      --zone COMPUTE_ZONE

    Windows(PowerShell)

    gcloud compute ssh INSTANCE_NAME `
      --project PROJECT_ID `
      --zone COMPUTE_ZONE

    Windows(cmd.exe)

    gcloud compute ssh INSTANCE_NAME ^
      --project PROJECT_ID ^
      --zone COMPUTE_ZONE

    Linux インスタンスとのやり取りに使用するターミナル ウィンドウが用意されています。

    DICOM イメージの DICOM ストアへのインポート

    ネットワーク上で DICOM イメージを送信するために使用できるソフトウェア オプションは複数存在します。以下のセクションでは、DCMTK DICOM ツールキットを使用します。

    DICOM 画像を DICOM ストアにインポートするには、前のセクションで作成した VM から次の手順を行います。

    1. DCMTK DICOM ツールキット ソフトウェアをインストールします。

      sudo apt-get install -y dcmtk
      
    2. DICOM イメージを VM に保存します。たとえば、DICOM 画像が Cloud Storage バケットに保存されている場合、次のコマンドを実行して、現在の作業ディレクトリにダウンロードします。

      gcloud storage cp gs://BUCKET/DCM_FILE .

      gcs-public-data--healthcare-tcia-lidc-idri データセットから無料で入手できる DICOM 画像を Google Cloud で使用するには、次のコマンドを実行します。

      gcloud storage cp gs://gcs-public-data--healthcare-tcia-lidc-idri/dicom/1.3.6.1.4.1.14519.5.2.1.6279.6001.100036212881370097961774473021/1.3.6.1.4.1.14519.5.2.1.6279.6001.130765375502800983459674173881/1.3.6.1.4.1.14519.5.2.1.6279.6001.100395847981751414562031366859.dcm . --billing-project=PROJECT_ID
    3. DCMTK DICOM ツールキットから入手できる dcmsend コマンドを実行します。このコマンドを実行するときは、アプリケーション エンティティ(AE)タイトルを IMPORTADAPTER に設定します。必要に応じて、--verbose フラグを追加して処理の詳細を表示します。このガイドで使用しているポートは 2575 です。

      dcmsend --verbose PEER 2575 DCM_FILE_IN -aec IMPORTADAPTER

      以下を置き換えます。

      • PEER: Service を検査した時に返された LoadBalancer Ingress IP アドレス
      • DCMFILE_IN: VM 上の DICOM 画像へのパス

      単一の DICOM イメージを使用して dcmsend を実行すると、出力は次のようになります。

      I: checking input files ...
      I: starting association #1
      I: initializing network ...
      I: negotiating network association ...
      I: Requesting Association
      I: Association Accepted (Max Send PDV: 16366)
      I: sending SOP instances ...
      I: Sending C-STORE Request (MsgID 1, MR)
      I: Received C-STORE Response (Success)
      I: Releasing Association
      I:
      I: Status Summary
      I: --------------
      I: Number of associations   : 1
      I: Number of pres. contexts : 1
      I: Number of SOP instances  : 1
      I: - sent to the peer       : 1
      I:   * with status SUCCESS  : 1
      
    4. DICOM イメージが DICOM ストアに正常にインポートされたことを確認するには、DICOM ストアでインスタンスを検索し、新しい DICOM イメージがストアにあることを確認します。

    このセクションを完了すると、DICOM アダプタが GKE に正常にデプロイされ、アダプタを介して DICOM イメージが PACS インスタンスから Cloud Healthcare API に送信されます。

    トラブルシューティング

    GKE のトラブルシューティング

    GKE にデプロイした後、DICOM アダプタで障害が発生した場合は、デプロイされたワークロードに関する問題のトラブルシューティングの手順に従います。

    アダプタのトラブルシューティング

    インポート アダプタとエクスポート アダプタによって生成されるログは、問題の診断に使用できます。GKE を使用してアダプタを実行すると、ログが Cloud Logging に保存されます。ログを表示するには、 Google Cloud コンソールまたは kubectl ツールを使用して、次の手順を行います。

    コンソール

    1. Google Cloud コンソールで GKE の [ワークロード] ダッシュボードに移動します。

      GKE ワークロードに移動

    2. dicom-adapter ワークロードを選択します。

    3. [Deployment の詳細] ページで、[コンテナのログ] をクリックします。

    kubectl

    クラスタで実行しているすべての Pod を表示するには、次のコマンドを実行します。

    kubectl get pods
    

    名前が dicom-adapter で始まる Pod を探します。

    Pod のログを取得するには、次のコマンドを実行します。

    kubectl logs POD_NAME

    このガイドの手順のいずれかを完了しないと、dcmsend コマンドで画像のアップロードに失敗する可能性があります。この問題を調査するには、-d フラグを指定してコマンドを再実行します(「デバッグ」の場合)。このフラグでは、失敗に関する情報を提供するメッセージを含めて、アクションの詳細ログを出力します。

    権限と承認のトラブルシューティング

    以降のセクションでは、権限または承認が正しく構成されていない場合に dcmsend で発生する可能性があるエラーについて説明します。

    ピアが関連付けを中断したというエラー

    次の問題は、PACS からロードバランサのポート 2575 にネットワーク トラフィックを配信できない場合に発生します。

    cannot send SOP instance: Peer aborted Association (or never connected)
    

    この問題を解決するには、PACS VM と GKE クラスタが同じ VPC ネットワーク内で実行されていることを確認します。これらが同じ VPC ネットワークで実行されていない場合は、次の点を確認してください。

    • ロードバランサが「内部」として構成されていません。
    • ポート 2575 への接続をブロックするファイアウォール ルールがない。

    このエラーは、ロードバランサ サービスまたはアダプタ Pod が GKE クラスタに正しく設定されていない場合にも発生します。それらが正しく設定されていることを確認するには、このガイドの Deployment を検査するService の検査をご覧ください。

    必要な API が有効になっていないというエラー

    アダプタがある GKE クラスタが実行されているプロジェクトで Cloud Healthcare API が有効になっていないと、次の問題が発生します。

    LO [Http_403, PERMISSION_DENIED, Cloud Healthcare API has not been u]
    

    この問題を解決するには、始める前にの手順に沿って、必要な API をすべて有効にします。

    スコープが不十分というエラー

    アダプタを実行している GKE クラスタに正しいスコープ値が設定されていない場合に、次の問題が発生します。

    LO [Http_403, PERMISSION_DENIED, Request had insufficient authentica]
    

    この問題を解決するには、GKE クラスタを更新するか、次のフラグを指定して新しいクラスタを作成します。

    --scopes=https://www.googleapis.com/auth/cloud-healthcare
    

    DICOM ストアへの権限拒否エラー

    アダプタを実行している GKE クラスタで使用されるサービス アカウントに roles/healthcare.dicomEditor ロールが付与されていないと、次のエラーが発生します。

    LO [Http_403, PERMISSION_DENIED, Permission healthcare.dicomStores.d]
    

    この問題を解決するには、Compute Engine サービス アカウントに権限を付与するの手順に沿って操作してください。

    次のステップ

    このガイドのプロトタイプを構成すると、Cloud VPN を使用して PACS と Cloud Healthcare API の間のトラフィックを暗号化できるようになります。