將 PACS 連線至 Cloud Healthcare API

本頁說明如何在 Google Kubernetes Engine (GKE) 上使用開放原始碼的 Cloud Healthcare API DICOM 介面卡,完成下列工作:

  • 將影像封存與通訊系統 (PACS) 連線至 Cloud Healthcare API。
  • 將醫療影像儲傳系統 (PACS) 中的 DICOM 資料匯入 Cloud Healthcare API 的 DICOM 儲存庫。

本指南提供簡單的方法,協助您使用 Google Kubernetes Engine 和 Compute Engine 虛擬機器 (VM) 設定原型。Compute Engine VM 會模擬地端 PACS。如需更多詳細資訊,請參閱 DICOM 轉接程式 README

DICOM 配接器總覽

轉接程式包含兩個主要元件:匯入轉接程式和匯出轉接程式。本指南說明如何使用匯入轉接程式,將 DICOM 圖片儲存在 DICOM 儲存庫。

使用 DICOM 轉接程式,在傳統通訊協定和 RESTful 通訊協定之間轉換資料。舉例來說,您可以將 C-STORE 格式轉換為 STOW-RS 格式。

費用

本指南使用 Google Cloud的計費元件,包括:

  • Cloud Healthcare API
  • Google Kubernetes Engine
  • Compute Engine

使用 Pricing Calculator,根據您的預測使用量來產生預估費用。初次使用 Cloud Platform 的使用者可能符合免費試用的資格。

