자습서: IoT Edge 디바이스의 계층 구조 만들기
적용 대상: IoT Edge 1.5
IoT Edge 1.4
Important
IoT Edge 1.5 LTS 및 IoT Edge 1.4 LTS는 지원되는 릴리스입니다. IoT Edge 1.4 LTS는 2024년 11월 12일에 수명이 종료됩니다. 이전 릴리스에 있는 경우 IoT Edge 업데이트를 참조하세요.
계층 구조의 레이어로 구성된 네트워크에 Azure IoT Edge 노드를 배포할 수 있습니다. 계층 구조의 각 레이어는 그 아래 레이어에 있는 디바이스의 메시지와 요청을 처리하는 게이트웨이 디바이스입니다. 이 구성을 중첩된 에지라고도 합니다.
상위 레이어만 클라우드에 연결되고 하위 레이어는 인접한 업스트림 및 다운스트림 레이어와만 통신할 수 있도록 디바이스의 계층 구조를 구성할 수 있습니다. 이러한 네트워크 계층화는 ISA-95 표준을 따르는 대부분의 산업 네트워크의 기초입니다.
이 자습서에서는 IoT Edge 디바이스의 계층 구조를 만들고, 디바이스에 IoT Edge 런타임 컨테이너를 배포하고, 로컬에서 디바이스를 구성하는 과정을 안내합니다. 다음 작업을 수행합니다.
- IoT Edge 디바이스의 계층 구조에서 관계를 만들고 정의합니다.
- 계층 구조의 디바이스에서 IoT Edge 런타임을 구성합니다.
- 디바이스 계층 구조 전체에 일관된 인증서를 설치합니다.
- 계층 구조의 디바이스에 워크로드를 추가합니다.
- IoT Edge API 프록시 모듈을 사용하여 하위 계층 디바이스에서 단일 포트를 통해 HTTP 트래픽을 안전하게 라우팅합니다.
팁
이 자습서에는 중첩된 IoT Edge 기능을 소개하는 수동 및 자동 단계가 함께 포함되어 있습니다.
IoT Edge 디바이스의 계층 구조 설정을 완전히 자동화하려면 스크립팅된 산업용 IoT용 Azure IoT Edge 샘플을 따라 하면 됩니다. 이 스크립팅된 시나리오는 Azure 가상 머신을 미리 구성된 디바이스로 배포하여 공장 환경을 시뮬레이션합니다.
IoT Edge 디바이스 계층 구조를 만들고 관리하는 수동 단계를 자세히 확인하려면 IoT Edge 디바이스 게이트웨이 계층 구조에 대한 방법 가이드를 참조하세요.
이 자습서에서는 다음 네트워크 계층이 정의됩니다.
상위 레이어: 이 레이어의 IoT Edge 디바이스는 클라우드에 직접 연결할 수 있습니다.
하위 계층: 최상위 계층 아래에 있는 계층의 IoT Edge 디바이스는 클라우드에 직접 연결할 수 없습니다. 데이터를 보내고 받으려면 하나 이상의 중간 IoT Edge 디바이스를 거쳐야 합니다.
이 자습서에서는 간단하게 두 개의 디바이스 계층 구조를 사용합니다. 상위 레이어 디바이스는 계층 구조의 상위 레이어에 있는 디바이스를 나타내며 클라우드에 직접 연결할 수 있습니다. 이 디바이스를 부모 디바이스라고 합니다. 하위 레이어 디바이스는 계층 구조의 하위 레이어에 있는 디바이스를 나타내며 클라우드에 직접 연결할 수 없습니다. 프로덕션 환경을 나타내는 디바이스를 필요에 따라 더 추가할 수 있습니다. 하위 레이어의 디바이스는 자식 디바이스라고 합니다.
참고 항목
자식 디바이스는 중첩된 토폴로지의 다운스트림 디바이스 또는 게이트웨이 디바이스일 수 있습니다.
필수 조건
IoT Edge 디바이스의 계층 구조를 만들려면 다음이 필요합니다.
인터넷에 연결된 컴퓨터(Windows 또는 Linux)
유효한 구독이 있는 Azure 계정. Azure 구독이 아직 없는 경우 시작하기 전에 체험 계정을 만듭니다.
Azure의 무료 또는 표준 계층 IoT Hub.
Azure IoT 확장이 설치된 Azure CLI를 사용하는 Azure Cloud Shell의 Bash 셸. 이 자습서에서는 Azure Cloud Shell을 사용합니다. Azure CLI 모듈 및 확장의 현재 버전을 보려면 az version을 실행합니다.
계층 구조를 구성할 Linux 디바이스 2개. 사용 가능한 디바이스가 없는 경우 IoT Edge Azure Resource Manager 템플릿을 사용하여 계층 구조의 각 디바이스를 위한 Azure 가상 머신을 만들 수 있습니다. IoT Edge 버전 1.5는 이 Resource Manager 템플릿과 함께 사전 설치됩니다. 소유한 디바이스에 IoT Edge를 설치하는 경우 Linux용 Azure IoT Edge 설치 또는 IoT Edge 업데이트를 참조하세요.
디바이스 간의 네트워크 통신을 간소화하려면 가상 머신이 동일한 가상 네트워크에 있거나 가상 네트워크 피어링을 사용해야 합니다.
최저 레이어 디바이스(443, 5671, 8883)를 제외한 모든 디바이스에서 다음 포트가 인바운드로 개방되어 있는지 확인합니다.
- 443: REST API 호출 및 docker 컨테이너 이미지를 끌어오기 위한 부모 및 자식 에지 허브 간에 사용됩니다.
- 5671, 8883: AMQP 및 MQTT에 사용됩니다.
자세한 내용은 Azure Portal을 사용하여 가상 머신에 대한 포트를 여는 방법을 참조하세요.
팁
이후 단계에서 구성 시 각 가상 머신의 SSH 핸들과 FQDN 또는 IP 주소를 사용하므로 이 정보를 기록해 두세요. Azure Portal에서 IP 주소 및 FQDN을 확인할 수 있습니다. IP 주소를 보려면 가상 머신 목록으로 이동하고 공용 IP 주소 필드를 확인합니다. FQDN을 보려면 각 가상 머신의 개요 페이지로 이동하고 DNS 이름 필드를 찾습니다. SSH 핸들을 보려면 각 가상 머신의 연결 페이지로 이동합니다.
IoT Edge 디바이스 계층 구조 만들기
IoT Edge 디바이스는 계층 구조의 계층을 구성합니다. 이 자습서에서는 상위 레이어 디바이스 및 하위 레이어 디바이스의 두 IoT Edge 디바이스 계층 구조를 만듭니다. 필요에 따라 다운스트림 디바이스를 추가로 만들 수 있습니다.
IoT Edge 디바이스의 계층 구조를 만들고 구성하려면 az iot edge devices create Azure CLI 명령을 사용합니다. 이 명령은 여러 단계를 자동화하고 압축하여 계층 구조의 구성을 간소화합니다.
- IoT Hub에서 디바이스 만들기
- 부모-자식 관계를 설정하여 디바이스 간 통신 권한 부여
- 각 디바이스에 배포 매니페스트 적용
- 디바이스 간에 보안 통신을 설정하기 위해 각 디바이스에 대한 인증서 체인 생성
- 각 디바이스의 구성 파일 생성
디바이스 구성 만들기
하나의 자식 디바이스가 있는 부모 디바이스를 포함하는 중첩된 에지 디바이스 그룹을 만듭니다. 이 자습서에서는 기본 샘플 배포 매니페스트를 사용합니다. 다른 시나리오 예제에서는 구성 예제 템플릿을 검토합니다.
az iot edge devices create 명령을 사용하기 전에 상위 레이어 및 하위 레이어 디바이스에 대한 배포 매니페스트를 정의해야 합니다. 로컬 컴퓨터에 deploymentTopLayer.json 샘플 파일을 다운로드합니다.
상위 레이어 디바이스 배포 매니페스트는 IoT Edge API 프록시 모듈을 정의하고 하위 레이어 디바이스에서 IoT Hub로의 경로를 선언합니다.
로컬 컴퓨터에 deploymentLowerLayer.json 샘플 파일을 다운로드합니다.
하위 레이어 디바이스 배포 매니페스트는 시뮬레이션된 온도 센서 모듈을 포함하며 상위 레이어 디바이스에 대한 경로를 선언합니다. systemModules 섹션에서 런타임 모듈이 mcr.microsoft.com 대신 $upstream:443에서 끌어오도록 설정되어 있음을 확인할 수 있습니다. 하위 계층 디바이스는 클라우드에서 이미지를 직접 끌어올 수 없으므로, 포트 443의 IoT Edge API Proxy 모듈로 Docker 이미지 요청을 보냅니다. 하위 레이어 디바이스에 배포된 다른 모듈(Simulated Temperature Sensor 모듈)도 이미지 요청을
$upstream:443
으로 보냅니다.하위 레이어 배포 매니페스트를 만드는 방법에 대한 자세한 내용은 Azure IoT Edge 디바이스를 연결하여 계층 구조 만들기를 참조하세요.
Azure Cloud Shell에서 az iot edge devices create Azure CLI 명령을 사용하여 IoT Hub에서 디바이스를 만들고 계층 구조의 각 디바이스에 대한 구성 번들을 만듭니다. 다음 자리 표시자를 적절한 값으로 바꿉니다.
자리 표시자 설명 <hub-name> IoT Hub의 이름입니다. <config-bundle-output-path> 구성 번들을 저장할 폴더 경로입니다. <parent-device-name> 상위 레이어 부모 디바이스 ID 이름입니다. <parent-deployment-manifest> 부모 디바이스 배포 매니페스트 파일입니다. <parent-fqdn-or-ip> 부모 디바이스 FQDN(정규화된 도메인 이름) 또는 IP 주소입니다. <child-device-name> 하위 레이어 자식 디바이스 ID 이름입니다. <child-deployment-manifest> 자식 디바이스 배포 매니페스트 파일입니다. <child-fqdn-or-ip> 자식 디바이스 FQDN(정규화된 도메인 이름) 또는 IP 주소입니다. az iot edge devices create \ --hub-name <hub-name> \ --output-path <config-bundle-output-path> \ --default-edge-agent "mcr.microsoft.com/azureiotedge-agent:1.5" \ --device id=<parent-device-name> \ deployment=<parent-deployment-manifest> \ hostname=<parent-fqdn-or-ip> \ --device id=child-1 \ parent=parent-1 \ deployment=<child-deployment-manifest> \ hostname=<child-fqdn-or-ip>
예를 들어 다음 명령은 IoT Hub에서 두 개의 IoT Edge 디바이스 계층 구조를 만듭니다. parent-1이라는 상위 레이어 디바이스 및 child-1*이라는 하위 레이어 디바이스 계층 구조를 만듭니다. 이 명령은 출력 디렉터리에 각 디바이스에 대한 구성 번들을 저장합니다. 또한 이 명령은 자체 서명된 테스트 인증서를 생성하여 구성 번들에 포함합니다. 구성 번들은 설치 스크립트를 사용하여 각 디바이스에 설치됩니다.
az iot edge devices create \ --hub-name my-iot-hub \ --output-path ./output \ --default-edge-agent "mcr.microsoft.com/azureiotedge-agent:1.5" \ --device id=parent-1 \ deployment=./deploymentTopLayer.json \ hostname=10.0.0.4 \ --device id=child-1 \ parent=parent-1 \ deployment=./deploymentLowerLayer.json \ hostname=10.1.0.4
명령을 실행한 후 출력 디렉터리에서 디바이스 구성 번들을 찾을 수 있습니다. 예시:
PS C:\nested-edge\output> dir
Directory: C:\nested-edge\output
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 4/10/2023 4:12 PM 7192 child-1.tgz
-a--- 4/10/2023 4:12 PM 6851 parent-1.tgz
명령에 인수로 전달된 사용자 고유의 인증서와 키를 사용하거나 더 복잡한 디바이스 계층 구조를 만들 수 있습니다. az 명령을 사용하여 중첩된 디바이스를 만드는 방법에 대한 자세한 내용은 az iot edge devices create를 참조하세요. 게이트웨이 시나리오에서 인증서를 사용하는 방법을 잘 모를 경우 방법 가이드의 인증서 섹션을 참조하세요.
이 자습서에서는 인라인 인수를 사용하여 디바이스 및 구성 번들을 만듭니다. YAML 또는 JSON 형식의 구성 파일을 사용할 수도 있습니다. 샘플 구성 파일은 sample_devices_config.yaml 예제를 참조하세요.
IoT Edge 런타임 구성
구성 단계는 디바이스를 프로비전하는 이외에 앞서 만든 인증서를 사용하여 계층 구조의 디바이스 간에 신뢰할 수 있는 통신을 설정합니다. 또한 계층 구조의 네트워크 구조를 설정하기 시작합니다. 상위 레이어 디바이스는 인터넷 연결을 유지하여 클라우드에서 런타임의 이미지를 끌어오고, 하위 레이어 디바이스는 상위 레이어 디바이스를 통해 라우팅하여 이러한 이미지에 액세스합니다.
IoT Edge 런타임을 구성하려면 구성 번들을 디바이스에 적용해야 합니다. 상위 레이어 디바이스 및 하위 레이어 디바이스는 서로 구성이 다르므로 각 디바이스에 어느 디바이스 구성 파일을 적용하는지 잘 확인해야 합니다.
각 구성 번들 보관 파일을 해당 디바이스에 복사합니다. USB 드라이브, Azure Key Vault와 같은 서비스 또는 보안 파일 복사본과 같은 기능을 사용할 수 있습니다. 시나리오와 가장 일치하는 방법 중 하나를 선택합니다.
예를 들어 parent-1 구성 번들을 parent-1 VM의 홈 디렉터리로 보내려면 다음 예제와 같은 명령을 사용할 수 있습니다.
scp ./output/parent-1.tgz admin@parent-1-vm.westus.cloudapp.azure.com:~
각 디바이스에서 구성 번들 보관 파일을 추출합니다. 예를 들어 tar 명령을 사용하여 parent-1 보관 파일을 추출합니다.
tar -xzf ./parent-1.tgz
설치 스크립트에 대한 실행 권한을 설정합니다.
chmod +x install.sh
각 디바이스에서 루트 권한을 사용하여 디바이스에 구성 번들을 적용합니다.
sudo ./install.sh
디바이스의 구성 파일에 대한 수정 내용을 자세히 확인하려면 Azure IoT Edge 디바이스를 함께 연결하여 계층 구조 만들기를 참조하세요.
디바이스가 올바르게 구성되었는지 확인하려면 해당 디바이스에서 구성 및 연결 확인을 실행합니다.
sudo iotedge check
admin@child-1-vm:~$ sudo iotedge check
Configuration checks (aziot-identity-service)
---------------------------------------------
√ keyd configuration is well-formed - OK
√ certd configuration is well-formed - OK
√ tpmd configuration is well-formed - OK
√ identityd configuration is well-formed - OK
√ daemon configurations up-to-date with config.toml - OK
√ identityd config toml file specifies a valid hostname - OK
√ host time is close to reference time - OK
√ preloaded certificates are valid - OK
√ keyd is running - OK
√ certd is running - OK
√ identityd is running - OK
√ read all preloaded certificates from the Certificates Service - OK
√ read all preloaded key pairs from the Keys Service - OK
√ check all EST server URLs utilize HTTPS - OK
√ ensure all preloaded certificates match preloaded private keys with the same ID - OK
Connectivity checks (aziot-identity-service)
--------------------------------------------
√ host can connect to and perform TLS handshake with iothub AMQP port - OK
√ host can connect to and perform TLS handshake with iothub HTTPS / WebSockets port - OK
√ host can connect to and perform TLS handshake with iothub MQTT port - OK
Configuration checks
--------------------
√ aziot-edged configuration is well-formed - OK
√ configuration up-to-date with config.toml - OK
√ container engine is installed and functional - OK
√ configuration has correct parent_hostname - OK
√ configuration has correct URIs for daemon mgmt endpoint - OK
√ container time is close to host time - OK
‼ DNS server - Warning
Container engine is not configured with DNS server setting, which may impact connectivity to IoT Hub.
Please see https://aka.ms/iotedge-prod-checklist-dns for best practices.
You can ignore this warning if you are setting DNS server per module in the Edge deployment.
‼ production readiness: logs policy - Warning
Container engine is not configured to rotate module logs which may cause it run out of disk space.
Please see https://aka.ms/iotedge-prod-checklist-logs for best practices.
You can ignore this warning if you are setting log policy per module in the Edge deployment.
‼ production readiness: Edge Agent's storage directory is persisted on the host filesystem - Warning
The edgeAgent module is not configured to persist its /tmp/edgeAgent directory on the host filesystem.
Data might be lost if the module is deleted or updated.
Please see https://aka.ms/iotedge-storage-host for best practices.
‼ production readiness: Edge Hub's storage directory is persisted on the host filesystem - Warning
The edgeHub module is not configured to persist its /tmp/edgeHub directory on the host filesystem.
Data might be lost if the module is deleted or updated.
Please see https://aka.ms/iotedge-storage-host for best practices.
√ Agent image is valid and can be pulled from upstream - OK
√ proxy settings are consistent in aziot-edged, aziot-identityd, moby daemon and config.toml - OK
Connectivity checks
-------------------
√ container on the default network can connect to upstream AMQP port - OK
√ container on the default network can connect to upstream HTTPS / WebSockets port - OK
√ container on the IoT Edge module network can connect to upstream AMQP port - OK
√ container on the IoT Edge module network can connect to upstream HTTPS / WebSockets port - OK
30 check(s) succeeded.
4 check(s) raised warnings. Re-run with --verbose for more details.
2 check(s) were skipped due to errors from other checks. Re-run with --verbose for more details.
최상위 레이어 디바이스에서 몇 가지 전달 평가가 포함된 출력이 표시될 것입니다. 로그 정책 및 DNS 정책(네트워크에 따라 다름)에 대한 경고가 표시될 수 있습니다.
디바이스 모듈 배포
IoT Hub에서 디바이스를 만들면 디바이스에 대한 모듈 배포가 적용됩니다. az iot edge devices create 명령은 상위 및 하위 레이어 디바이스에 대한 배포 JSON 파일을 적용했습니다. 이러한 배포가 완료되면 하위 레이어 디바이스가 IoT Edge API Proxy 모듈을 사용하여 필요한 이미지를 끌어옵니다.
최상위 레이어 디바이스는 런타임 모듈 IoT Edge Agent 및 IoT Edge Hub 외에 Docker 레지스트리 모듈 및 IoT Edge API Proxy 모듈도 받습니다.
Docker 레지스트리 모듈은 기존 Azure Container Registry를 가리킵니다. 이 경우 REGISTRY_PROXY_REMOTEURL
은 Microsoft Container Registry를 가리킵니다. 기본적으로 Docke 레지스트리는 포트 5000에서 수신 대기합니다.
IoT Edge API Proxy 모듈은 HTTP 요청을 다른 모듈로 라우팅하므로 하위 레이어 디바이스가 컨테이너 이미지를 끌어오거나 Blob을 스토리지로 밀어 넣을 수 있습니다. 이 자습서에서는 포트 443에서 통신하고, Docker 컨테이너 이미지 끌어오기 요청을 포트 5000의 Docker 레지스트리 모듈로 라우팅하도록 구성됩니다. 또한 모든 Blob Storage 업로드 요청은 포트 11002에서 AzureBlobStorageonIoTEdge 모듈로 라우팅됩니다. IoT Edge API Proxy 모듈 및 이 모듈을 구성하는 방법에 대한 자세한 내용은 모듈의 방법 가이드를 참조하세요.
Azure Portal 또는 Azure Cloud Shell을 통해 이와 같은 배포를 만드는 방법을 알아보려면 방법 가이드의 최상위 레이어 디바이스 섹션을 참조하세요.
명령을 사용하여 모듈의 상태를 볼 수 있습니다.
az iot hub module-twin show --device-id <edge-device-id> --module-id '$edgeAgent' --hub-name <iot-hub-name> --query "properties.reported.[systemModules, modules]"
이 명령은 모든 edgeAgent reported 속성을 출력합니다. 디바이스 상태를 모니터링하는 데 도움이 되는 속성으로는 runtime status, runtime start time, runtime last exit time, runtime restart count가 있습니다.
Azure Portal에서 모듈의 상태를 확인할 수도 있습니다. IoT Hub의 디바이스 섹션으로 이동하여 디바이스 및 모듈을 확인합니다.
생성된 데이터 보기
사용자가 푸시한 시뮬레이션된 온도 센서 모듈은 샘플 환경 데이터를 생성합니다. 주변 온도 및 습도, 머신 온도 및 압력, 타임스탬프가 포함된 메시지를 보냅니다.
Azure Cloud Shell을 통해 이러한 메시지를 볼 수도 있습니다.
az iot hub monitor-events -n <iot-hub-name> -d <lower-layer-device-name>
예시:
az iot hub monitor-events -n my-iot-hub -d child-1
{
"event": {
"origin": "child-1",
"module": "simulatedTemperatureSensor",
"interface": "",
"component": "",
"payload": "{\"machine\":{\"temperature\":104.29281270901808,\"pressure\":10.48905461241978},\"ambient\":{\"temperature\":21.086561171611102,\"humidity\":24},\"timeCreated\":\"2023-04-17T21:50:30.1082487Z\"}"
}
}
문제 해결
iotedge check
명령을 실행하여 구성을 확인하고 오류를 해결합니다.
다운스트림 컴퓨터가 인터넷에 직접 액세스할 수 없는 경우에도 중첩된 계층 구조에서 iotedge check
를 실행할 수 있습니다.
하위 레이어에서 iotedge check
를 실행하면 프로그램이 포트 443을 통해 부모에서 이미지 끌어오기를 시도합니다.
azureiotedge-diagnostics
값은 레지스트리 모듈과 연결된 컨테이너 레지스트리에서 가져옵니다. 이 자습서에서는 기본적으로 https://mcr.microsoft.com으로 설정되어 있습니다.
속성 | 값 |
---|---|
REGISTRY_PROXY_REMOTEURL |
https://mcr.microsoft.com |
프라이빗 컨테이너 레지스트리를 사용하는 경우 모든 이미지(IoTEdgeAPIProxy, edgeAgent, edgeHub, Simulated Temperature Sensor 및 진단)가 컨테이너 레지스트리에 있는지 확인합니다.
다운스트림 디바이스에 부모 디바이스와 다른 프로세서 아키텍처가 있는 경우 적절한 아키텍처 이미지가 필요합니다. 연결된 레지스트리를 사용하거나 다운스트림 디바이스 config.toml 파일에서 edgeAgent 및 edgeHub 모듈에 대한 올바른 이미지를 지정할 수 있습니다. 예를 들어 부모 디바이스가 ARM32v7 아키텍처에서 실행 중이고 다운스트림 디바이스가 AMD64 아키텍처에서 실행 중인 경우, 다운스트림 디바이스 config.toml 파일에서 일치하는 버전 및 아키텍처 이미지 태그를 지정해야 합니다.
[agent.config]
image = "$upstream:443/azureiotedge-agent:1.5.0-linux-amd64"
"systemModules": {
"edgeAgent": {
"settings": {
"image": "$upstream:443/azureiotedge-agent:1.5.0-linux-amd64"
},
},
"edgeHub": {
"settings": {
"image": "$upstream:443/azureiotedge-hub:1.5.0-linux-amd64",
}
}
}
리소스 정리
요금이 부과되지 않도록 이 문서에서 만든 로컬 구성 및 Azure 리소스를 삭제할 수 있습니다.
리소스를 삭제하려면:
Azure Portal에 로그인하고 리소스 그룹을 선택합니다.
IoT Hub 테스트 리소스가 포함된 리소스 그룹 이름을 선택합니다.
리소스 그룹에 포함된 리소스의 목록을 검토합니다. 모든 항목을 삭제하려는 경우리소스 그룹 삭제를 선택할 수 있습니다. 일부만 삭제하려는 경우 각 리소스를 선택하여 개별적으로 삭제할 수 있습니다.
다음 단계
이 자습서에서는 두 개의 IoT Edge 디바이스를 게이트웨이로 구성하고 다른 디바이스를 부모 디바이스로 설정했습니다. 그런 다음, IoT Edge API Proxy 모듈을 사용하여 게이트웨이를 통해 다운스트림 디바이스로 컨테이너 이미지를 끌어왔습니다. 자세히 알아보려면 프록시 모듈 사용에 대한 방법 가이드를 참조하세요.
게이트웨이를 사용하여 IoT Edge 디바이스의 계층 레이어를 만드는 방법에 대해 자세히 알아보려면 다음 문서를 참조하세요.
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기