Tutorial: Menyebarkan registri yang terhubung ke hierarki IoT Edge berlapis

Dalam tutorial ini, Anda menggunakan perintah Azure CLI untuk membuat hierarki dua lapisan perangkat Azure IoT Edge dan menyebarkan registri yang terhubung sebagai modul di setiap lapisan. Dalam skenario ini, perangkat di lapisan atas berkomunikasi dengan registri cloud. Perangkat di lapisan bawah berkomunikasi dengan induk registri terhubungnya di lapisan atas.

Untuk gambaran umum menggunakan registri yang terhubung dengan IoT Edge, lihat Menggunakan registri yang terhubung dengan Azure IoT Edge.

Prasyarat

  • Azure IoT Hub. Untuk langkah-langkah penyebaran, lihat Membuat IoT Hub menggunakan portal Azure.

  • Dua sumber daya registri yang terhubung di Azure. Untuk langkah-langkah penyebaran, lihat mulai cepat menggunakan Azure CLI atau portal Azure.

    • Untuk lapisan atas, registri yang terhubung mungkin berada dalam mode ReadWrite atau ReadOnly. Dalam artikel ini, anggaplah dalam mode ReadWrite, dan nama registri yang terhubung disimpan dalam variabel lingkungan $CONNECTED_REGISTRY_RW.
    • Untuk lapisan bawah, registri yang terhubung harus dalam mode ReadOnly. Dalam artikel ini, nama registri yang terhubung disimpan dalam variabel lingkungan $CONNECTED_REGISTRY_RO.

Mengimpor gambar ke registri cloud Anda

Impor gambar kontainer berikut ke registri cloud Anda menggunakan perintah impor az acr. Lewati langkah ini jika Anda sudah mengimpor gambar-gambar ini.

Gambar registri tersambung

Untuk mendukung skenario IoT Edge yang bersarang, gambar kontainer untuk runtime registri yang terhubung harus tersedia di registri kontainer Azure pribadi Anda. Gunakan perintah impor az acr untuk mengimpor gambar registri yang terhubung ke registri pribadi Anda.

# Use the REGISTRY_NAME variable in the following Azure CLI commands to identify the registry
REGISTRY_NAME=<container-registry-name>

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/acr/connected-registry:0.8.0

Gambar proksi IoT Edge dan API

Untuk mendukung registri yang terhubung di IoT Edge bertumpuk, Anda perlu menerapkan modul untuk proksi IoT Edge dan API. Impor gambar-gambar ini ke dalam registri pribadi Anda.

Modul proksi IoT Edge API memungkinkan perangkat IoT Edge untuk mengekspos beberapa layanan menggunakan protokol HTTPS pada port yang sama seperti 443.

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/azureiotedge-agent:1.2.4

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/azureiotedge-hub:1.2.4

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/azureiotedge-api-proxy:1.1.2

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/azureiotedge-diagnostics:1.2.4

Gambar hello-world

Untuk menguji registri yang terhubung, impor gambar hello-world. Repositori ini akan disinkronkan ke registri yang terhubung dan ditarik oleh klien registri yang terhubung.

az acr import \
  --name $REGISTRY_NAME \
  --source mcr.microsoft.com/hello-world:1.1.2

Mengambil konfigurasi registri yang terhubung

Untuk menyebarkan tiap registri yang terhubung ke perangkat IoT Edge dalam hierarki, Anda perlu mengambil pengaturan konfigurasi dari sumber daya registri yang terhubung di Azure. Jika diperlukan, jalankan perintah az acr connected-registry get-settings untuk setiap registri yang terhubung untuk mengambil konfigurasi.

Secara default, informasi pengaturan tidak termasuk kata sandi token sinkronisasi, yang juga diperlukan untuk menyebarkan registri yang terhubung. Secara opsional, buat salah satu kata sandi dengan meneruskan parameter --generate-password 1 atau --generate-password 2. Simpan kata sandi yang dibuat ke lokasi yang aman. Ini tidak dapat diambil lagi.