事前準備

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  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 role (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 serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). 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 role (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 serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the APIs

  8. 等待 GKE API 和相關服務完成啟用。 這項作業可能需要幾分鐘才能完成。
  9. 如果還沒有 DICOM 儲存庫,請建立一個

選擇殼層

如要完成本指南,請使用 Cloud Shell 或本機殼層。

Cloud Shell 是殼層環境,用於管理託管在 Google Cloud上的資源。Cloud Shell 預先安裝了下列工具,您將在本指南中使用這些工具:

  • gcloud CLI:提供 Google Cloud 產品與服務的主要指令列介面 Google Cloud
  • kubectl:提供指令列介面,用於對 GKE 叢集執行指令

如要開啟 Cloud Shell 或設定本機殼層,請完成下列步驟:

Cloud Shell

  1. 前往 Google Cloud 控制台。

    Google Cloud console

  2. 在主控台的右上角,按一下「啟用 Google Cloud Shell」按鈕:

主控台底部的頁框中會開啟一個 Cloud Shell 工作階段。您可以使用這個殼層來執行 gcloudkubectl 指令。

本機殼層

如果您想要使用本機殼層,則必須安裝 gcloud CLI。如需操作說明,請參閱「安裝 Google Cloud CLI」。

使用 Google Kubernetes Engine 部署介面卡

匯入和匯出介面卡是容器化應用程式,會暫存在 Container Registry 的預先建構 Docker 映像檔中。在本指南中,您將部署 dicom-import-adapter 映像檔,在 GKE 叢集上執行。

授予 Compute Engine 服務帳戶權限

請按照「建立和啟用執行個體的服務帳戶」一文中的操作說明,將 roles/healthcare.dicomEditor 角色授予 Compute Engine 預設服務帳戶。詳情請參閱「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」。

使用文字編輯器,為匯入轉接程式建立名為 dicom_adapter.yaml 的 Deployment 資訊清單檔案,並加入以下內容:

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

設定服務

如要讓 GKE 叢集外部的應用程式 (例如 PACS) 存取 DICOM 介面卡,您必須設定內部負載平衡器。負載平衡器可讓您在內部公開 DIMSE 通訊埠 (在本指南中為通訊埠 2575)。

建立 Service 資訊清單檔案,設定負載平衡。 在您建立 Deployment 資訊清單檔案的目錄中,使用文字編輯器建立名為 dicom_adapter_load_balancer.yaml 的檔案,並加入下列內容。您會在「部署 Service 和內部負載平衡器」中建立及部署 Service 資訊清單檔案。

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 工具檢查。

若要取得 Deployment 的詳細資訊,請執行下列指令:

kubectl describe deployment dicom-adapter

如要查看 Deployment 建立的 Pod,請執行下列指令:

kubectl get pods -l app=dicom-adapter

如要取得所建立 Pod 的相關資訊,請使用上一個指令傳回的 Pod 名稱,執行下列指令:

kubectl describe pod POD_NAME

如果部署成功,先前指令的輸出內容最後一部分會包含下列資訊。當 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

部署服務和內部負載平衡器

如要建立內部負載平衡器,請在含有 dicom_adapter_load_balancer.yaml 服務資訊清單檔案的目錄中執行下列指令:

kubectl apply -f dicom_adapter_load_balancer.yaml

輸出內容如下:

service/dicom-adapter-load-balancer created

檢查服務

建立服務後,請檢查服務,確認服務已正確設定完成。

如要檢查負載平衡器,請執行下列指令:

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 位址最多可能需要一分鐘才會顯示。 儲存 LoadBalancer Ingress IP 位址。您會在下一個部分使用這個位址,從叢集外部存取服務。

建立 Compute Engine 虛擬機器

如要模擬地端部署的 PACS,請建立 Compute Engine VM,將要求傳送至 DICOM 介面卡。由於您部署了內部負載平衡器,因此您建立的 VM 和現有 GKE 叢集必須位於相同區域,並使用相同的虛擬私有雲網路

請完成下列步驟,在 Compute Engine 中建立 Linux 虛擬機器執行個體:

控制台

  1. 前往 Google Cloud 控制台的「VM Instances」(VM 執行個體) 頁面

    前往 VM 執行個體

  2. 點選「建立執行個體」

  3. 為執行個體選擇「Region」(地區)和「Zone」(區域),該區域須與建立叢集時選取的區域相符。舉例來說,如果您在建立叢集時使用 us-central1-a 做為 COMPUTE_ZONE,請選取 us-central1 (Iowa) 做為「區域」,並選取 us-central1-a 做為「可用區」

  4. 在「Boot disk」(開機磁碟) 部分,點選「Change」(變更) 即可設定開機磁碟。

  5. 在「Public images」(公開映像檔) 分頁中,選擇「Debian」作業系統的「9」版本。

  6. 按一下「選取」

  7. 在「Firewall」(防火牆) 區段中,選取 [Allow HTTP traffic] (允許 HTTP 流量)

  8. 按一下「建立」,建立執行個體。

gcloud

執行 gcloud compute instances create 指令。這項指令會使用 http-server 標記,允許 HTTP 流量。

使用下列任何指令資料之前,請先替換以下項目:

  • PROJECT_ID:您 Google Cloud 專案的 ID
  • COMPUTE_ZONE建立叢集時選取的區域
  • INSTANCE_NAMEVM 名稱

執行下列指令:

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 Instances」(VM 執行個體) 頁面

    前往 VM 執行個體

  2. 在虛擬機器執行個體清單中,找到您建立的執行個體,然後在該列中按一下「SSH」SSH

gcloud

執行 gcloud compute ssh 指令。

使用下列任何指令資料之前,請先替換以下項目:

  • PROJECT_ID:您 Google Cloud 專案的 ID
  • COMPUTE_ZONEVM 的可用區
  • INSTANCE_NAMEVM 的名稱

執行下列指令:

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 bucket 中,請執行下列指令,將圖片下載至目前的工作目錄:

    gcloud storage cp gs://BUCKET/DCM_FILE .

    如要使用 Google Cloud 資料集提供的 DICOM 圖片,請執行下列指令:gcs-public-data--healthcare-tcia-lidc-idri

    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. 執行 dcmsend 指令,這個指令可透過 DCMTK DICOM 工具包取得。執行指令時,請將應用程式實體 (AE) 標題設為 IMPORTADAPTER。您也可以選擇新增 --verbose 旗標,顯示處理詳細資料。 本指南使用的通訊埠為 2575。

    dcmsend --verbose PEER 2575 DCM_FILE_IN -aec IMPORTADAPTER

    更改下列內容:

    • PEER檢查服務時傳回的 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,並透過介面卡將 PACS 執行個體的 DICOM 影像傳送至 Cloud Healthcare API。

疑難排解

GKE 疑難排解

如果 DICOM 轉接程式部署至 GKE 後發生故障,請按照「排解已部署工作負載的問題」一文中的步驟操作。

排解轉接頭問題

匯入和匯出轉接程式會產生記錄,可用於診斷任何問題。使用 GKE 執行轉接程式時,記錄檔會儲存在 Cloud Logging。如要查看記錄,請使用 Google Cloud 控制台或 kubectl 工具完成下列步驟:

控制台

  1. 前往 Google Cloud 控制台的 GKE「Workloads」(工作負載) 資訊主頁。

    前往 GKE 工作負載

  2. 選取 dicom-adapter 工作負載。

  3. 在「部署詳細資料」頁面中,按一下「容器記錄」

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 叢集在同一個虛擬私有雲網路中執行。如果這些服務並未在同一個虛擬私有雲網路中執行,請檢查下列事項:

  • 負載平衡器未設定為「內部」。
  • 沒有任何防火牆規則封鎖連線至通訊埠 2575。

如果 GKE 叢集中的負載平衡器服務或轉接程式 Pod 設定不正確,也可能發生這個錯誤。如要確保設定正確無誤,請參閱本指南中的「檢查部署作業」和「檢查服務」。

未啟用必要 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 之間的流量。