Como conectar um PACS à API Cloud Healthcare

Nesta página, explicamos como usar o adaptador DICOM da API Cloud Healthcare de código aberto no Google Kubernetes Engine (GKE) para concluir as seguintes tarefas:

  • Conecte um sistema de comunicação e arquivamento de imagem (PACS, na sigla em inglês) à API Cloud Healthcare.
  • Importe dados DICOM do PACS para um armazenamento DICOM na API Cloud Healthcare.

Este guia oferece uma maneira simples de configurar um protótipo usando o Google Kubernetes Engine e uma máquina virtual (VM) do Compute Engine. A VM do Compute Engine simula os PACS no local. Para informações mais detalhadas, consulte o README do adaptador DICOM.

Visão geral do adaptador DICOM

O adaptador consiste em dois componentes principais: o adaptador de importação e o de exportação. Neste guia, mostramos como usar o adaptador de importação para armazenar imagens DICOM em um armazenamento DICOM.

Use o adaptador DICOM para converter dados entre protocolos tradicionais e protocolos RESTful. Por exemplo, é possível converter do formato C-STORE em formato STOW-RS.

Custos

Neste guia, são usados componentes faturáveis do Google Cloud, entre eles:

  • API Cloud Healthcare
  • Google Kubernetes Engine
  • Compute Engine

Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto. Novos usuários do Cloud Platform podem se qualificar para uma avaliação gratuita.

Antes de começar

  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. Aguarde a API GKE e os serviços relacionados serem ativados. Isso pode levar alguns minutos.
  9. Crie um armazenamento DICOM caso ainda não tenha feito isso.

Escolha um shell

Para concluir este guia, use o Cloud Shell ou o shell local.

O Cloud Shell é um ambiente de shell para gerenciar recursos hospedados no Google Cloud. O Cloud Shell vem pré-instalado com as seguintes ferramentas, que você usará neste guia:

  • CLI gcloud: fornece a interface de linha de comando principal para o Google Cloud
  • kubectl: fornece a interface de linha de comando para executar comandos nos clusters do GKE.

Para abrir o Cloud Shell ou configurar o shell local, siga estas etapas:

Cloud Shell

  1. Acesse o Console do Google Cloud.

    Console do Google Cloud

  2. No canto superior direito do console, clique no botão Ativar o Cloud Shell:

Uma sessão do Cloud Shell é aberta dentro de um frame na parte inferior do console. Use esse shell para executar os comandos gcloud e kubectl.

Shell local

Se você preferir usar o shell local, instale a CLI gcloud. Consulte Como instalar a CLI do Google Cloud para ver as instruções.

Implantar o adaptador usando o Google Kubernetes Engine

O adaptador de importação e o adaptador de exportação são aplicativos em contêiner preparados em uma imagem do Docker pré-criada no Container Registry. Neste guia, você implanta a imagem dicom-import-adapter para ser executada em um cluster do GKE.

Conceder permissões à conta de serviço do Compute Engine

Siga as instruções em Como criar e ativar contas de serviço para instâncias para conceder o papel roles/healthcare.dicomEditor à conta de serviço padrão do Compute Engine. Para mais informações, consulte Papéis de armazenamento DICOM.

Crie o cluster

gcloud

Para criar um cluster no GKE chamado dicom-adapter, execute o comando gcloud container clusters create.

Antes de usar os dados do comando abaixo, faça estas substituições:

  • COMPUTE_ZONE: a zona em que o cluster é implantado. Uma zona é um local regional aproximado em que os clusters e os recursos deles são implantados. Por exemplo, us-west1-a é uma zona na região us-west. Se você definiu uma zona padrão usando o comando gcloud config set compute/zone, o valor da flag no comando anterior vai substituir o padrão.

Execute o seguinte comando:

Linux, macOS ou 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

Você receberá uma resposta semelhante a esta:

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

Configurar a implantação

Ao implantar um aplicativo no GKE, você define as propriedades da implantação usando um arquivo de manifesto de implantação, que normalmente é um arquivo YAML. Para informações sobre os arquivos de manifesto da implantação, consulte Como criar implantações.

Usando um editor de texto, crie um arquivo de manifesto de implantação para o adaptador de importação chamado dicom_adapter.yaml com o seguinte conteúdo:

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"

Substitua:

  • PROJECT_ID: ID do projeto
  • LOCATION: local do conjunto de dados;
  • DATASET_ID: ID do conjunto de dados pai do armazenamento DICOM;
  • DICOM_STORE_ID: ID do armazenamento DICOM em que você está importando dados DICOM.

Configurar o Serviço:

Para tornar o adaptador DICOM acessível a aplicativos fora do cluster do GKE, como PACS, configure um balanceador de carga interno. O balanceador de carga permite expor internamente a porta DIMSE (neste guia, porta 2575).

Crie um arquivo de manifesto de Serviço para configurar o balanceamento de carga interno. No diretório em que o arquivo de manifesto de implantação foi criado, use um editor de texto para criar um arquivo chamado dicom_adapter_load_balancer.yaml com o seguinte conteúdo. Crie e implante o arquivo de manifesto do Serviço em Como implantar o Serviço e o balanceador de carga interno.

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