Peringatan

Membuat ulang kata sandi akan memutar kredensial token sinkronisasi. Jika Anda mengonfigurasi perangkat menggunakan kata sandi sebelumnya, Anda perlu memperbarui konfigurasi.

# Use the REGISTRY_NAME variable in the following Azure CLI commands to identify the registry
REGISTRY_NAME=<container-registry-name>

# Run the command for each registry resource in the hierarchy

az acr connected-registry get-settings \
  --registry $REGISTRY_NAME \
  --name $CONNECTED_REGISTRY_RW \
  --parent-protocol https

az acr connected-registry get-settings \
  --registry $REGISTRY_NAME \
  --name $CONNECTED_REGISTRY_RO \
  --parent-protocol https

Output perintah termasuk string koneksi registri dan pengaturan terkait. Contoh output berikut menunjukkan string koneksi untuk registri yang terhubung bernama myconnectedregistry dengan contosoregistryregistri induk:

{
  "ACR_REGISTRY_CONNECTION_STRING": "ConnectedRegistryName=myconnectedregistry;SyncTokenName=myconnectedregistry-sync-token;SyncTokenPassword=xxxxxxxxxxxxxxxx;ParentGatewayEndpoint=contosoregistry.eastus.data.azurecr.io;ParentEndpointProtocol=https"
}

Mengonfigurasi manifes penyebaran

Manifes penyebaran berupa dokumen JSON yang menjelaskan modul mana yang akan disebarkan ke perangkat IoT Edge. Untuk informasi selengkapnya, lihat Memahami bagaimana modul IoT Edge dapat digunakan, dikonfigurasi, dan digunakan kembali.

Untuk menyebarkan modul registri yang terhubung pada setiap perangkat IoT Edge menggunakan Azure CLI, simpan manifes penyebaran berikut secara lokal sebagai file JSON. Gunakan informasi dari bagian sebelumnya untuk memperbarui nilai JSON yang relevan di setiap manifes. Gunakan jalur file di bagian selanjutnya saat Anda menjalankan perintah untuk menerapkan konfigurasi ke perangkat Anda.

Manifes penyebaran untuk lapisan atas

Untuk perangkat di lapisan atas, buat file manifes penyebaran deploymentTopLayer.json dengan konten berikut. Manifes ini serupa dengan yang digunakan di Mulai cepat: Menyebarkan registri yang terhubung ke perangkat IoT Edge.

Catatan

Jika Anda sudah menyebarkan registri yang terhubung ke perangkat IoT Edge lapisan atas menggunakan mulai cepat, Anda dapat menggunakannya di lapisan atas hierarki berlapis. Ubah langkah-langkah penyebaran dalam tutorial ini untuk mengonfigurasinya dalam hierarki (tidak ditampilkan).

Setelan modul registri tersambung

  • Gunakan kredensial token dan string koneksi dari bagian sebelumnya untuk memperbarui nilai JSON yang relevan di node env.

  • Variabel lingkungan berikut bersifat opsional di node env:

    Variabel Deskripsi
    ACR_REGISTRY_LOGIN_SERVER Menentukan nama host atau FQDN yang unik. Jika digunakan, registri yang terhubung hanya menerima permintaan yang dibuat untuk nilai server login ini.

    Jika tidak ada nilai yang diberikan, maka registri yang terhubung dapat diakses dengan nilai server login apa pun.
    ACR_REGISTRY_CERTIFICATE_VOLUME Jika registri tersambung Anda akan dapat diakses melalui HTTPS, tunjukkan volume tempat sertifikat HTTPS disimpan.

    Jika tidak diatur, lokasi default adalah /var/acr/certs.
    ACR_REGISTRY_DATA_VOLUME Menimpa lokasi default /var/acr/data tempat gambar akan disimpan oleh registri yang terhubung.

    Lokasi ini harus sesuai dengan pengikat volume untuk kontainer.

    Penting

    Jika registri yang terhubung mendengarkan pada port yang berbeda dari 80 dan 443, nilai ACR_REGISTRY_LOGIN_SERVER (jika ditentukan) harus menyertakan port. Contoh: 192.168.0.100:8080.

  • Pengikatan HostPort untuk registri yang terhubung harus diatur jika modul proksi API tidak digunakan. Contoh:

     "createOptions": "{\"HostConfig\":{\"Binds\":[\"/home/azureuser/connected-registry:/var/acr/data\"],\"PortBindings\":{\"8080/tcp\":[{\"HostPort\":\"8080\"}]}}}"
    

