Cloud Healthcare API에 PACS 연결

이 페이지에서는 Google Kubernetes Engine(GKE)에서 오픈소스 Cloud Healthcare API DICOM 어댑터를 사용하여 사진 보관 및 통신 시스템(PACS)을 Cloud Healthcare API에 연결하고 DICOM 데이터를 가져오는 방법을 설명합니다.

이 가이드에서는 Google Kubernetes Engine 및 Compute Engine 가상 머신(VM)을 사용하여 프로토타입을 설정하는 간단한 방법을 제공합니다. Compute Engine VM은 온프레미스 PACS를 시뮬레이션합니다. 자세한 내용은 GitHub의 DICOM 어댑터 README를 참조하세요.

개요

DICOM 어댑터는 기존 DICOM DIMSE 프로토콜(예: C-STORE)과 RESTful DICOMweb 프로토콜(예: STOW-RS) 간에 데이터를 변환할 수 있는 구성요소 집합을 제공합니다. 어댑터는 가져오기 어댑터와 내보내기 어댑터라는 두 가지 기본 구성요소로 구성됩니다. 이 가이드에서는 가져오기 어댑터를 사용하여 DICOM 이미지를 DICOM 저장소로 가져옵니다.

비용

이 가이드에서는 비용이 청구될 수 있는 다음과 같은 Google Cloud 구성요소를 사용합니다.

  • Cloud Healthcare API
  • Google Kubernetes Engine
  • Compute Engine

가격 계산기를 사용하면 예상 사용량을 기준으로 예상 비용을 산출할 수 있습니다. 새 Cloud Platform 사용자는 무료 체험판을 사용할 수 있습니다.

시작하기 전에

DICOM 어댑터를 설정하려면 먼저 Google Cloud 프로젝트를 선택하거나 만들고 다음 단계를 완료하여 필요한 API를 사용 설정해야 합니다.

  1. Google 계정으로 로그인합니다.

    아직 계정이 없으면 새 계정을 등록하세요.

  2. Google Cloud Console의 프로젝트 선택기 페이지에서 Google Cloud 프로젝트를 선택하거나 만듭니다.

    프로젝트 선택기 페이지로 이동

  3. Cloud 프로젝트에 결제가 사용 설정되어 있는지 확인합니다. 프로젝트에 결제가 사용 설정되어 있는지 확인하는 방법을 알아보세요.

  4. Cloud Healthcare API, Google Kubernetes Engine, and Container Registry API를 사용 설정합니다.

    API 사용 설정

  5. GKE API 및 관련 서비스가 사용 설정될 때까지 기다립니다. 몇 분 정도 걸릴 수 있습니다.

셸 선택

이 가이드를 완료하려면 Cloud Shell 또는 로컬 셸을 사용하면 됩니다.

Cloud Shell은 Google Cloud에서 호스팅되는 리소스를 관리하는 데 사용되는 셸 환경입니다. Cloud Shell에는 gcloud 도구kubectl 도구가 사전 설치되어 있습니다. gcloud 도구는 GCP의 기본 명령줄 인터페이스를 제공합니다. kubectl은 GKE 클러스터에서 명령어를 실행하기 위한 명령줄 인터페이스를 제공합니다.

로컬 셸을 사용하려면 gcloud 도구와 kubectl 도구가 포함된 Cloud SDK를 설치해야 합니다.

Cloud Shell을 열거나 로컬 셸을 구성하려면 다음 단계를 완료하세요.

Cloud Shell

Cloud Shell을 시작하려면 다음 단계를 완료하세요.

  1. Google Cloud Console로 이동합니다.

    Google Cloud Console

  2. Console의 오른쪽 상단에서 Activate Google Cloud Shell(Google Cloud Shell 활성화) 버튼()을 클릭합니다.

Cloud Shell 세션이 콘솔 아래쪽 프레임 안에서 열립니다. 이 셸을 사용하여 gcloudkubectl 명령어를 실행합니다.

로컬 셸

gcloud 도구 및 kubectl 도구를 설치하려면 최신 Cloud SDK 버전을 설치하고 초기화합니다.

DICOM 저장소 만들기

DICOM 어댑터를 사용하기 전에 DICOM 저장소를 만들어야 합니다.

Google Kubernetes Engine을 사용하여 어댑터 배포

가져오기 어댑터 및 내보내기 어댑터는 Container Registry에 사전 빌드된 Docker 이미지에 스테이징된 컨테이너식 애플리케이션입니다. 이러한 이미지를 배포하여 GKE 클러스터에서 실행할 수 있습니다.