Implantar a implantação

Para implantar o adaptador em um cluster do GKE, execute o seguinte comando no diretório em que está o arquivo de manifesto de implantação dicom_adapter.yaml:

kubectl apply -f dicom_adapter.yaml

A saída é esta:

deployment.apps/dicom-adapter created

Inspecionar a implantação

Depois de criar a implantação, use a ferramenta kubectl para inspecioná-la.

Para ver informações detalhadas sobre a implantação, execute o seguinte comando:

kubectl describe deployment dicom-adapter

Para conferir o pod criado pela implantação, execute o seguinte comando:

kubectl get pods -l app=dicom-adapter

Para receber informações sobre o pod criado, execute o seguinte comando usando o nome do pod retornado do comando anterior:

kubectl describe pod POD_NAME

Se a implantação for bem-sucedida, a última parte da saída do comando anterior deverá conter as seguintes informações: O adaptador está pronto para exibir solicitações quando o contêiner dicom-import-adapter tem o valor Started na coluna Reason.

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

Implante o Serviço e o balanceador de carga interno

Para criar o balanceador de carga interno, execute o seguinte comando no diretório que contém o arquivo de manifesto de serviço dicom_adapter_load_balancer.yaml:

kubectl apply -f dicom_adapter_load_balancer.yaml

A saída é esta:

service/dicom-adapter-load-balancer created

Inspecionar o serviço

Depois de criar o Serviço, inspecione-o para verificar se ele foi configurado corretamente.

Para inspecionar o balanceador de carga, execute o seguinte comando:

kubectl describe service dicom-adapter-load-balancer

A saída é esta:

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

O endereço IP LoadBalancer Ingress pode demorar até um minuto para ser preenchido. Salve o endereço IP LoadBalancer Ingress. Use-o para acessar o Serviço de fora do cluster na próxima seção.

Criar uma máquina virtual do Compute Engine

Para simular o PACS local, crie uma VM do Compute Engine para enviar solicitações ao adaptador DICOM. Como um balanceador de carga interno foi implantado, a VM criada e o cluster do GKE existente deverão estar na mesma região e usar a mesma rede VPC.

Siga estas etapas para criar uma instância de máquina virtual do Linux no Compute Engine:

Console

  1. No Console do Google Cloud, acesse a página Instâncias de VMs.

    Acessar instâncias de VM

  2. Clique em Criar instância.

  3. Escolha uma Região e uma Zona para a instância que corresponda à zona selecionada quando você criou o cluster. Por exemplo, se você usou us-central1-a para o COMPUTE_ZONE ao criar o cluster, selecione us-central1 (Iowa) para a Região e us-central1-a para a Zona.

  4. Na seção Disco de inicialização, clique em Alterar para configurar o disco de inicialização.

  5. Na guia Imagens públicas, escolha a versão 9 do sistema operacional Debian.

  6. Clique em Selecionar.

  7. Na seção Firewall, selecione Permitir tráfego HTTP.

  8. Clique em Criar para criar a instância.

gcloud

Execute o comando gcloud compute instances create. O comando usa a tag http-server para permitir o tráfego HTTP.

Antes de usar os dados do comando abaixo, faça estas substituições:

  • PROJECT_ID: o ID do seu projeto do Google Cloud;
  • COMPUTE_ZONE: a zona selecionada quando você criou o cluster.
  • INSTANCE_NAME: nome da VM

Execute o seguinte comando:

Linux, macOS ou 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

Você receberá uma resposta semelhante a esta:

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

Aguarde a inicialização da instância. Depois que a instância é iniciada, ela é listada na página "Instâncias de VM" com um ícone de status verde.

Conectar-se à VM

Para se conectar à VM, conclua as seguintes etapas:

Console

  1. No Console do Google Cloud, acesse a página Instâncias de VMs.

    Acessar instâncias de VM

  2. Na lista de instâncias de máquina virtual, clique em SSH na linha da instância que você criou.

gcloud

Execute o comando gcloud compute ssh.

Antes de usar os dados do comando abaixo, faça estas substituições:

  • PROJECT_ID: o ID do seu projeto do Google Cloud;
  • COMPUTE_ZONE: a zona da VM.
  • INSTANCE_NAME: o nome da VM

Execute o seguinte comando:

Linux, macOS ou 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

Agora você tem uma janela de terminal para interagir com a instância do Linux.

Importar imagens DICOM para o armazenamento DICOM

Há várias opções de software disponíveis para enviar imagens DICOM por uma rede. Nas seções a seguir, será usado o kit de ferramentas DICOM do DCMTK.