Setelan modul proksi API

  • Proksi API akan mendengarkan pada port 8000 dikonfigurasi sebagai NGINX_DEFAULT_PORT. Untuk informasi selengkapnya tentang pengaturan proksi API, lihat IoT Edge GitHub repo.
{
    "modulesContent": {
        "$edgeAgent": {
            "properties.desired": {
                "modules": {
                    "connected-registry": {
                        "settings": {
                            "image": "<REPLACE_WITH_CLOUD_REGISTRY_NAME>.azurecr.io/acr/connected-registry:0.8.0",
                            "createOptions": "{\"HostConfig\":{\"Binds\":[\"/home/azureuser/connected-registry:/var/acr/data\"]}}"
                        },
                        "type": "docker",
                        "env": {
                            "ACR_REGISTRY_CONNECTION_STRING": {
                                "value": "ConnectedRegistryName=<REPLACE_WITH_CONNECTED_REGISTRY_NAME>;SyncTokenName=<REPLACE_WITH_SYNC_TOKEN_NAME>;SyncTokenPassword=REPLACE_WITH_SYNC_TOKEN_PASSWORD;ParentGatewayEndpoint=<REPLACE_WITH_CLOUD_REGISTRY_NAME>.<REPLACE_WITH_CLOUD_REGISTRY_REGION>.data.azurecr.io;ParentEndpointProtocol=https"
                            }
                        },
                        "status": "running",
                        "restartPolicy": "always",
                        "version": "1.0"
                    },
                    "IoTEdgeAPIProxy": {
                        "settings": {
                            "image": "<REPLACE_WITH_CLOUD_REGISTRY_NAME>.azurecr.io/azureiotedge-api-proxy:1.1.2",
                            "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"8000/tcp\":[{\"HostPort\":\"8000\"}]}}}"
                        },
                        "type": "docker",
                        "env": {
                            "NGINX_DEFAULT_PORT": {
                                "value": "8000"
                            },
                            "CONNECTED_ACR_ROUTE_ADDRESS": {
                                "value": "connected-registry:8080"
                            },
                            "BLOB_UPLOAD_ROUTE_ADDRESS": {
                                "value": "AzureBlobStorageonIoTEdge:11002"
                            }
                        },
                        "status": "running",
                        "restartPolicy": "always",
                        "version": "1.0"
                    }
                },
                "runtime": {
                    "settings": {
                        "minDockerVersion": "v1.25",
                        "registryCredentials": {
                            "cloudregistry": {
                                "address": "<REPLACE_WITH_CLOUD_REGISTRY_NAME>.azurecr.io",
                                "password": "<REPLACE_WITH_SYNC_TOKEN_PASSWORD>",
                                "username": "<REPLACE_WITH_SYNC_TOKEN_NAME>"
                            }
                        }
                    },
                    "type": "docker"
                },
                "schemaVersion": "1.1",
                "systemModules": {
                    "edgeAgent": {
                        "settings": {
                            "image": "<REPLACE_WITH_CLOUD_REGISTRY_NAME>.azurecr.io/azureiotedge-agent:1.2.4",
                            "createOptions": ""
                        },
                        "type": "docker",
                        "env": {
                            "SendRuntimeQualityTelemetry": {
                                "value": "false"
                            }
                        }
                    },
                    "edgeHub": {
                        "settings": {
                            "image": "<REPLACE_WITH_CLOUD_REGISTRY_NAME>.azurecr.io/azureiotedge-hub:1.2.4",
                            "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
                        },
                        "type": "docker",
                        "status": "running",
                        "restartPolicy": "always"
                    }
                }
            }
        },
        "$edgeHub": {
            "properties.desired": {
                "routes": {
                    "route": "FROM /messages/* INTO $upstream"
                },
                "schemaVersion": "1.1",
                "storeAndForwardConfiguration": {
                    "timeToLiveSecs": 7200
                }
            }
        }
    }
}