클러스터 만들기

GKE에서 dicom-adapter라는 클러스터를 만들려면 gcloud container clusters create 명령어를 실행합니다.

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

각 매개변수는 다음과 같습니다.

  • COMPUTE_ZONE은 클러스터가 배포된 영역입니다. 영역은 클러스터 및 리소스가 배포된 대략적인 리전 위치입니다. 예를 들어 us-west1-aus-west 리전에 있는 한 영역입니다. gcloud config set compute/zone을 사용하여 기본 영역을 설정한 경우 이 플래그의 값이 기본값을 재정의합니다.

성공하면 명령어가 다음과 같은 응답을 반환합니다.

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.15.12-gke.2   123.456.789.012  n1-standard-1  1.15.12-gke.2  3          RUNNING

배포 구성

GKE에 애플리케이션을 배포할 때는 일반적으로 YAML 파일인 배포 매니페스트 파일을 사용하여 배포의 속성을 정의합니다.

텍스트 편집기를 사용하여 다음 콘텐츠가 포함된 dicom_adapter.yaml이라는 가져오기 어댑터의 배포 매니페스트 파일을 만듭니다.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: dicom-adapter
spec:
  replicas: 1
  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.1
          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는 DICOM 저장소가 포함된 Google Cloud 프로젝트의 ID입니다.
  • LOCATION은 DICOM 저장소가 있는 위치입니다.
  • DATASET_ID는 DICOM 저장소의 상위 데이터 세트 ID입니다.
  • DICOM_STORE_ID는 DICOM 데이터를 가져올 DICOM 저장소의 ID입니다.

서비스 구성

DICOM 어댑터가 GKE 클러스터 외부의 애플리케이션(예: PACS)에 액세스할 수 있게 하려면 내부 부하 분산기를 구성해야 합니다. 부하 분산기를 사용하면 DIMSE 포트(이 가이드에서는 포트 2575)를 내부적으로 노출할 수 있습니다.

내부 부하 분산을 구성하기 위한 서비스 매니페스트 파일을 만듭니다. 배포 매니페스트 파일을 만든 디렉터리에서 텍스트 편집기를 사용하여 다음 콘텐츠가 포함된 dicom_adapter_load_balancer.yaml이라는 파일을 만듭니다.

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

배포 준비

GKE 클러스터에 어댑터를 배포하려면 dicom_adapter.yaml 배포 매니페스트 파일이 포함된 디렉터리에서 다음 명령어를 실행합니다.

kubectl apply -f dicom_adapter.yaml

성공하면 명령어가 다음과 같은 출력을 반환합니다.

deployment.extensions "dicom-adapter-deployment" created

배포 검사

배포를 만든 후 kubectl 도구를 사용하여 배포를 검사할 수 있습니다.

배포에 대한 자세한 정보를 보려면 다음 명령어를 실행하세요.

kubectl describe deployment dicom-adapter

배포에서 만든 Pod를 나열하려면 다음 명령어를 실행합니다.

kubectl get pods -l app=dicom-adapter

생성된 Pod에 대한 정보를 가져오려면 다음 안내를 따르세요.

kubectl describe pod POD_NAME

배포에 성공하면 이전 명령어의 출력 중 마지막 부분에 다음 정보가 포함되어야 합니다.

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.1"
  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.1"
  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

성공하면 명령어가 다음과 같은 출력을 반환합니다.

deployment.extensions "dicom_adapter_load_balancer.yaml" 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 주소가 채워지는 데 최대 1분이 걸릴 수 있습니다. LoadBalancer Ingress IP 주소를 복사합니다. 다음 섹션에서 이 IP 주소와 2575 포트를 사용하여 클러스터 외부의 서비스에 액세스합니다.

Compute Engine 가상 머신 만들기

온프레미스 PACS를 시뮬레이션하려면 DICOM 어댑터에 요청을 보내는 데 사용할 Compute Engine VM을 만듭니다. 개발자가 내부 부하 분산기와 생성된 VM을 배포했으므로 기존 GKE 클러스터는 동일한 리전과 동일한 VPC 네트워크에 있어야 합니다.

다음 단계는 Compute Engine에서 Linux 가상 머신 인스턴스를 만드는 방법을 보여줍니다.