Para importar imagens DICOM para o armazenamento DICOM, conclua as seguintes etapas da VM criada na seção anterior:

  1. Instale o software do kit de ferramentas DICOM do DCMTK:

    sudo apt-get install -y dcmtk
    
  2. Salve a imagem DICOM na VM. Por exemplo, se a imagem DICOM estiver armazenada em um bucket do Cloud Storage, execute o seguinte comando para fazer o download dela para o diretório de trabalho atual:

    gcloud storage cp gs://BUCKET/DCM_FILE .

    Para usar uma imagem DICOM disponibilizada gratuitamente pelo Google Cloud do conjunto de dados gcs-public-data--healthcare-tcia-lidc-idri, execute o seguinte comando:

    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. Execute o comando dcmsend, que está disponível no kit de ferramentas DCMTK DICOM. Ao executar o comando, defina o título da entidade do aplicativo (AE, na sigla em inglês) como IMPORTADAPTER. Opcionalmente, é possível adicionar a sinalização --verbose para mostrar os detalhes do processamento. A porta usada neste guia é 2575.

    dcmsend --verbose PEER 2575 DCM_FILE_IN -aec IMPORTADAPTER

    Substitua:

    • PEER: LoadBalancer Ingress endereço IP que foi retornado quando você inspecionou o Serviço;
    • DCMFILE_IN: caminho para a imagem DICOM na VM.

    Ao executar dcmsend com uma única imagem DICOM, a saída é a seguinte:

    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. Para verificar se a imagem DICOM foi importada com êxito para o armazenamento DICOM, pesquise instâncias no armazenamento DICOM e verifique se a nova imagem DICOM está no armazenamento.

Ao concluir esta seção, o adaptador DICOM terá sido implantado com sucesso no GKE e uma imagem DICOM terá sido enviada de uma instância do PACS pelo adaptador para a API Cloud Healthcare.

Resolver problemas

Solução de problemas do GKE

Se o adaptador DICOM encontrar uma falha depois de ser implantado no GKE, siga as etapas em Solução de problemas com cargas de trabalho implantadas.

Como solucionar problemas do adaptador

Os adaptadores de importação e exportação geram registros que podem ser usados para diagnosticar quaisquer problemas. Quando um adaptador é executado usando o GKE, os registros são armazenados no Cloud Logging. Para conferir os registros, conclua as etapas a seguir usando o console do Google Cloud ou a ferramenta kubectl:

Console

  1. Acesse o painel de cargas de trabalho do GKE no console do Google Cloud.

    Acessar as cargas de trabalho do GKE

  2. Selecione a carga de trabalho dicom-adapter.

  3. Na página Detalhes da implantação, clique em Registros do contêiner.

kubectl

Para ver todos os pods em execução no cluster, execute o seguinte comando:

kubectl get pods

Procure o pod cujo nome começa com dicom-adapter.

Para receber os registros do pod, execute o seguinte comando:

kubectl logs POD_NAME

Se você não seguiu alguma das etapas deste guia, o comando dcmsend pode falhar ao fazer upload de imagens. Para investigar esse problema, execute novamente o comando com a sinalização -d (para "depurar"). A sinalização imprime um registro mais detalhado das ações, incluindo mensagens que fornecem informações sobre a falha.

Como solucionar problemas de permissão e autorização

As seções a seguir descrevem erros que podem ocorrer em dcmsend quando as permissões ou autorizações estiverem configuradas incorretamente.

Erro de associação cancelada pelo par

O seguinte problema ocorre quando o tráfego de rede não pode fluir do PACS para a porta 2575 do balanceador de carga:

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

Para resolver esse problema, verifique se a VM do PACS e o cluster do GKE estão em execução na mesma rede VPC. Se eles não estiverem em execução na mesma rede VPC, verifique o seguinte:

  • O balanceador de carga não está configurado como "interno".
  • Não há regras de firewall bloqueando a conexão com a porta 2575.

Esse erro também pode acontecer quando o serviço do balanceador de carga ou o pod do adaptador não estão configurados corretamente no cluster do GKE. Para garantir que estejam configurados corretamente, leia Como inspecionar a implantação e Como inspecionar o Serviço neste guia.

Erro de APIs obrigatórias não ativadas

O seguinte problema ocorre quando a API Cloud Healthcare não foi ativada no projeto em que o cluster do GKE com o adaptador está em execução:

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

Para resolver esse problema, verifique se todas as APIs necessárias estão ativadas seguindo as instruções na seção Antes de começar.

Erro de escopo insuficiente

O seguinte problema ocorre quando o cluster do GKE em que o adaptador está em execução não tem o valor de escopo correto definido:

LO [Http_403, PERMISSION_DENIED, Request had insufficient authentica]

Para resolver esse problema, atualize o cluster do GKE ou crie um novo cluster com a seguinte sinalização:

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

Erro de permissão de armazenamento DICOM negado

O seguinte erro ocorre quando a conta de serviço usada pelo cluster do GKE em que o adaptador está em execução não tem o papel roles/healthcare.dicomEditor:

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

Para resolver esse problema, siga as instruções em Como conceder permissões da conta de serviço do Compute Engine.

A seguir

Após configurar o protótipo neste guia, será possível começar a usar o Cloud VPN para criptografar o tráfego entre o SFTP e a API Cloud Healthcare.