Manifes penyebaran untuk lapisan bawah

Untuk perangkat di lapisan bawah, buatlah file manifes penyebaran deploymentLowerLayer.json dengan konten berikut.

Secara keseluruhan, file penyebaran lapisan bawah serupa dengan file penyebaran lapisan atas. Perbedaannya adalah:

  • Ini menarik citra yang diperlukan dari registri yang terhubung lapisan atas, bukan dari registri cloud.

    Saat Anda menyiapkan registri yang terhubung di lapisan atas, pastikan bahwa registri menyinkronkan semua gambar yang diperlukan secara lokal, termasuk azureiotedge-agent, azureiotedge-hub, azureiotedge-api-proxy, dan acr/connected-registry. Perangkat IoT lapisan bawah perlu menarik citra ini dari registri yang terhubung lapisan atas.

  • Ini menggunakan token sinkronisasi yang dikonfigurasi pada lapisan bawah untuk mengautentikasi dengan registri yang terhubung lapisan atas.

  • Ini mengonfigurasi titik akhir gateway induk dengan alamat IP registri yang terhubung lapisan atas atau FQDN, bukan dengan FQDN registri cloud.

Penting

Dalam manifes penyebaran berikut, $upstream digunakan sebagai alamat IP atau FQDN perangkat yang menghosting registri yang terhubung induk. Namun, $upstream tidak didukung dalam variabel lingkungan. Registri yang terhubung perlu membaca variabel lingkungan ACR_PARENT_GATEWAY_ENDPOINT untuk mendapatkan titik akhir gateway induk. Alih-alih menggunakan $upstream, registri yang terhubung mendukung penyelesaian alamat IP atau FQDN secara dinamis dari variabel lingkungan lain.

Pada IoT Edge berlapis, ada variabel lingkungan $IOTEDGE_PARENTHOSTNAME pada lapisan bawah yang setara dengan alamat IP atau FQDN perangkat induk. Ganti variabel lingkungan secara manual sebagai nilai ParentGatewayEndpoint dalam string koneksi untuk menghindari hard-coding alamat IP induk atau FQDN. Karena perangkat induk dalam contoh ini menjalankan nginx pada port 8000, teruskan $IOTEDGE_PARENTHOSTNAME:8000. Anda juga perlu memilih protokol yang tepat di ParentEndpointProtocol.