Console

  1. Cloud Console에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스 페이지로 이동

  2. 인스턴스 만들기를 클릭합니다.

  3. 클러스터를 만들 때 선택한 영역과 일치하는 인스턴스의 리전영역을 선택합니다. 예를 들어 클러스터를 만들 때 COMPUTE_ZONEus-central1-a를 사용한 경우 인스턴스 생성 화면에서 리전us-central1 (Iowa)를, 영역us-central1-a를 선택합니다.

  4. 부팅 디스크 섹션에서 변경을 클릭하여 부팅 디스크 구성을 시작합니다.

  5. 공개 이미지 탭에서 Debian 운영 체제 버전 9를 선택합니다.

  6. 선택을 클릭합니다.

  7. 방화벽 섹션에서 HTTP 트래픽 허용을 선택합니다.

  8. 만들기를 클릭하여 인스턴스를 만듭니다.

gcloud

Compute 인스턴스를 만들기 위해 다음 옵션을 사용해서 gcloud compute instances create 메서드를 실행합니다.

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 인스턴스 페이지에 녹색 상태 아이콘으로 표시됩니다.

기본적으로 인스턴스에는 클러스터에 사용되는 기본 VPC 네트워크가 사용됩니다. 즉, 인스턴스에서 클러스터로 트래픽이 전송될 수 있습니다.

인스턴스에 연결하기 위해 다음 단계를 완료합니다.

Console

  1. Cloud Console에서 VM 인스턴스 페이지로 이동합니다.

    VM 인스턴스 페이지로 이동

  2. 가상 머신 인스턴스 목록의 바로 전에 만든 인스턴스 행에서 SSH를 클릭합니다.

gcloud

인스턴스에 연결하기 위해 gcloud compute ssh 명령어를 실행합니다.

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 install dcmtk
    
  2. DICOM 저장소로 가져올 DICOM 이미지를 VM에 업로드합니다. 예를 들어 DICOM 이미지가 Cloud Storage 버킷에 저장되어 있으면 다음 명령어를 실행하여 현재 작업 디렉터리에 다운로드합니다.

    gsutil cp gs://BUCKET/DCM_FILE .
    

    gcs-public-data--healthcare-tcia-lidc-idri 데이터 세트에서 Google Cloud에서 무료로 제공하는 DICOM 이미지를 사용하려면 다음 명령어를 실행하세요.

    gsutil -u PROJECT_ID 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 .
    
  3. DCMTK DICOM 툴킷을 통해 사용 가능한 dcmsend 명령어를 실행합니다. 명령어를 실행할 때 애플리케이션 항목(AE) 제목을 IMPORTADAPTER로 설정합니다. 선택적으로 --verbose 플래그를 추가하여 처리 세부정보를 표시할 수 있습니다. 요청을 보내기 전에 다음을 바꿉니다.

    • PEER: 서비스를 검사했을 때 반환된 LoadBalancer Ingress IP 주소입니다.
    • PORT: 사용되는 포트는 2575입니다.
    • DCMFILE_IN: 업로드하는 DICOM 이미지에 대한 파일 시스템의 경로입니다.
    dcmsend --verbose PEER 2575 DCM_FILE_IN -aec IMPORTADAPTER
    

    요청이 성공하면 단일 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에 배포하고 어댑터 및 Cloud Healthcare API를 통해 PACS 인스턴스에서 DICOM 이미지를 전송하게 됩니다.

어댑터 오류 문제 해결

DICOM 어댑터를 GKE에 배포한 후 오류가 발생하면 배포된 워크로드 문제 해결의 단계를 따릅니다.

가져오기 및 내보내기 어댑터는 문제를 진단하는 데 사용할 수 있는 로그를 생성합니다. GKE를 사용하여 어댑터를 실행하면 로그가 Cloud Logging에 저장됩니다. 로그를 보려면 Google Cloud Console 또는 kubectl 도구를 사용하여 다음 단계를 완료합니다.

Console

  1. Cloud Console에서 GKE 워크로드 대시보드로 이동합니다.

    GKE 워크로드 대시보드로 이동

  2. dicom-adapter 워크로드를 선택합니다.

  3. 배포 세부정보 페이지에서 컨테이너 로그를 클릭합니다.

kubectl

클러스터에서 실행 중인 모든 Pod를 보려면 다음 명령어를 실행합니다.

kubectl get pods

이름이 dicom-adapter로 시작하는 Pod를 찾습니다.

Pod의 로그를 가져오려면 다음 명령어를 실행합니다.

kubectl logs POD_NAME

다음 단계

이 가이드의 프로토타입을 구성한 후에는 Cloud VPN을 사용하여 PACS와 Cloud Healthcare API 간의 트래픽을 암호화할 수 있습니다.