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.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

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

    Go to project selector

  6. Make sure that billing is enabled for your Google Cloud project.

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

    Enable the APIs

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

シェルを選択する

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

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

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

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

Cloud Shell

  1. Google Cloud Console に移動します。

    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 仮想マシン インスタンスを作成する手順は次のとおりです。

Console

  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への接続は、次の手順で行います。

Console

  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 Console または kubectl ツールを使用して、次の手順を行います。

Console

  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 の間のトラフィックを暗号化できるようになります。