{
    "modulesContent": {
        "$edgeAgent": {
            "properties.desired": {
                "modules": {
                    "connected-registry": {
                        "settings": {
                            "image": "$upstream:8000/acr/connected-registry:0.8.0",
                            "createOptions": "{\"HostConfig\":{\"Binds\":[\"/home/azureuser/connected-registry:/var/acr/data\"]}}"
                        },
                        "type": "docker",
                        "env": {
                            "ACR_REGISTRY_CONNECTION_STRING": {
                                "value": "ConnectedRegistryName=<REPLACE_WITH_CONNECTED_REGISTRY_NAME>;SyncTokenName=<REPLACE_WITH_SYNC_TOKEN_NAME>;SyncTokenPassword=<REPLACE_WITH_SYNC_TOKEN_PASSWORD>;ParentGatewayEndpoint=$IOTEDGE_PARENTHOSTNAME:8000;ParentEndpointProtocol=https"
                            }
                        },
                        "status": "running",
                        "restartPolicy": "always",
                        "version": "1.0"
                    },
                    "IoTEdgeApiProxy": {
                        "settings": {
                            "image": "$upstream:8000/azureiotedge-api-proxy:1.1.2",
                            "createOptions": "{\"HostConfig\": {\"PortBindings\": {\"8000/tcp\": [{\"HostPort\": \"8000\"}]}}}"
                        },
                        "type": "docker",
                        "version": "1.0",
                        "env": {
                            "NGINX_DEFAULT_PORT": {
                                "value": "8000"
                            },
                            "CONNECTED_ACR_ROUTE_ADDRESS": {
                                "value": "connected-registry:8080"
                            },
                            "NGINX_CONFIG_ENV_VAR_LIST": {
                                    "value": "NGINX_DEFAULT_PORT,BLOB_UPLOAD_ROUTE_ADDRESS,CONNECTED_ACR_ROUTE_ADDRESS,IOTEDGE_PARENTHOSTNAME,DOCKER_REQUEST_ROUTE_ADDRESS"
                            },
                            "BLOB_UPLOAD_ROUTE_ADDRESS": {
                                "value": "AzureBlobStorageonIoTEdge:11002"
                            }
                        },
                        "status": "running",
                        "restartPolicy": "always",
                        "startupOrder": 3
                    }
                },
                "runtime": {
                    "settings": {
                        "minDockerVersion": "v1.25",
                        "registryCredentials": {
                            "connectedregistry": {
                                "address": "$upstream:8000",
                                "password": "<REPLACE_WITH_SYNC_TOKEN_PASSWORD>",
                                "username": "<REPLACE_WITH_SYNC_TOKEN_NAME>"
                            }
                        }
                    },
                    "type": "docker"
                },
                "schemaVersion": "1.1",
                "systemModules": {
                    "edgeAgent": {
                        "settings": {
                            "image": "$upstream:8000/azureiotedge-agent:1.2.4",
                            "createOptions": ""
                        },
                        "type": "docker",
                        "env": {
                            "SendRuntimeQualityTelemetry": {
                                "value": "false"
                            }
                        }
                    },
                    "edgeHub": {
                        "settings": {
                            "image": "$upstream:8000/azureiotedge-hub:1.2.4",
                            "createOptions": "{\"HostConfig\":{\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
                        },
                        "type": "docker",
                        "status": "running",
                        "restartPolicy": "always"
                    }
                }
            }
        },
        "$edgeHub": {
            "properties.desired": {
                "routes": {
                    "route": "FROM /messages/* INTO $upstream"
                },
                "schemaVersion": "1.1",
                "storeAndForwardConfiguration": {
                    "timeToLiveSecs": 7200
                }
            }
        }
    }
}

Menyiapkan dan menyebarkan modul registri yang terhubung

Langkah-langkah berikut diadaptasi dari Tutorial: Membuat hierarki perangkat IoT Edge dan khusus untuk menyebarkan modul registri yang terhubung dalam hierarki IoT Edge. Lihat tutorial itu untuk detail tentang langkah-langkahnya.

Membuat perangkat lapisan atas dan lapisan bawah

Buat mesin virtual lapisan atas dan lapisan bawah menggunakan templat ARM yang ada. Templat ini juga menginstal agen IoT Edge. Jika Anda ingin menyebarkan dari perangkat Anda sendiri, lihat Tutorial: Menginstal atau menghapus instalan Azure IoT Edge untuk Linux untuk mempelajari cara menyiapkan perangkat secara manual.

Penting

Untuk akses selanjutnya ke modul yang disebarkan pada perangkat lapisan atas, pastikan Anda membuka port masuk berikut: 8000, 443, 5671, 8883. Untuk langkah-langkah konfigurasi, lihat Cara membuka port ke mesin virtual dengan portal Azure.

Membuat dan mengonfigurasi hierarki

Gunakan alat iotedge-config untuk membuat dan mengonfigurasi hierarki Anda dengan mengikuti langkah-langkah berikut di Azure CLI atau Azure Cloud Shell:

  1. Unduh alat konfigurasi.

     mkdir nested_iot_edge_tutorial
     cd ~/nested_iot_edge_tutorial
     wget -O iotedge_config.tar "https://github.com/Azure-Samples/iotedge_config_cli/releases/download/latest/iotedge_config_cli.tar.gz"
     tar -xvf iotedge_config.tar
    

    Langkah ini akan membuat folder iotedge_config_cli_release dalam direktori tutorial Anda. File template yang digunakan untuk membuat hierarki perangkat Anda adalah file iotedge_config.yaml yang ditemukan di ~/nested_iot_edge_tutorial/iotedge_config_cli_release/templates/tutorial. Dalam direktori yang sama, ada dua manifes penyebaran untuk lapisan atas dan bawah: file deploymentTopLayer.json dan deploymentLowerLayer.json.

  2. Edit iotedge_config.yaml dengan informasi Anda. Edit iothub_hostname, iot_name, nama file manifes penyebaran untuk lapisan atas dan lapisan bawah, serta kredensial token klien yang Anda buat untuk menarik citra dari upstram setiap lapisan. Contoh berikut adalah sampel file konfigurasi:

    config_version: "1.0"
    
    iothub:
        iothub_hostname: <REPLACE_WITH_HUB_NAME>.azure-devices.net
        iothub_name: <REPLACE_WITH_HUB_NAME>
        ## Authentication method used by IoT Edge devices: symmetric_key or x509_certificate
        authentication_method: symmetric_key 
    
        ## Root certificate used to generate device CA certificates. Optional. If not provided a self-signed CA will be generated
        # certificates:
        #   root_ca_cert_path: ""
        #   root_ca_cert_key_path: ""
    
        ## IoT Edge configuration template to use
    configuration:
        template_config_path: "./templates/tutorial/device_config.toml"
        default_edge_agent: "$upstream:8000/azureiotedge-agent:1.2.4"
    
        ## Hierarchy of IoT Edge devices to create
    edgedevices:
        device_id: top-layer
        edge_agent: "<REPLACE_WITH_REGISTRY_NAME>.azurecr.io/azureiotedge-agent:1.2.4" ## Optional. If not provided, default_edge_agent will be used
        deployment: "./templates/tutorial/deploymentTopLayer.json" ## Optional. If provided, the given deployment file will be applied to the newly created device
            # hostname: "FQDN or IP" ## Optional. If provided, install.sh will not prompt user for this value nor the parent_hostname value
        container_auth: ## The token used to pull the image from cloud registry
            serveraddress: "<REPLACE_WITH_REGISTRY_NAME>.azurecr.io"
            username: "<REPLACE_WITH_SYNC_TOKEN_NAME_FOR_TOP_LAYER>"
            password: "<REPLACE_WITH_SYNC_TOKEN_PASSWORD_FOR_TOP_LAYER>"
        child:
            - device_id: lower-layer
              deployment: "./templates/tutorial/deploymentLowerLayer.json" ## Optional. If provided, the given deployment file will be applied to the newly created device
               # hostname: "FQDN or IP" ## Optional. If provided, install.sh will not prompt user for this value nor the parent_hostname value
              container_auth: ## The token used to pull the image from parent connected registry
                serveraddress: "$upstream:8000"
                username: "<REPLACE_WITH_SYNC_TOKEN_NAME_FOR_LOWER_LAYER>"
                password: "<REPLACE_WITH_SYNC_TOKEN_PASSWORD_FOR_LOWER_LAYER>"
    
  3. Siapkan file penyebaran lapisan atas dan lapisan bawah: deploymentTopLayer.json dan deploymentLowerLayer.json. Salin file manifes penyebaran yang Anda buat sebelumnya di artikel ini ke folder berikut: ~/nestedIotEdgeTutorial/iotedge_config_cli_release/templates/tutorial.

  4. Navigasikan ke direktori iotedge_config_cli_release Anda dan jalankan alat untuk membuat hierarki perangkat IoT Edge Anda.

    cd ~/nestedIotEdgeTutorial/iotedge_config_cli_release
    ./iotedge_config --config ~/nestedIotEdgeTutorial/iotedge_config_cli_release/templates/tutorial/iotedge_config.yaml --output ~/nestedIotEdgeTutorial/iotedge_config_cli_release/outputs -f
    

    Dengan parameter --output, alat ini membuat sertifikat perangkat, bundel sertifikat, dan file log dalam direktori pilihan Anda. Dengan parameter -f, alat ini secara otomatis mencari perangkat IoT Edge yang ada di IoT Hub Anda dan menghapusnya, untuk menghindari kesalahan dan menjaga hub Anda tetap bersih.

    Alat ini dapat berjalan selama beberapa menit.

  5. Salin file top-layer.zip dan lower-layer.zip yang dihasilkan pada langkah sebelumnya ke mesin virtual lapisan atas dan bawah yang sesuai menggunakan scp:

    scp <PATH_TO_CONFIGURATION_BUNDLE>   <USER>@<VM_IP_OR_FQDN>:~
    
  6. Sambungkan ke perangkat lapisan atas untuk menginstal bundel konfigurasi.

    1. Buka zip bundel konfigurasi. Anda harus menginstal zip terlebih dahulu.

      sudo apt install zip
      unzip ~/<PATH_TO_CONFIGURATION_BUNDLE>/<CONFIGURATION_BUNDLE>.zip #unzip top-layer.zip
      
    2. Jalankan sudo ./install.sh. Masukkan alamat IP atau nama host. Sebaiknya gunakan alamat IP.

    3. Jalankan sudo iotedge list untuk mengonfirmasi semua modul sedang berjalan.

  7. Sambungkan ke perangkat lapisan bawah untuk menginstal bundel konfigurasi.

    1. Buka zip bundel konfigurasi. Anda harus menginstal zip terlebih dahulu.

      sudo apt install zip
      unzip ~/<PATH_TO_CONFIGURATION_BUNDLE>/<CONFIGURATION_BUNDLE>.zip #unzip lower-layer.zip
      
    2. Jalankan sudo ./install.sh. Masukkan perangkat dan alamat IP induk atau nama host. Sebaiknya gunakan alamat IP.

    3. Jalankan sudo iotedge list untuk mengonfirmasi semua modul sedang berjalan.

Jika Anda tidak menentukan file penyebaran untuk konfigurasi perangkat, atau jika terjadi masalah penyebaran seperti manifes penyebaran yang tidak valid di perangkat lapisan atas atau bawah, sebarkan modul secara manual. Lihat bagian berikut.

Sebarkan modul registri yang terhubung secara manual

Gunakan perintah berikut untuk menyebarkan modul registri yang terhubung secara manual pada perangkat IoT Edge:

az iot edge set-modules \
  --device-id <device-id> \
  --hub-name <hub-name> \
  --content <deployment-manifest-filename>

Untuk detailnya, lihat Menyebarkan modul Azure IoT Edge dengan Azure CLI.

Setelah penyebaran berhasil, registri yang terhubung menunjukkan status Online.

Untuk memeriksa status registri yang terhubung, gunakan perintah az acr connected-registry show berikut:

az acr connected-registry show \
  --registry $REGISTRY_NAME \
  --name $CONNECTED_REGISTRY_RO \
  --output table

Anda mungkin perlu menunggu beberapa menit hingga penyebaran registri yang terhubung selesai.

Setelah penyebaran berhasil, registri yang terhubung menunjukkan status Online.

Untuk memecahkan masalah penyebaran, jalankan iotedge check pada perangkat yang terpengaruh. Untuk informasi selengkapnya, lihat Pemecahan masalah.

Langkah berikutnya

Dalam panduan mulai cepat ini, Anda telah mempelajari cara menyebarkan registri yang terhubung ke perangkat IoT Edge berlapis. Lanjutkan ke panduan berikutnya untuk mempelajari cara menarik citra dari registri yang baru disebarkan.